要件: 動画ファイルを反転して、新しい動画ファイルとして 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();
これは、ビデオ フレームが逆の順序で出力ファイルに書き込まれることを想定して行われました。しかし、結果は元のビデオと同じでした (反転していません)。
ここで試したことは意味がないと感じています。基本的に、ビデオフォーマット、コーデック、バイトバッファなどについてはあまり理解していません。
また、opencv、ffmpegなどの優れたJavaラッパーであるJavaCVを使用してみましたが、そのライブラリで動作するようになりました。ただし、エンコード処理に時間がかかり、ライブラリのせいで apk のサイズが大きくなりました。
Android に組み込まれている MediaCodec API を使用すると、より高速で軽量になることが期待されます。しかし、同じものを提供している場合は、他のソリューションも受け入れることができます。
Androidでこれを行う方法について誰かが助けてくれれば幸いです。また、ビデオ、コーデック、ビデオ処理などの詳細/基本を学ぶのに役立つ素晴らしい記事があれば、それも役立ちます。