音视频开发系列
Android音视频开发 -> ffmpeg+h264+aac编译以及测试调用
Android音视频开发 -> ffmpeg+h264+avfilter+camera推流旋转角度
Android音视频开发 -> fdk-aac编码pcm为eld-aac
Android音视频开发 -> fdk-aac解码eld-aac为pcm
几个相关概念
- 采样频率 > 以8000为例
- 通道数 > 以单通道为例
- 采样格式 > 以16bit为例
直接上代码
public class AudioUtil {
//音频采集输入源
int audioSource = MediaRecorder.AudioSource.MIC;
//音频的采样频率
int sampleRate = 8000;
//单通道
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
//音频PCM数据的采样格式
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
//配置音频内部数据的缓冲区(我这里是因为在使用fdk-aac编码的时候单通道的字节数量为1024所以这里直接写1024位缓冲区长度)
// int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
int bufferSize = 1024;
public static AudioUtil audioUtil;
private AudioRecord audioRecord;
private byte[] pcmByte;
private boolean isAudio = false;
public static AudioUtil getInstance() {
if (audioUtil == null) {
audioUtil = new AudioUtil();
}
return audioUtil;
}
public int audioInit(Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
return -1;
}
isAudio = false;
audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, bufferSize);
if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
audioRecord = null;
bufferSize = 0;
return -1;
}
pcmByte = new byte[bufferSize];
return 0;
}
//开始读取本地音频
public void audioStart() {
try {
audioRecord.startRecording();
isAudio = true;
} catch (Exception e) {
}
}
//停止读取本地音频
public void audioStop() {
if (audioRecord != null) {
audioRecord.stop();
isAudio = false;
audioRecord.stop();
audioRecord.release();
}
}
//获取本地读取到的音频数据
public void audioRead() {
int read = -1;
while (isAudio) {
read = audioRecord.read(pcmByte, 0, bufferSize);
if (read < AudioRecord.SUCCESS) {
break;
}
if (read >= AudioRecord.SUCCESS) {
synchronized (AudioUtil.class) {
pcmByte -> 这个byte[]里面就是读取到的原始PCM音频数据,这里拿到原始数据就可以为所欲为啦哈
}
}
}
}
}