Android Red5视频通讯第二篇:音频数据采集
1.音频数据编码
采用speex编码。编译so库
https://download.youkuaiyun.com/download/sclgxt/12031721
例子中已经有编译好的so文件
2.jni使用new package com.speex.lib,新建Speex.java
//包名不能改
package com.speex.lib;
public class Speex {
/* quality
* 1 : 4kbps (very noticeable artifacts, usually intelligible)
* 2 : 6kbps (very noticeable artifacts, good intelligibility)
* 4 : 8kbps (noticeable artifacts sometimes)
* 6 : 11kpbs (artifacts usually only noticeable with headphones)
* 8 : 15kbps (artifacts not usually noticeable)
*/
private static final int DEFAULT_COMPRESSION = 4;
public Speex() {
init();
}
public void init() {
load();
open(DEFAULT_COMPRESSION);
}
private void load() {
//对应的so库名称
System.loadLibrary("speex");
}
public native int open(int compression);
public native int getFrameSize();
public native int decode(byte encoded[], short lin[], int size);
public native int encode(short lin[], int offset, byte encoded[], int size);
public native void close();
}
3.音频数据采集WechatAudioMicro.java
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;
import com.smaxe.io.ByteArray;
import com.smaxe.uv.client.microphone.AbstractMicrophone;
import com.smaxe.uv.stream.support.MediaDataByteArray;
import com.speex.lib.Speex;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class WechatAudioMicro extends AbstractMicrophone {
public static final String TAG="WechatAudioMicro";
private volatile boolean isEncoding = false;
private Speex speex = new Speex();
private byte[] SpeexRtmpHead = new byte[]{(byte) 0xB2};
private byte[] processedData = new byte[1024];
private ExecutorService singleExecutors = Executors.newSingleThreadExecutor();
Runnable recordRunnable = new Runnable() {
@Override
public void run() {
int bufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
short[] mAudioRecordBuffer = new short[bufferSize];
AudioRecord mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
mAudioRecord.startRecording();
int bufferRead;
int len;
isEncoding = true;
while (isEncoding) {
bufferRead = mAudioRecord.read(mAudioRecordBuffer, 0, bufferSize);
if (bufferRead > 0) {
try {
len = speex.encode(mAudioRecordBuffer, 0, processedData, bufferRead);
byte[] speexData = new byte[len + 1];
System.arraycopy(SpeexRtmpHead, 0, speexData, 0, 1);
System.arraycopy(processedData, 0, speexData, 1, len);
fireOnAudioData(new MediaDataByteArray(20, new
ByteArray(speexData)));
} catch (Exception e) {
//e.printStackTrace();
Log.i(TAG, "AudioMicro:" + e.getMessage());
}
}
}
mAudioRecord.stop();
mAudioRecord.release();
}
};
public void start() {
singleExecutors.execute(recordRunnable);
}
public void stop() {
isEncoding = false;
}
}