仮想ディスプレイから記録するために、しばらく 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 を async と呼べないため機能しません...ここで正しい 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();
}
}
次に、AudioRecord からデータを受け取る必要がある AudioEncoder によって使用されるコールバックがあります。
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();
}
}
}