6

AudioRecord オブジェクトから生データを取得し、MediaMuxer と MediaCodec を使用してファイルに保存しようとしています。

コーデックを開始し、マルチプレクサを開始し、データを入力バッファにロードしますが、そのような運はありません。

デバッグ調査の結果、 への呼び出しで問題が発生していることがわかりましたdequeueInputBuffer()。データの最初のいくつかのチャンクは成功しているように見えますが、最終的にはコンスタントdequeueInputBuffer()に返されます。-1

私が行方不明であることは明らかですか?これは、入力バッファがいっぱいになっているように見えますが、コーデックによって決して解放されていません。

関連コードのスニペット:

int numChunks = input.length / CHUNKSIZE;
mAudioEncoder.start();
    for (int chunk = 0; chunk <= numChunks; chunk++) {
        byte[] passMe = new byte[CHUNKSIZE];
        int inputBufferIndex = -1;
        Log.d("offerAudioEncoder","printing chunk #" + chunk + "of " + numChunks);
        //Copy the data into the chunk array
        if (chunk < input.length / CHUNKSIZE)
            for (int i = 0; i < CHUNKSIZE; i++)
                passMe[i] = input[chunk * CHUNKSIZE + i];
        else {
            eosReceived = true;
            for (int i = 0; chunk * CHUNKSIZE + i < input.length; i++)
                passMe[i] = input[chunk * CHUNKSIZE + i];
        }

        //Get the input buffer
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
            while(inputBufferIndex < 0)//justk keep trying.
                inputBufferIndex = mAudioEncoder.dequeueInputBuffer(100);
            inputBuffer = mAudioEncoder.getInputBuffer(inputBufferIndex);
        } else {
            //backwards compatibility.
            ByteBuffer[] inputBuffers = mAudioEncoder.getInputBuffers();
            inputBufferIndex = mAudioEncoder.dequeueInputBuffer(-1);
            if (inputBufferIndex >= 0)
                inputBuffer = inputBuffers[inputBufferIndex];
        }

        //Plop the data into the input buffer
        if (inputBuffer != null) {
            inputBuffer.clear();
            inputBuffer.put(passMe);
        }
        long presentationTimeUs = chunk * 10000000; //each encoded chunk represents one second of audio
        //this is what the frame should be labeled as
        mAudioEncoder.queueInputBuffer(inputBufferIndex, 0, passMe.length, presentationTimeUs, 0);

        //Pull the output buffer.
        int encoderStatus = -1;
        while(encoderStatus < 0) //Like, seriously, WAIT forever.
            encoderStatus = mAudioEncoder.dequeueOutputBuffer(mAudioBufferInfo, -1);//wait forever, why not?
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
            outputBuffer = mAudioEncoder.getOutputBuffer(encoderStatus);
        else {
            ByteBuffer[] encoderOutputBuffers = mAudioEncoder.getOutputBuffers();
            outputBuffer = encoderOutputBuffers[encoderStatus];
        }

        if(encoderStatus >= 0) {
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
                mMuxer.writeSampleData(audioTrackIndex, outputBuffer, mAudioBufferInfo);

            //Done with the output buffer, release it.
            mAudioEncoder.releaseOutputBuffer(encoderStatus, false);
        }//TODO: Add cases for what to do when the output format changes
4

1 に答える 1

2

わかりました。最終的に、チャンキングロジックをダンプし、設定して入力バッファのサイズを増やしただけです

audioFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 14000000);

MediaCodec の configure メソッドに渡される MediaFormat オブジェクト用。

また、良いヒント: 必ず 16 ビット オーディオ エンコーディングを使用し、ショートを吐き出す AudioRecord.read メソッドを使用してください。バイトは厄介なオーディオを生成するようです (おそらく、AudioRecord が 16 ビットで動作することを望んでいるため)。

于 2017-01-12T19:11:50.057 に答える