利用MediaCodec API 21录制视频和音频

时间:2014-12-10 17:26:17

标签: android mediacodec android-audiorecord mediamuxer

我一直在忙着使用MediaCodec和MediaMuxer一段时间来从虚拟显示器进行录制。我很好地工作了。现在我想录制麦克风的声音并将其添加到视频中。我找到了完全符合我想要的示例,但是所有这些示例都使用了MediaCodec的弃用部分。我真的很困惑如何重构新的api。

首先,我从这样的AudioRecord中读取了一个读取字节的线程。

while (running && recording) {
            audioPresentationTimeNs = System.nanoTime();

            iReadResult = mAudioRecord.read(mTempBuffer, 0, SAMPLES_PER_FRAME);
            if(iReadResult == AudioRecord.ERROR_BAD_VALUE || iReadResult == AudioRecord.ERROR_INVALID_OPERATION)
                Log.e(TAG, "audio buffer read error");

            // send current frame data to encoder
            try {

这不会起作用,因为dequeueInputBuffer不能被称为异步...那么我需要做些什么才能在这里获得正确的inputBufferIndex?

                int inputBufferIndex = audioEncoder.dequeueInputBuffer(-1);

                if (inputBufferIndex >= 0) {
                    inputBuffer = audioEncoder.getInputBuffer(inputBufferIndex);
                    inputBuffer.clear();
                    inputBuffer.put(mTempBuffer);

                    if(VERBOSE)Log.d(TAG, "sending frame to audio encoder");
                    audioEncoder.queueInputBuffer(inputBufferIndex, 0, mTempBuffer.length, audioPresentationTimeNs / 1000, 0);
                }
            } catch (Throwable t) {
                Log.e(TAG, "sendFrameToAudioEncoder exception");
                t.printStackTrace();
            }
        }

然后我的回调被我的AudioEncoder用来接收来自AudioRecord的数据:

private class audioEncoderCallback extends MediaCodec.Callback{

我应该收到inputData并以某种方式发送到onOutputBufferAvailable吗?

    @Override
    public void onInputBufferAvailable(MediaCodec codec, int index) {
    }

这件作品应该将数据传递给复用器

    @Override
    public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) {

        if(muxerStarted) {
            ByteBuffer encodedData = codec.getOutputBuffer(index);

            encodedData.position(info.offset);
            encodedData.limit(info.offset + info.size);

            mMuxer.writeSampleData(audioTrackIndex, encodedData, info);
            if (VERBOSE) Log.d(TAG, "AudioEncoder sent " + info.size + " bytes to mMuxer");

            codec.releaseOutputBuffer(index, false);
        }
    }

    @Override
    public void onError(MediaCodec codec, MediaCodec.CodecException e) {
        Log.d(TAG, "Error: " + e);
    }

我是否正确考虑同时使用audioTrackIndex和videoTrackIndex将数据传送到多路复用器?

    @Override
    public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
        if (VERBOSE) Log.d(TAG, "encoder output format changed: " + format);

        audioTrackIndex = mMuxer.addTrack(format);
        if(videoTrackIndex != -1) {
            muxerStarted = true;
            mMuxer.start();
        }
    }
}

0 个答案:

没有答案