Android播放音频
SDL是一个跨平台的音视频渲染库,是支持Android平台的,所以可以直接使用SDL库进行音频的播放。
但是SDL库在Android平台上的实现只有一种,就是通过JNI来调用Java层的AudioTrack来进行播放。所以如果你有其它的需求不想使用SDL库,那么可以直接使用Android平台原生API来播放音频。
Android平台音频播放API
前面录制的时候讲过,Android上音频输出的API比较繁琐,有多套实现。有Java层的实现AudioTrack,也有native层实现OpenSLES,在 Android O上又推出了新的native层实现AAudio,并且提供了Oboe库,对OpenSLES和AAudio进行了封装。
下面来详细的介绍下每套API的使用
AudioTrack
AudioTrack是Android平台提供的播放音频的Java层API,使用起来非常简单。通过设置待播放音频参数就可以创建一个AudioTrack对象,调用了play方法后,就可以开始写入数据了,通过write方法将数据写入,调用stop后就停止播放。
需要注意的是,在创建AudioTrack的时候,对于待播放的音频数据格式都已经设定好了,也就是说这个创建的AudioTrack只能播放这种格式的音频数据。所以一般在获取到音频流解码后,都需要将PCM数据进行重采样,重采样成和AudioTrack一样的数据格式,才能交给AudioTrack播放。
创建AudioTrack
AudioTrack的构造函数有两套,新的一套是在Android L推出的,老的一套已经被标记为deprecated。
1 | // 根据指定采样率、声道数、位数获取最小需要的缓冲区大小,后续再创建AudioTrack时设置的缓冲区大小必须大于这个值 |
播放模式
AudioTrack支持两种模式,MODE_STATIC和 MODE_STREAM
- MODE_STREAM : 预先将需要播放的音频数据读取到内存中,所以如果使用这种模式,那么在创建AudioTrack的时候,传入的缓冲区大小就必须是整个播放文件的大小,AudioTrack只会播放这么多数据。
- MODE_STREAM : 边读边播,不会将数据直接加载到内存,如果使用这种模式,需要注意每次写入的数据大小,需要确保小于或者等于创建时传入的缓冲区大小。一般使用这种模式。
音频流类型
- AudioManager.STREAM_VOICE_CALL : 电话
- AudioManager.STREAM_SYSTEM : 系统
- AudioManager.STREAM_RING : 响铃和消息
- AudioManager.STREAM_MUSIC : 音乐
- AudioManager.STREAM_ALARM : 闹钟
- AudioManager.STREAM_NOTIFICATION : 通知
- AudioManager.STREAM_BLUETOOTH_SCO : 蓝牙
- AudioManager.STREAM_SYSTEM_ENFORCED : 强制系统声音
- AudioManager.STREAM_DTMF : 双音多频
- AudioManager.STREAM_TTS : 语音
写入数据
1 |
|
OpenSL-ES
OpenSL-ES是Android平台上提供的高性能音频的API,相对Java层API有着一定的低延迟性。由于是C库,所以使用起来API相对繁琐一些。
配置数据参数
1 |
|
创建引擎
在OpenSLES中,任何API接口对象都要由引擎来创建
1 | // 设置线程安全模式 |
创建播放器
在OpenSLES中,播放需要通过播放器对象来进行,
1 | // 通过引擎实现创建混音器接口 |
写入数据
每次回调函数被触发,则说明播放器需要数据,通过调用Enqueue函数将数据写入到缓冲队列中
1 | void OpenSLESPlayer::SimpleBufferQueueCallback( |