Получить точный кадр из видео в Android

Итак, у меня есть приложение, в котором пользователи могут снимать видео, и я хочу получить определенные кадры из файла. Когда я использую метод MediaMetaDataRetriever.getFrameAtTime(), он может извлекать только один кадр в секунду, но я также хочу захватывать кадры между секундами. Я также попытался внедрить Jcodec в свой проект, чтобы получить нужные кадры:

FrameGrab.getFrame(new File(videoFileToRetreive.getVideoFile()), currentFrame);,

Однако независимо от того, какое число я ввел в currentFrame, изображение всегда возвращает первый кадр видео. Есть ли способ выполнить что-то подобное без использования ffmpeg? Если кто знает ответ, буду очень признателен.


person hermt2    schedule 22.02.2017    source источник


Ответы (4)


В итоге я использовал библиотеку Android FFmpeg, найденную здесь: https://github.com/wseemann/FFmpegMediaMetadataRetriever

person hermt2    schedule 22.02.2017
comment
Вы использовали файлы предварительной сборки .aar? Я только что опубликовал вопрос об этом - stackoverflow. ком/вопросы/52253127/ - person ClassA; 10.09.2018

Предположительно, если вы используете MediaMetaDataRetriever, вы также используете MediaPlayer из того же фреймворка.

Если это так, MediaPlayer предоставляет метод seekTo(millis)

К сожалению, seekTo перемещает дорожку в timestamp, а не кадр, но вы сможете определить правильную позицию для перемещения, если знаете частоту кадров.

Кроме того: при просмотре getFrameAtTime параметром, который он принимает, является «uSecs», который я принимаю за микросекунды - это означает, что метод может возвращать гораздо больше, чем один кадр в секунду - проблема, которую вы видите, может быть потому, что если нет кадра в именно в эту микросекунду требуется соседний кадр

Это означает, что если ваше видео имеет 30 кадров в секунду, кадр будет появляться каждые 33,333 мкс, поэтому обязательно используйте интервалы, близкие к этому размеру, при вызове getFrameAtTime

person Nick Cardoso    schedule 22.02.2017
comment
Я пробовал это, но он пропускает только ключевые кадры, которые существуют каждую секунду снова. Нет ли способа игнорировать это? - person hermt2; 22.02.2017
comment
Я не настолько хорошо знаком, я просто немного взглянул на исходный код, потому что проблема была интересной, извините. - person Nick Cardoso; 22.02.2017
comment
Есть ли у вас контроль над предоставляемыми типами видео? Возможно, другой формат с другим кодеком даст лучшие результаты. - person Nick Cardoso; 22.02.2017
comment
Это видео с нестандартной камеры, которую я сделал. - person hermt2; 22.02.2017

У меня такая же проблема.

MediaMetaDataRetriever.getFrameAtTime() работает так, как вы хотите в API 27.

person Jeff    schedule 31.05.2018

вы можете использовать те же метаданные библиотечного носителя **retriver.MediaMetaDataRetriever.getFrameAtTime(OPTION_CLOSEST)**. вам нужно использовать OPTION_CLOSEST, а не OPTION_CLOSEST_SYNC.OPTION_CLOSEST_SYNC быстрее, чем OPTION_CLOSEST, но он заменяет каждый первый кадр 30 кадрами в секунду. OPTION_CLOSEST работает медленно по сравнению с OPTION_CLOSEST_SYNC, но работает нормально.

person kamran liaqat    schedule 20.02.2021