下面列出了android.media.AudioRecord#ERROR_INVALID_OPERATION 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void read(boolean endOfStream) {
mCurrentBuffer = mByteBufferPool.get();
if (mCurrentBuffer == null) {
LOG.e("Skipping audio frame, encoding is too slow.");
// TODO should fix the next presentation time here. However this is
// extremely unlikely based on my tests. The mByteBufferPool should be big enough.
} else {
mCurrentBuffer.clear();
mReadBytes = mAudioRecord.read(mCurrentBuffer, FRAME_SIZE);
if (mReadBytes > 0) { // Good read: increase PTS.
increaseTime(mReadBytes);
mCurrentBuffer.limit(mReadBytes);
onBuffer(endOfStream);
} else if (mReadBytes == AudioRecord.ERROR_INVALID_OPERATION) {
LOG.e("Got AudioRecord.ERROR_INVALID_OPERATION");
} else if (mReadBytes == AudioRecord.ERROR_BAD_VALUE) {
LOG.e("Got AudioRecord.ERROR_BAD_VALUE");
}
}
}
@Override
public void run() {
try {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
int bytesRecord;
byte[] tempBuffer = new byte[bufferSize];
mRecorder.startRecording();
while (isStart) {
if (mRecorder != null) {
bytesRecord = mRecorder.read(tempBuffer, 0, bufferSize);
if (bytesRecord == AudioRecord.ERROR_INVALID_OPERATION || bytesRecord ==
AudioRecord.ERROR_BAD_VALUE) {
continue;
}
if (bytesRecord != 0 && bytesRecord != -1) {
dos.write(tempBuffer, 0, bytesRecord);
} else {
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (!mIsLoopExit) {
byte[] buffer = new byte[SAMPLES_PER_FRAME * 2];
int ret = mAudioRecord.read(buffer, 0, buffer.length);
if (ret == AudioRecord.ERROR_INVALID_OPERATION) {
Log.e(TAG, "Error ERROR_INVALID_OPERATION");
} else if (ret == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG, "Error ERROR_BAD_VALUE");
} else {
if (mOnAudioFrameCapturedListener != null) {
mOnAudioFrameCapturedListener.onAudioFrameCaptured(buffer, System.nanoTime());
}
}
}
}
@Override
public void run() {
while (!mIsLoopExit) {
byte[] buffer = new byte[mMinBufferSize];
int ret = mAudioRecord.read(buffer, 0, mMinBufferSize);
if (ret == AudioRecord.ERROR_INVALID_OPERATION) {
Log.e(TAG, "Error ERROR_INVALID_OPERATION");
} else if (ret == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG, "Error ERROR_BAD_VALUE");
} else {
if (mAudioFrameCapturedListener != null) {
mAudioFrameCapturedListener.onAudioFrameCaptured(buffer);
}
Log.d(TAG, "OK, Captured " + ret + " bytes !");
}
SystemClock.sleep(10);
}
}
@Override
public void run() {
while (!mIsLoopExit) {
byte[] buffer = new byte[mMinBufferSize];
int ret = mAudioRecord.read(buffer, 0, mMinBufferSize);
if (ret == AudioRecord.ERROR_INVALID_OPERATION) {
Log.e(TAG , "Error ERROR_INVALID_OPERATION");
}
else if (ret == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG , "Error ERROR_BAD_VALUE");
}
else {
if (mAudioFrameCapturedListener != null) {
mAudioFrameCapturedListener.onAudioFrameCaptured(buffer);
}
Log.d(TAG , "OK, Captured "+ret+" bytes !");
}
SystemClock.sleep(10);
}
}
@Override
public int consume(final byte[] array, final int offset, final int count) throws IOException {
final int bytes = Math.min(readLimit, count);
//Log.d(TAG, "READING " + bytes + " B");
final int read = audioRecord.read(array, offset, bytes);
if (read == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG, "AUDIO RECORD ERROR - BAD VALUE");
return 0;
}
if (read == AudioRecord.ERROR_INVALID_OPERATION) {
Log.e(TAG, "AUDIO RECORD ERROR - INVALID OPERATION");
return 0;
}
if (read == AudioRecord.ERROR) {
Log.e(TAG, "AUDIO RECORD ERROR - UNKNOWN ERROR");
return 0;
}
if (wavFileWriter != null && read > 0) {
wavFileWriter.write(array, offset, read);
}
audioHandler.post(audioReader);
return read;
}
public void start() {
mAudioRecord.startRecording();
mMediaCodec.start();
final long startWhen = System.nanoTime();
final ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
mThread = new Thread(new Runnable() {
@Override
public void run() {
int len, bufferIndex;
while (isStart && !Thread.interrupted()) {
synchronized (mMediaCodec) {
if (!isStart) return;
bufferIndex = mMediaCodec.dequeueInputBuffer(10000);
if (bufferIndex >= 0) {
inputBuffers[bufferIndex].clear();
long presentationTimeNs = System.nanoTime();
len = mAudioRecord.read(inputBuffers[bufferIndex], bufferSize);
presentationTimeNs -= (len / samplingRate ) / 1000000000;
Loggers.i(TAG, "Index: " + bufferIndex + " len: " + len + " buffer_capacity: " + inputBuffers[bufferIndex].capacity());
long presentationTimeUs = (presentationTimeNs - startWhen) / 1000;
if (len == AudioRecord.ERROR_INVALID_OPERATION || len == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG, "An error occured with the AudioRecord API !");
} else {
mMediaCodec.queueInputBuffer(bufferIndex, 0, len, presentationTimeUs, 0);
if (onDataComingCallback != null) {
onDataComingCallback.onComing();
}
}
}
}
}
}
});
mThread.start();
isStart = true;
}
@Override void startPoolingAndWriting(AudioRecord audioRecord, int pullSizeInBytes,
OutputStream outputStream) throws IOException {
AudioChunk audioChunk = new AudioChunk.Bytes(new byte[pullSizeInBytes]);
while (pullableSource.isEnableToBePulled()) {
audioChunk.readCount(audioRecord.read(audioChunk.toBytes(), 0, pullSizeInBytes));
if (AudioRecord.ERROR_INVALID_OPERATION != audioChunk.readCount()
&& AudioRecord.ERROR_BAD_VALUE != audioChunk.readCount()) {
if (onAudioChunkPulledListener != null) {
postPullEvent(audioChunk);
}
writeAction.execute(audioChunk, outputStream);
}
}
}
@Override void startPoolingAndWriting(AudioRecord audioRecord, int pullSizeInBytes,
OutputStream outputStream) throws IOException {
final AudioChunk.Shorts audioChunk = new AudioChunk.Shorts(new short[pullSizeInBytes]);
while (pullableSource.isEnableToBePulled()) {
short[] shorts = audioChunk.toShorts();
audioChunk.readCount(audioRecord.read(shorts, 0, shorts.length));
if (AudioRecord.ERROR_INVALID_OPERATION != audioChunk.readCount()
&& AudioRecord.ERROR_BAD_VALUE != audioChunk.readCount()) {
if (onAudioChunkPulledListener != null) {
postPullEvent(audioChunk);
}
if (audioChunk.peakIndex() > -1) {
writeAction.execute(audioChunk, outputStream);
firstSilenceMoment = 0;
noiseRecordedAfterFirstSilenceThreshold++;
} else {
if (firstSilenceMoment == 0) {
firstSilenceMoment = System.currentTimeMillis();
}
final long silenceTime = System.currentTimeMillis() - firstSilenceMoment;
if (firstSilenceMoment != 0 && silenceTime > this.silenceTimeThreshold) {
if (silenceTime > 1000) {
if (noiseRecordedAfterFirstSilenceThreshold >= 3) {
noiseRecordedAfterFirstSilenceThreshold = 0;
if (silenceListener != null) {
postSilenceEvent(silenceListener, silenceTime);
}
}
}
} else {
writeAction.execute(audioChunk, outputStream);
}
}
}
}
}
private void onError(int errorCode) {
if (errorCode == AudioRecord.ERROR_INVALID_OPERATION) {
Log.w(TAG, "record fail: ERROR_INVALID_OPERATION");
mAudioDataCallback.onError();
} else if (errorCode == AudioRecord.ERROR_BAD_VALUE) {
Log.w(TAG, "record fail: ERROR_BAD_VALUE");
mAudioDataCallback.onError();
}
}
@Override
public void run() {
while (!mIsLoopExit) {
int ret = mAudioRecord.read(mAudioSrcBuffer, 0, mAudioSrcBuffer.length);
if (ret == AudioRecord.ERROR_INVALID_OPERATION) {
Log.e(TAG, "Error ERROR_INVALID_OPERATION");
} else if (ret == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG, "Error ERROR_BAD_VALUE");
} else {
if (mOnAudioFrameCapturedListener != null) {
mOnAudioFrameCapturedListener.onAudioFrameCaptured(mAudioSrcBuffer);
}
}
}
}
private void sendAudioToEncoder(boolean endOfStream) {
// send current frame data to encoder
try {
ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
audioInputBufferIndex = mMediaCodec.dequeueInputBuffer(-1);
if (audioInputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[audioInputBufferIndex];
inputBuffer.clear();
audioInputLength = mAudioRecord.read(inputBuffer, SAMPLES_PER_FRAME * 2);
audioAbsolutePtsUs = (System.nanoTime()) / 1000L;
// We divide audioInputLength by 2 because audio samples are
// 16bit.
audioAbsolutePtsUs = getJitterFreePTS(audioAbsolutePtsUs, audioInputLength / 2);
if (audioInputLength == AudioRecord.ERROR_INVALID_OPERATION)
Log.e(TAG, "Audio read error: invalid operation");
if (audioInputLength == AudioRecord.ERROR_BAD_VALUE)
Log.e(TAG, "Audio read error: bad value");
// if (VERBOSE)
// Log.i(TAG, "queueing " + audioInputLength + " audio bytes with pts " + audioAbsolutePtsUs);
if (endOfStream) {
if (VERBOSE) Log.i(TAG, "EOS received in sendAudioToEncoder");
mMediaCodec.queueInputBuffer(audioInputBufferIndex, 0, audioInputLength, audioAbsolutePtsUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
} else {
mMediaCodec.queueInputBuffer(audioInputBufferIndex, 0, audioInputLength, audioAbsolutePtsUs, 0);
}
}
} catch (Throwable t) {
Log.e(TAG, "_offerAudioEncoder exception");
t.printStackTrace();
}
}
@Override
public int read(@NonNull final byte[] buffer, final int byteOffset, final int byteCount) throws IOException {
final int bytesRead = audioRecord.read(buffer, byteOffset, byteCount);
if (bytesRead > 0) {
synchronized (bytesLock) {
if (config.isNormalizeInputSound())
normalize(buffer, bytesRead);
byte[] temp = bytes;
int tempLength = temp != null ? temp.length : 0;
bytes = new byte[tempLength + bytesRead];
if (tempLength > 0) {
System.arraycopy(temp, 0, bytes, 0, tempLength);
}
System.arraycopy(buffer, 0, bytes, tempLength, bytesRead);
while (bytes.length >= FRAME_SIZE_IN_BYTES) {
final byte[] b = new byte[FRAME_SIZE_IN_BYTES];
System.arraycopy(bytes, 0, b, 0, FRAME_SIZE_IN_BYTES);
vad.processBuffer(b, FRAME_SIZE_IN_BYTES);
temp = bytes;
final int newLength = temp.length - FRAME_SIZE_IN_BYTES;
bytes = new byte[newLength];
System.arraycopy(temp, FRAME_SIZE_IN_BYTES, bytes, 0, newLength);
}
onAudioLevelChanged((float) vad.calculateRms());
}
}
return bytesRead != 0 ? bytesRead : AudioRecord.ERROR_INVALID_OPERATION;
}
private void sendAudioToEncoder(boolean endOfStream) {
if (mMediaCodec == null)
mMediaCodec = mEncoderCore.getMediaCodec();
// send current frame data to encoder
try {
ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
audioInputBufferIndex = mMediaCodec.dequeueInputBuffer(-1);
if (audioInputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[audioInputBufferIndex];
inputBuffer.clear();
audioInputLength = mAudioRecord.read(inputBuffer, SAMPLES_PER_FRAME * 2);
audioAbsolutePtsUs = (System.nanoTime()) / 1000L;
// We divide audioInputLength by 2 because audio samples are
// 16bit.
audioAbsolutePtsUs = getJitterFreePTS(audioAbsolutePtsUs, audioInputLength / 2);
if(audioInputLength == AudioRecord.ERROR_INVALID_OPERATION)
Log.e(TAG, "Audio read error: invalid operation");
if (audioInputLength == AudioRecord.ERROR_BAD_VALUE)
Log.e(TAG, "Audio read error: bad value");
// if (VERBOSE)
// Log.i(TAG, "queueing " + audioInputLength + " audio bytes with pts " + audioAbsolutePtsUs);
if (endOfStream) {
if (VERBOSE) Log.i(TAG, "EOS received in sendAudioToEncoder");
mMediaCodec.queueInputBuffer(audioInputBufferIndex, 0, audioInputLength, audioAbsolutePtsUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
} else {
mMediaCodec.queueInputBuffer(audioInputBufferIndex, 0, audioInputLength, audioAbsolutePtsUs, 0);
}
}
} catch (Throwable t) {
Log.e(TAG, "_offerAudioEncoder exception");
t.printStackTrace();
}
}
@Override
public void run() {
FileOutputStream out = prepareWriting();
if (out == null) { return; }
AudioRecord record = new AudioRecord(AudioSource.VOICE_RECOGNITION, /*AudioSource.MIC*/
SAMPLING_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
record.startRecording();
int read = 0;
while (isRecording) {
read = record.read(audioBuffer, 0, bufferSize);
if ((read == AudioRecord.ERROR_INVALID_OPERATION) ||
(read == AudioRecord.ERROR_BAD_VALUE) ||
(read <= 0)) {
continue;
}
proceed();
write(out);
}
record.stop();
record.release();
finishWriting(out);
convertRawToWav();
}
/**
* 判断是是否有录音权限
*/
public static boolean isHasAudioPermission(final Context context){
int bufferSizeInBytes = 0;
bufferSizeInBytes = AudioRecord.getMinBufferSize(44100,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes);
//开始录制音频
//开始录制音频
try{
// 防止某些手机崩溃,例如联想
audioRecord.startRecording();
}catch (IllegalStateException e){
e.printStackTrace();
// AVLogUtils.e(TAG, Log.getStackTraceString(e));
}
/**
* 根据开始录音判断是否有录音权限
*/
if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING
&& audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED) {
// AVLogUtils.e(TAG, "audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING : " + audioRecord.getRecordingState());
return false;
}
if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED) {
//如果短时间内频繁检测,会造成audioRecord还未销毁完成,此时检测会返回RECORDSTATE_STOPPED状态,再去read,会读到0的size,可以更具自己的需求返回true或者false
return false;
}
byte[] bytes = new byte[1024];
int readSize = audioRecord.read(bytes, 0, 1024);
if (readSize == AudioRecord.ERROR_INVALID_OPERATION || readSize <= 0) {
// AVLogUtils.e(TAG, "readSize illegal : " + readSize);
return false;
}
audioRecord.stop();
audioRecord.release();
audioRecord = null;
return true;
}
@Override
protected void encode() throws IOException {
// 获取音频数据,并对其进行编码,之后传递给packetizer进行打包发送
// 或者采用设置编码器的方式?
final int bufferSize = AudioRecord.getMinBufferSize(8000/*mQuality.samplingRate*/, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*2;
((AACLATMPacketizer)mPacketizer).setSamplingRate(8000/*mQuality.samplingRate*/);
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000/*mQuality.samplingRate*/, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
mMediaCodec = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_BIT_RATE,32000 /*mQuality.bitRate*/);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 8000/*mQuality.samplingRate*/);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, bufferSize);
mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mAudioRecord.startRecording();
mMediaCodec.start();
final MediaCodecInputStream inputStream = new MediaCodecInputStream(mMediaCodec);
final ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
mThread = new Thread(new Runnable() {
@Override
public void run() {
int len = 0, bufferIndex = 0;
try {
while (!Thread.interrupted()) {
bufferIndex = mMediaCodec.dequeueInputBuffer(10000);
if (bufferIndex>=0) {
inputBuffers[bufferIndex].clear();
len = mAudioRecord.read(inputBuffers[bufferIndex], bufferSize);
if (len == AudioRecord.ERROR_INVALID_OPERATION || len == AudioRecord.ERROR_BAD_VALUE) {
L.e("An error occured with the AudioRecord API !");
} else {
//Log.v(TAG,"Pushing raw audio to the decoder: len="+len+" bs: "+inputBuffers[bufferIndex].capacity());
mMediaCodec.queueInputBuffer(bufferIndex, 0, len, System.nanoTime()/1000, 0);
}
}
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
});
mThread.start();
// 设置 packetizer 的发送地址
mPacketizer.setDestination(mDestination, mRtpPort, mRtcpPort);
// 设置 packetizer 的接收流,使其能够打包发送编码后的数据
mPacketizer.setInputStream(inputStream);
// 开始循环获取inputStream的数据
mPacketizer.start();
mStreaming = true;
}
/**
* 音声をレコードして、MediaCodec に渡します.
*/
private void recordAudio() throws NativeInterfaceException {
int samplingRate = mSamplingRate.getValue();
int channels = mChannels == 1 ? AudioFormat.CHANNEL_IN_MONO : AudioFormat.CHANNEL_IN_STEREO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSize = AudioRecord.getMinBufferSize(samplingRate, channels, audioFormat) * 4;
int oneFrameDataCount = mSamplingRate.getValue() / mFrameSize.getFps();
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT,
samplingRate,
channels,
audioFormat,
bufferSize);
if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
if (mAudioRecordCallback != null) {
mAudioRecordCallback.onEncoderError();
}
return;
}
if (mUseAEC && AcousticEchoCanceler.isAvailable()) {
// ノイズキャンセラー
mEchoCanceler = AcousticEchoCanceler.create(mAudioRecord.getAudioSessionId());
if (mEchoCanceler != null) {
int ret = mEchoCanceler.setEnabled(true);
if (ret != AudioEffect.SUCCESS) {
if (DEBUG) {
Log.w(TAG, "AcousticEchoCanceler is not supported.");
}
}
}
}
OpusEncoder opusEncoder = null;
try {
opusEncoder = new OpusEncoder(mSamplingRate, mChannels, mFrameSize, mBitRate, mApplication);
mAudioRecord.startRecording();
short[] emptyBuffer = new short[oneFrameDataCount];
short[] pcmBuffer = new short[oneFrameDataCount];
byte[] opusFrameBuffer = opusEncoder.bufferAllocate();
while (!mStopFlag) {
int readSize = mAudioRecord.read(pcmBuffer, 0, oneFrameDataCount);
if (readSize > 0) {
int opusFrameBufferLength;
if (isMute()) {
opusFrameBufferLength = opusEncoder.encode(emptyBuffer, readSize, opusFrameBuffer);
} else {
opusFrameBufferLength = opusEncoder.encode(pcmBuffer, readSize, opusFrameBuffer);
}
if (opusFrameBufferLength > 0 && mAudioRecordCallback != null) {
mAudioRecordCallback.onPeriodicNotification(opusFrameBuffer, opusFrameBufferLength);
}
} else if (readSize == AudioRecord.ERROR_INVALID_OPERATION) {
if (DEBUG) {
Log.e(TAG, "Invalid operation error.");
}
break;
} else if (readSize == AudioRecord.ERROR_BAD_VALUE) {
if (DEBUG) {
Log.e(TAG, "Bad value error.");
}
break;
} else if (readSize == AudioRecord.ERROR) {
if (DEBUG) {
Log.e(TAG, "Unknown error.");
}
break;
}
}
} finally {
if (mEchoCanceler != null) {
mEchoCanceler.release();
mEchoCanceler = null;
}
if (opusEncoder != null) {
opusEncoder.release();
}
}
}
@Override
@SuppressLint({ "InlinedApi", "NewApi" })
protected void encodeWithMediaCodec() throws IOException {
final int bufferSize = AudioRecord.getMinBufferSize(mQuality.samplingRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*2;
((AACLATMPacketizer)mPacketizer).setSamplingRate(mQuality.samplingRate);
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, mQuality.samplingRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
mMediaCodec = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_BIT_RATE, mQuality.bitRate);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mQuality.samplingRate);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, bufferSize);
mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mAudioRecord.startRecording();
mMediaCodec.start();
final MediaCodecInputStream inputStream = new MediaCodecInputStream(mMediaCodec);
final ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
mThread = new Thread(new Runnable() {
@Override
public void run() {
int len = 0, bufferIndex = 0;
try {
while (!Thread.interrupted()) {
bufferIndex = mMediaCodec.dequeueInputBuffer(10000);
if (bufferIndex>=0) {
inputBuffers[bufferIndex].clear();
len = mAudioRecord.read(inputBuffers[bufferIndex], bufferSize);
if (len == AudioRecord.ERROR_INVALID_OPERATION || len == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG,"An error occured with the AudioRecord API !");
} else {
//Log.v(TAG,"Pushing raw audio to the decoder: len="+len+" bs: "+inputBuffers[bufferIndex].capacity());
mMediaCodec.queueInputBuffer(bufferIndex, 0, len, System.nanoTime()/1000, 0);
}
}
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
});
mThread.start();
// The packetizer encapsulates this stream in an RTP stream and send it over the network
mPacketizer.setDestination(mDestination, mRtpPort, mRtcpPort);
mPacketizer.setInputStream(inputStream);
mPacketizer.start();
mStreaming = true;
}
@Override
@SuppressLint({ "InlinedApi", "NewApi" })
protected void encodeWithMediaCodec() throws IOException {
final int bufferSize = AudioRecord.getMinBufferSize(mQuality.samplingRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)*2;
((AACLATMPacketizer)mPacketizer).setSamplingRate(mQuality.samplingRate);
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, mQuality.samplingRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
mMediaCodec = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_BIT_RATE, mQuality.bitRate);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mQuality.samplingRate);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, bufferSize);
mMediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mAudioRecord.startRecording();
mMediaCodec.start();
final MediaCodecInputStream inputStream = new MediaCodecInputStream(mMediaCodec);
final ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
mThread = new Thread(new Runnable() {
@Override
public void run() {
int len = 0, bufferIndex = 0;
try {
while (!Thread.interrupted()) {
bufferIndex = mMediaCodec.dequeueInputBuffer(10000);
if (bufferIndex>=0) {
inputBuffers[bufferIndex].clear();
len = mAudioRecord.read(inputBuffers[bufferIndex], bufferSize);
if (len == AudioRecord.ERROR_INVALID_OPERATION || len == AudioRecord.ERROR_BAD_VALUE) {
Log.e(TAG,"An error occured with the AudioRecord API !");
} else {
//Log.v(TAG,"Pushing raw audio to the decoder: len="+len+" bs: "+inputBuffers[bufferIndex].capacity());
mMediaCodec.queueInputBuffer(bufferIndex, 0, len, System.nanoTime()/1000, 0);
}
}
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
});
mThread.start();
// The packetizer encapsulates this stream in an RTP stream and send it over the network
mPacketizer.setInputStream(inputStream);
mPacketizer.start();
mStreaming = true;
}