Есть ли какой-либо API, который может дать мне список штампов времени ключевых кадров для данного видеофайла в Android?
Как получить список фреймов ключевых кадров (синхронизирующих кадров) для видеофайла в Android?
Ответ 1
Я верю, что правильный ответ http://code.google.com/p/mp4parser/
API-интерфейс isoparser может читать и писать файловую структуру MP4. Это инструмент низкого уровня, имеющий дело с так называемыми ящиками, но он также касается структуры, такой как дорожки и фильмы.
Хороший API и способы намного быстрее, чем ffmpeg behemoth
Ответ 2
Для элегантного решения кажется, что вам нужно использовать ffmpeg для Android, чтобы достичь этого. Кто-то еще пробовал это так: Как получить фрейм из видеофайла в android; и было предложено использовать ffmpeg.
Я проверил справочное руководство, но мог найти способ получить только ключевой кадр (без метки времени) относительно данной позиции во времени с помощью MediaMetadataRetriever(), как описано здесь: http://developer.android.com/reference/android/media/MediaMetadataRetriever.html#extractMetadata%28int%29
Если вы не хотите использовать ffmpeg, вы можете попробовать следующее:
private ArrayList<int> getKeyFrameTimestamps(String filename) {
ArrayList<int> timeStamps = new ArrayList<int>();
try {
MediaMetadataRetriever mRetriever = new MediaMetadataRetriever();
mRetriever.setDataSource(getDataSource(filename));
mRetriever.getFrameAtTime(i, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
Bitmap lastFame = mRetriever.getFrameAtTime(0, MediaMetadataRetriever.OPTION_NEXT_SYNC);
result.add(0);
for(int time=1; frame ; ++time) {
Bitmap frame = mRetriever.getFrameAtTime(time, MediaMetadataRetriever.OPTION_PREVIOUS_SYNC);
if (frame && !frame.sameAs(lastFrame)) {
result.add(time);
lastFrame = frame;
}
}
} catch (Exception e) { /* TODO: HANDLE THIS */ }
return timeStamps;
}
Это, конечно, не очень элегантно, но, вероятно, будет работать без хлопот, чтобы установить ffmpeg... Вероятно, он тоже довольно медленный (я не знаю). Но, возможно, это именно то, что вам нужно.
PS: учебник ffmpeg, который подходит для вашей проблемы, можно найти здесь: http://dranger.com/ffmpeg/tutorial07.html
Ответ 3
4.1+ - быстрее, чем mp4parser, потому что сделано в native underneath и код чище
mp4parser вам нужно вычислить временные метки из getyncsamples + getsampledurations, что также раздражает, и они не совпадают с ffprobe. это дает точные результаты
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(getVideoPath());
int trackindex = MediaExtractorUtil.selectVideoTrack(extractor);
extractor.selectTrack(trackindex);
while (extractor.getSampleTime() != -1) {
long sampleTime = extractor.getSampleTime();
// check not really necessary but JIC
if ((extractor.getSampleFlags() & MediaExtractor.SAMPLE_FLAG_SYNC) > 0) {
mKeyframeTimestampsMS.add(sampleTime / 1000);
}
extractor.seekTo(sampleTime + 1, MediaExtractor.SEEK_TO_NEXT_SYNC);
}