前面一段时间一直在学习android音视频的相关知识,我觉得应该分享出来,android音视频学习过程很有趣,也很有成就感,因为学习过后,你会发现你能做出的app类型又多了,而且往深层次学习时你会发现这些知识的通用性很高,并不局限于android。
数字音频通常分为三步:采样、量化、编码
采样:就是将获取的信号给数字化,其中有个概念就是采样频率,而人耳能听到的频率范围只有20Hz~20kHz,所以一般设置的都是44.1kHz
量化:就是如何去表达采样的数据,常用使用二进制来表示声音信号的幅度
编码:如何去保存采样和量化过后的数据,这就出现了很多格式,其中最基础的格式就是PCM(脉冲编码调制),就是裸数据格式完全没有压缩,PCM格式中有几个属性:量化格式、采样率、声道数
采样率:即前面采样中所说的采样频率
声道数:即单声道还是双声道以及更多声道
在android中我们使用AudioRecord来进行音频采集,采样量化编码全套服务最后输出PCM数据
首先要申请android.permission.RECORD_AUDIO权限
audioSize = AudioRecord.getMinBufferSize(44100,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC,
44100,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
audioSize);
我们可以看见初始化AudioRecord的几个属性
streamType: 音频来源,例如麦克风MediaRecorder.AudioSource.MIC
sampleRateInHz: 采样频率
channelConfig: 声道数
audioFormat:量化格式
bufferSizeInBytes:通过 getMinBufferSize()方法可以获得,根据我们采样录制的过程中的参数来确定,每次从硬件读取数据所需要的缓冲区的大小。
我们可以发现初始化所需要的属性基本就是PCM的属性
初始化完之后,AudioRecord使用就很简单了
while (isRecording) {
int readResult = audioRecord.read(bytes, 0, audioSize);
for (int i = 0; i < readResult; i++) {
outputStream.write(bytes[i]);
}
}
我们用关键字来控制无限循环,当停止录制的时候就关键字就控制while循环停止,然后在while循环中我们使用read方法,read方法会把数据传入byte数组中并返回数组大小,我们用for循环将byte数组中的数据用文件输出流输出到文件中,这就完成了PCM数据的采集,最后记住关闭audioRecord就可以了。
以上就是在android中音频的采集
AudioTrack 是用来播放音频的框架,只能播放已经解码的pcm流,而对于文件只能播放wav格式的音频文件
MediaPlayer 也可以用来播放音频,不过不一样的是mediaplayer播放的声音文件格式很很多,例如MP3,AAC,WAV,OGG,MIDI 等,而且实质上mediaplayer内部是会创建audiotrack,不过在之前会有文件解码器进行解码
int trackSize = AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
int streamType = AudioManager.STREAM_MUSIC;
int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int mode = AudioTrack.MODE_STREAM;
int minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);
audioTrack = new AudioTrack(streamType, sampleRate, channelConfig, audioFormat, Math.max(minBufferSize, 2048), mode)
初始化 Audiotrack 和初始化 AudioRecord 的属性很像
streamType:播放的音频类型,比如铃声,音乐声,警告声等等
sampleRateInHz 采样频率,依旧常用是44.1kHz
channelConfig 声道数
audioFormat:量化格式
bufferSizeInBytes:通过 getMinBufferSize()方法可以获得,根据我们播放的过程中的参数来确定,每次写入数据到audio内部缓冲区所需要的大小。
mode:这个就是audiotrack独一份了,表示写入缓冲区的方式,有两种模式,一种是MODE_STREAM,这种写法是通过write将音频数据一次次写入缓冲区,这样可能会有延时
而另外一种就是MODE_STATIC,这种写法是在调用audiotrack的play方法之前一次性把所有数据都写入缓冲区,这种适用与铃声这种小数据的类型,不然一次写入数据太大会导致无法给缓冲区分配足够大的内存
audioTrack.write(datas, 0, datas.length);
只用调用write方法就可以了,不过还是要记住关流
以上就是android中最基础的采集音频和播放pcm数据流了,如有不对请指正(下午打个球先 )