Android MediaMetadataRetriever OPTION_CLOSET не работает для некоторых видео
Я только начинаю разработку Android.
Некоторое время я пытался извлечь кадры из видеофайлов, которые есть на моем телефоне, вот так:
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(getApplicationContext(),linkToVideo); // linkToVideo is Uri
ImageView frameView = (ImageView) findViewById(R.id.video_frame);
frameView.setImageBitmap(retriever.getFrameAtTime(frameTime,MediaMetadataRetriever.OPTION_CLOSEST)); // frameTime in microseconds
Это работает для видео 640x480 .mp4, но не для файлов 1280x720 .3gp, записанных моей камерой. Это занимает очень много времени и приложение перестает отвечать на запросы. Когда я использую OPTION_CLOSEST_SYNC, все идет гладко, однако мне интересно получить больше, чем просто синхронизировать кадры.
Любые идеи о том, как я могу решить это? Я пытался избежать кодирования видео, но если нет другого выбора, я прибегну к этому.
Заранее спасибо за то время, которое вы уделите мне.
2 ответа
Попробуйте https://github.com/wseemann/FFmpegMediaMetadataRetriever:
import wseemann.media.FFmpegMediaMetadataRetriever;
...
FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
retriever.setDataSource(getApplicationContext(),linkToVideo); // linkToVideo is Uri
ImageView frameView = (ImageView) findViewById(R.id.video_frame);
frameView.setImageBitmap(retriever.getFrameAtTime(frameTime,MediaMetadataRetriever.OPTION_CLOSEST)); // frameTime in microseconds
Умножьте MediaPlayer.currentPosition на 1000.
SNAPSHOT_DURATION_IN_MILLIS * 1000
Пример
val mediaMetadataRetriever = MediaMetadataRetriever()
return try {
println("mediaPlayer.currentPosition.toLong(): ${mediaPlayer?.currentPosition?.toLong()}")
mediaMetadataRetriever.setDataSource(context, uri)
val bitmap = mediaPlayer?.let { mediaMetadataRetriever.getFrameAtTime(it.currentPosition.toLong()*1000, MediaMetadataRetriever.OPTION_CLOSEST) }
bitmap
} catch (t: Throwable) {
// TODO log
null
} finally {
try {
mediaMetadataRetriever.release()
} catch (e: RuntimeException) {
//
}
}