Я использую FFmpeg в своем приложении для извлечения кадров из видео, кадры будут добавлены в вид обрезки видео, где вы получите иллюстрацию того, что происходит в видео в определенное время в видео. Таким образом, каждый кадр должен представлять некоторое время в видео.
Я не совсем понимаю, как FFmpeg создает кадры. Вот мой код:
"-i",
videoCroppedFile.getAbsolutePath(),
"-vf",
"fps=1/" + frameSeperation,
mediaStorageDir.getAbsolutePath() +
"/%d.jpg"
Мое приложение позволяет записывать видео максимальной продолжительностью 20 секунд. Количество кадров, извлеченных из видео, зависит от продолжительности захваченного видео. frameSeperation вычисляется с помощью приведенного ниже кода.
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long videoLength = Long.parseLong(time) / 1000;
double frameSeperationDouble = (double) videoLength;
// Divide by 11 because there is a maximum of 11 frames on trim video view
frameSeperationDouble /= 11;
frameSeperationDouble = Math.ceil(frameSeperationDouble);
int frameSeperation = (int) frameSeperationDouble;
Может быть, приведенная выше логика очень плоха, если есть лучший способ, пожалуйста, может кто-нибудь сказать мне.
В любом случае я запускаю код, и ниже приведены несколько тестовых примеров:
- Видео, снятое продолжительностью 6 секунд, состоит из 7 кадров.
- Видео, снятое продолжительностью 2 секунды, состоит из 3 кадров.
- Видео, снятое продолжительностью 10 секунд, состоит из 12 кадров.
- Видео, снятое продолжительностью 15 секунд, состоит из 9 кадров.
- Видео, снятое продолжительностью 20 секунд, состоит из 11 кадров.
Нет согласованности, и из-за этого мне трудно ставить временные метки для каждого кадра. Я чувствую, что моя логика неверна или я не понимаю. Любая помощь высоко ценится
Обновление 1
Итак, я сделал то, что вы сказали в комментариях:
final FFmpeg ffmpeg = FFmpeg.getInstance(mContext);
final File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ mContext.getPackageName()
+ "/vFrames");
if (!mediaStorageDir.exists()){
mediaStorageDir.mkdirs();
}
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(mContext, Uri.fromFile(videoCroppedFile));
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long videoLength = Long.parseLong(time) / 1000;
double frameSeperationDouble = (double) videoLength / 8;
retriever.release();
final String cmd[] = {
"-i",
videoCroppedFile.getAbsolutePath(),
"-vf",
"fps=1/" + frameSeperationDouble,
"-vframes," + 8,
mediaStorageDir.getAbsolutePath() +
"/%d.jpg"
};
Я также пробовал "-vframes=" + 8
в тот же момент, когда я помещал vFrames в cmd. Кажется, это вообще не работает, теперь из видео не извлекаются кадры.
-vf fps=1/[frameseparation]
. Если вы хотите захватывать изображение каждые x секунд, вам, вероятно, следует использовать-r fps
вместо этого. - person TheAtomicOption   schedule 16.11.2017