Требование: я хочу перевернуть видеофайл и сохранить его как новый видеофайл в Android. т.е. окончательный выходной файл должен воспроизводить видео в обратном порядке.
Что я пробовал: я использовал приведенный ниже код (который я получил от AOSP https://android.googlesource.com/platform/cts/+/kitkat-release/tests)./tests/media/src/android/media/cts/MediaMuxerTest.java) с небольшой модификацией.
File file = new File(srcMedia.getPath());
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(file.getPath());
int trackCount = extractor.getTrackCount();
// Set up MediaMuxer for the destination.
MediaMuxer muxer;
muxer = new MediaMuxer(dstMediaPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// Set up the tracks.
HashMap<Integer, Integer> indexMap = new HashMap<Integer, Integer>(trackCount);
for (int i = 0; i < trackCount; i++) {
extractor.selectTrack(i);
MediaFormat format = extractor.getTrackFormat(i);
int dstIndex = muxer.addTrack(format);
indexMap.put(i, dstIndex);
}
// Copy the samples from MediaExtractor to MediaMuxer.
boolean sawEOS = false;
int bufferSize = MAX_SAMPLE_SIZE;
int frameCount = 0;
int offset = 100;
long totalTime = mTotalVideoDurationInMicroSeconds;
ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize);
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
if (degrees >= 0) {
muxer.setOrientationHint(degrees);
}
muxer.start();
while (!sawEOS) {
bufferInfo.offset = offset;
bufferInfo.size = extractor.readSampleData(dstBuf, offset);
if (bufferInfo.size < 0) {
if (VERBOSE) {
Log.d(TAG, "saw input EOS.");
}
sawEOS = true;
bufferInfo.size = 0;
} else {
bufferInfo.presentationTimeUs = totalTime - extractor.getSampleTime();
//noinspection WrongConstant
bufferInfo.flags = extractor.getSampleFlags();
int trackIndex = extractor.getSampleTrackIndex();
muxer.writeSampleData(indexMap.get(trackIndex), dstBuf,
bufferInfo);
extractor.advance();
frameCount++;
if (VERBOSE) {
Log.d(TAG, "Frame (" + frameCount + ") " +
"PresentationTimeUs:" + bufferInfo.presentationTimeUs +
" Flags:" + bufferInfo.flags +
" TrackIndex:" + trackIndex +
" Size(KB) " + bufferInfo.size / 1024);
}
}
}
muxer.stop();
muxer.release();
Основное изменение, которое я сделал, находится в этой строке
bufferInfo.presentationTimeUs = totalTime - extractor.getSampleTime();
Это было сделано в расчете на то, что видеокадры будут записаны в выходной файл в обратном порядке. Но результат был таким же, как и исходное видео (не перевернутое).
Я чувствую, что то, что я пробовал здесь, не имеет никакого смысла. По сути, я не очень разбираюсь в видеоформатах, кодеках, байтовых буферах и т. д.
Я также пробовал использовать JavaCV, который является хорошей оболочкой java поверх opencv, ffmpeg и т. д., и у меня получилось работать с этой библиотекой. Но процесс кодирования занимает много времени, а также размер apk стал большим из-за библиотеки.
Я ожидаю, что со встроенными в Android API MediaCodec все будет быстрее и легче. Но я могу принять и другие решения, если они предлагают то же самое.
Мы очень признательны, если кто-то может предложить любую помощь в том, как это можно сделать в Android. Кроме того, если у вас есть отличные статьи, которые могут помочь мне узнать специфику/основы о видео, кодеках, обработке видео и т. д., это тоже поможет.
MediaCodec
). - person vxh.viet   schedule 05.10.2016MediaCodec
, действующему как кодировщик, чтобы вы могли мультиплексировать его в файл MP4. Вы можете взглянуть на BigFlake для примера, но я не знаю, как передать входные данные вMediaCodec
из другого экземпляраMediaCodec
. Еще одним препятствием является то, что некоторые устройства плохо работают с несколькими экземплярамиMediaCodec
, особенно для видео высокого качества (см. -for-1080p-videos">вопрос здесь). - person vxh.viet   schedule 05.10.2016you will need to drop all the B frames between 2 key frames
? Как можно отбросить B-кадры? В настоящее время я возвращаюсь к предыдущему ключевому кадру и продолжаю кормить декодер, пока не получу кадр, который ищу. Это отлично работает, но, как вы упомянули, это прерывисто. - person KRK   schedule 20.08.2019