0

MediaExtractor クラスを使用して、保存された mp4 ビデオからエンコードされたオーディオ サンプル データを以下のように取得できます。

ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 256);
MediaExtractor audioExtractor = new MediaExtractor();
try {
    int trackIndex = -1;
    audioExtractor.setDataSource(originalMediaItem.getFilePath());

    for (int i = 0; i < audioExtractor.getTrackCount(); i++) {
        MediaFormat format = audioExtractor.getTrackFormat(i);
        String mime = format.getString(MediaFormat.KEY_MIME);

        if (mime.startsWith("audio/")) {
            trackIndex = i;
            break;
        }
    }

    audioExtractor.selectTrack(trackIndex);

    mAudioFormatMedia = audioExtractor.getTrackFormat(trackIndex);
    mAudioTrackIndex = mMediaMuxer.addTrack(mAudioFormatMedia);

    int size = audioExtractor.readSampleData(byteBuffer, 0);
    do {
        if (audioExtractor.getSampleTrackIndex() == 1) {
            long presentationTime = audioExtractor.getSampleTime();
            mInputBufferHashMap.put(presentationTime, byteBuffer);
            audioExtractor.advance();
            size = audioExtractor.readSampleData(byteBuffer, 0);
        }
    } while (size >= 0);
    audioExtractor.release();
    audioExtractor = null;
} catch (IOException e) {
    e.printStackTrace();
}

GlSurface からのビデオ ソースがあり、MediaMuxer を使用して、このビデオと前述のオーディオ抽出を多重化したいと考えています。ビデオの処理中に、ハッシュマップを使用してオーディオがマルチプレクサにインターリーブされます。ビデオとオーディオの両方を多重化し、再生可能な mp4 ビデオを作成することに成功しましたが、オーディオは元の mp4 の元のオーディオのようには聞こえません。

マルチプレクサに書き込むと、予想される bufferinfo.size と bufferInfo.presentationTimeUs が表示されます。

mMediaMuxer.writeSampleData(mAudioTrackIndex, buffer, mAudioBufferInfo);
Log.d(TAG, String.format("Wrote %d audio bytes at %d", mAudioBufferInfo.size, mAudioBufferInfo.presentationTimeUs));

このhttps://gist.github.com/ams/1991ab18fbcb0fcc2cf9のように、MediaCodec で標準の inputBuffer、outputBuffer を使用しようとしましたが、これは同じオーディオを生成し、私の理解では、MediaExtractor は既にエンコードされたオーディオ データである必要があります。そのため、データを直接パイプできる必要があります。

また興味深いのは、最初に抽出するときにフラグをチェックするときです。

if( (audioExtractor.getSampleFlags() & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) 
   Log.d(TAG, "BUFFER_FLAG_END_OF_STREAM")

上記のどちらも、元の mp4 ビデオでは印刷されません。私は現在、元の mp4 ビデオと、mp4 の抽出不可能なオーディオトラックを持つことが可能かどうか、およびこれをどのように確認できるかについて質問しています。

私は、stackoverflow に関するすべての MediaExtractor の質問と、github 上の MediaExtractor の多くのシングルトン ソリューションではないにしても、ほとんどを調べたと思います。オーディオを別の方法で抽出する方法、つまり ExoPlayer を使用する方法を知っている人はいますか (Android プロジェクトに大量のオーバーヘッドが追加されるため、ffmpeg を使用しないことが望ましいです)。現在の実装にエラーがある場合は、洞察が役立ちます!

編集 1:これは、audioExtractor.getTrackFormat(trackIndex) の形式です。

{max-bitrate=512000, sample-rate=48000, track-id=2, durationUs=22373187, mime=audio/mp4a-latm, profile=2, channel-count=4, language=```, aac-profile =2、ビットレート=512000、最大入力サイズ=1764、csd-0=java.nio.HeapByteBuffer[pos=0 lim=2 cap=2]}

4

1 に答える 1