要求:我想反转视频文件并将其保存为android中的新视频文件。IE。最终输出文件应反向播放视频。
我尝试了什么:我使用了以下代码(我从 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,它是对 opencv、ffmpeg 等的一个很好的 java 包装器,我让它与那个库一起工作。但是编码过程需要很长时间,而且由于库的原因,apk 的大小也变得很大。
使用 android 内置的 MediaCodec API,我希望事情变得更快更轻量级。但如果他们提供相同的解决方案,我也可以接受其他解决方案。
如果有人可以提供有关如何在 android 中完成此操作的任何帮助,我们将不胜感激。此外,如果您有很棒的文章可以帮助我了解有关视频、编解码器、视频处理等的细节/基础知识,那也会有所帮助。