Android系统提供了四个层面的音频API:
- Java层MediaRecorder&MediaPlayer系列;
- Java层AudioTrack&AudioRecorder系列;
- Jni层opensles;
- JNI层AAudio(Android O引入)
下面分别介绍这些API的使用及特点。
1. MediaRecorder&MediaPlayer
MediaRecorder与MediaPlayer并不能算完整意义的音频API,它们只是系统音频API的封装,除了采集/播放,他们集成了编码/解码、复用/解复用等能力。它们在最底层还是调用了AudioRecorder、AudioTrack。下面主要介绍它们的几个主要的配置项。
1.1 MediaRecorder
MediaRecorder因为已经集成了录音、压缩编码、封装复用等功能,所以使用起来相对比较简单。
MediaRecorder 使用起来相对简单,主要设置以下几项:
- 音源setAudioSource,系统提供的选项:
- AudioSource.DEFAULT:默认音频源;
- AudioSource.MIC:麦克风;
- AudioSource.VOICE_UPLINK:上行电话录音,android.Manifest.permission#CAPTURE_AUDIO_OUTPUT;
- AudioSource.VOICE_DOWNLINK:下行电话录音,android.Manifest.permission#CAPTURE_AUDIO_OUTPUT;
- AudioSource.VOICE_CALL:上下行电话录音,android.Manifest.permission#CAPTURE_AUDIO_OUTPUT;
- AudioSource.CAMCORDER:设定录音来源于同方向的相机麦克风相同,若相机无内置相机或无法识别,则使用预设的麦克风
- AudioSource.VOICE_RECOGNITION:用于语音识别;
- AudioSource.VOICE_COMMUNICATION:用于语音通话;
- AudioSource.UNPRECESSED:原始音频;
- AudioSource.VOICE_PERFORMANCE:低延迟用于满足实时音频处理;
- AudioSource.REMOTE_SUBMIX:用于传输系统混音的音频流到远端, android.Manifest.permission.CAPTURE_AUDIO_OUTPUT;
- AudioSource.ECHO_REFERENCE:回声抑制参考信号,SystemApi,android.Manifest.permission.CAPTURE_AUDIO_OUTPUT;
- AudioSource.RADIO_TUNER:电台广播声音,SystemApi;
- AudioSource.HOTWORD:抢占式的热词检测,SystemApi。
- 编码器setAudioEncoder
- Audio.Encoder.DEFAULT:
- Audio.Encoder.AMR_NB:
- Audio.Encoder.AMR_WB:
- Audio.Encoder.AAC:
- Audio.Encoder.HE_AAC:
- Audio.Encoder.AAC_ELD:4.1+
- Audio.Encoder.VORBIS:
- Audio.Encoder.OPUS:Android 10+
- 复用器setOutputFormat
- OutputFormat.DEFAULT
- OutputFormat.THREE_GPP:3GP;
- OutputFormat.MPEG_4:mp4;
- OutputFormat.RAW_AMR:.aac or .amr;
- OutputFormat.AMR_NB:amr nb;
- OutputFormat.AMR_WB:amr wb;
- OutputFormat.AAC_ADIF:aac adif;
- OutputFormat.AAC_ADTS:aac adts;
- OutputFormat.OUTPUT_FORMAT_RTP_AVP:网络流;
- OutputFormat.MPEG_2_TS:ts封装;
- OutputFormat.WEBM:webm 容器;
- OutputFormat.HEIF: heif容器;
- OutputFormat.OGG:ogg容器。
- 输出文件路径setOutputFile
示例代码:
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(PATH_NAME);
recorder.prepare();
recorder.start(); // Recording is now started
...
recorder.stop();
recorder.reset(); // You can reuse the object by going back to setAudioSource() step
recorder.release(); // Now the object cannot be reused
上面代码只是基本使用方式,具体使用还需结合项目具体需求制定具体逻辑,但是MediaRecorder使用时需实例化,所以在不用时一定要记得即时释放,以免造成内存泄漏。
MediaRecorder状态图:
总结:MediaRecorder 实现录音比较简单的,代码量相对较少,较为简明,但也有不足之处,例如输出文件格式选择较少,录音过程不能暂停等。
1.2 MediaPlayer
MediaPlayer使用示例:
MediaPlayer mediaPlayer = new MediaPlayer();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ALARM)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build();
mediaPlayer.setAudioAttributes(audioAttributes);
} else {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
}
mediaPlayer.reset();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// 播放完成
}
});
mediaPlayer.setDataSource(path);
mediaPlayer.prepare();
mediaPlayer.start();
//or mediaPlayer.prepareAsync()并在setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)设置的回调中start
1.2.1 状态图:
1.2.2setAudioStreamType提供的选项:
- AudioSystem.STREAM_VOICE_CALL:电话通话;
- AudioSystem.STREAM_SYSTEM:系统声音;
- AudioSystem.STREAM_RING:电话响铃声;
- AudioSystem.STREAM_MUSIC:音乐播放;
- AudioSystem.STREAM_ALARM:闹钟;
- AudioSystem.STREAM_NOTIFICATION:通知
AudioAttributes用来替代stream types,它可以设置比stream types更多的属性,有三个方面:
- usage(why):为什么要播放这个声音?
- content type(what):播放的内容是什么?是可选项,有些usage,比如CONTENT_TYPE_MOVIE是movie usage。
- flags(how):如何影响播放。
1.2.3 setDataSource说明
setDataSource设置播放源,可以是本地文件也可以是网络文件。如果是网络文件和本地比较大的文件,在主线程中调用prepare可能会导致ANR,所以尽量用prepareAsync,然后再onPrepared回调中调用start。
2. AudioRecorder&AudioTrack
2.1 AudioRecorder
AndioRecord 类的主要功能是让各种 Java 应用能够管理音频资源,以便它们通过此类能够录制平台的声音输入硬件所收集的声音。它的实现就是通过 "pulling 同步"(reading读取)AudioRecord 对象的声音数据来完成的。在录音过程中,应用所需要做的就是通过后面三个类方法中的一个去及时地获取 AudioRecord 对象的录音数据。 AudioRecord 类提供的三个获取声音数据的方法分别是 read(byte[], int, int), read(short[], int, int), read(ByteBuffer, int)。无论选择使用哪一个方法都必须事先设定方便用户的声音数据的存储格式。
开始录音的时候,一个 AudioRecord 需要初始化一个相关联的声音buffer,这个 buffer 主要是用来保存新的声音数据。这个 buffer 的大小,我们可以在对象构造期间去指定。它表明一个 AudioRecord 对象还没有被读取(同步)声音数据前能录多长的音(即一次可以录制的声音容量)。声音数据从音频硬件中被读出,数据大小不超过整个录音数据的大小(可以分多次读出),即每次读取初始化 buf