Android录音支持的格式有amr、aac,但这两种音频格式在跨平台上表现并不好。
MP3显然才是跨平台的最佳选择。
项目地址
实现思路概述
在分析代码前,我们需要明确几个问题
1. 如何最终生成MP3
实现MP3格式最好是借助Lame这个成熟的解决方案。
对于Android来说,需要借助JNI来调用Lame的C语言代码,实现音频格式的转化。
2. 如何获取最初的音频数据
AudioRecord类可以直接帮助我们获取音频数据。
3. 如何进行转换
网上有代码是先录制后转为MP3,这种效率比较低。因为如果录音时间过长,转换时间就会相应变长,用户在存储录音时需要等待的时间就会变长。
Samsung Developers先录后转示例代码
显然,这种方案是不可取的。
我们需要的是边录边转的实现方式,这样在停止录音进行存储的时候,就不会花费太长时间。
实现代码介绍
既然是录音,我们上面也提到了需要使用AudioRecord类,我们就从这个类的构造器开始说起
构造器
public AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
构造器参数很多,我们一点一点来看:
audioSource : 声源,一般使用MediaRecorder.AudioSource.MIC表示来自于麦克风
sampleRateInHz :官方明确说到只有44100Hz是所有设备都支持的。其他22050、16000和11025只能在某些设备上使用。
channelConfig : 有立体声(CHANNEL_IN_STEREO)和单声道(CHANNEL_IN_MONO)两种。但只有单声道(CHANNEL_IN_MONO)是所有设备都支持的。
audioFormat : 有ENCODING_PCM_16BIT和ENCODING_PCM_8BIT两种音频编码格式。同样的,官方声明只有ENCODING_PCM_16BIT是所有设备都支持的。
bufferSizeInBytes : 录音期间声音数据的写入缓冲区大小(单位是字节)。
其实从上面的解释可以看到,类的参数很多,但为了保证在所有设备上可以使用,我们真正需要填写的只有一个参数:bufferSizeInBytes,其他都可以使用通用的参数而不用自己费心来选择。
在深究bufferSizeInBytes该传入什么之前,我们先略过这一段,先来说一下录音的读取与转换。
录音的读取与转换策略
录音的读取其实和UDP差不多,需要不断的读取数据。
既然是不断,那么我们当然需要循环读取,意味着我们需要一个线程来单独读取录音,避免阻塞主线程。