音频播放的主要工作是将音频数据转码为可听见的音频模拟信号并通过输出设备进行播放,同时对播放任务进行管理。
接口名 | 描述 |
---|---|
AudioRenderer(AudioRendererInfo audioRendererInfo, PlayMode pm) throws IllegalArgumentException | 构造函数,设置播放相关音频参数和播放模式,使用默认播放设备。 |
AudioRenderer(AudioRendererInfo audioRendererInfo, PlayMode pm, AudioDeviceDescriptor outputDevice) throws IllegalArgumentException | 构造函数,设置播放相关音频参数、播放模式和播放设备。 |
boolean start() | 播放音频流。 |
boolean write(byte[] data, int offset, int size) | 将音频数据以 byte 流写入音频接收器以进行播放。 |
boolean write(short[] data, int offset, int size) | 将音频数据以 short 流写入音频接收器以进行播放。 |
boolean write(float[] data, int offset, int size) | 将音频数据以 float 流写入音频接收器以进行播放。 |
boolean write(java.nio.ByteBuffer data, int size) | 将音频数据以 ByteBuffer 流写入音频接收器以进行播放。 |
boolean pause() | 暂停播放音频流。 |
boolean stop() | 停止播放音频流。 |
boolean release() | 释放播放资源。 |
AudioDeviceDescriptor getCurrentDevice() | 获取当前工作的音频播放设备。 |
boolean setPlaybackSpeed(float speed) | 设置播放速度。 |
boolean setPlaybackSpeed(AudioRenderer.SpeedPara speedPara) | 设置播放速度与音调。 |
boolean setVolume(ChannelVolume channelVolume) | 设置指定声道上的输出音量。 |
boolean setVolume(float vol) | 设置所有声道上的输出音量。 |
static int getMinBufferSize(int sampleRate, AudioStreamInfo.EncodingFormat format, AudioStreamInfo.ChannelMask channelMask) | 获取Stream播放模式所需的buffer大小。 |
State getState() | 获取音频播放的状态。 |
int getRendererSessionId() | 获取音频播放的 session ID。 |
int getSampleRate() | 获取采样率。 |
int getPosition() | 获取音频播放的帧数位置。 |
boolean setPosition(int position) | 设置起始播放帧位置。 |
AudioRendererInfo getRendererInfo() | 获取音频渲染信息。 |
boolean duckVolume() | 降低音量并将音频与另一个拥有音频焦点的应用程序混合。 |
boolean unduckVolume() | 恢复音量。 |
SpeedPara getPlaybackSpeed() | 获取播放速度、音调参数。 |
boolean setSpeed(SpeedPara speedPara) | 设置播放速度、音调参数。 |
Timestamp getAudioTime() | 获取播放时间戳信息。 |
boolean flush() | 刷新当前的播放流数据队列。 |
static float getMaxVolume() | 获取播放流可设置的最大音量。 |
static float getMinVolume() | 获取播放流可设置的最小音量。 |
StreamType getStreamType() | 获取播放流的音频流类型。 |
AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder().sampleRate(
AudioStreamInfo.SAMPLE_RATE_UNSPECIFIED)
.audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_NONE)
.encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_INVALID)
.channelMask(AudioStreamInfo.ChannelMask.CHANNEL_INVALID)
.streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_UNKNOWN)
.build();
以真实的播放pcm流为例:
AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder().sampleRate(44100) // 44.1kHz
.audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_MAY_DUCK) // 混音
.encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT) // 16-bit PCM
.channelMask(AudioStreamInfo.ChannelMask.CHANNEL_OUT_STEREO) // 双声道
.streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_MEDIA) // 媒体类音频
.build();
AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(audioStreamInfo)
.audioStreamOutputFlag(AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_NONE)
.bufferSizeInBytes(0)
.distributedDeviceId("")
.isOffload(false)
.sessionID(AudioRendererInfo.SESSION_ID_UNSPECIFIED)
.build();
以真实的播放pcm流为例:
AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(audioStreamInfo)
.audioStreamOutputFlag(AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_DIRECT_PCM) // pcm格式的输出流
.bufferSizeInBytes(100)
.distributedDeviceId("E54***5E8") // 使用分布式设备E54***5E8播放
.isOffload(false) // false表示分段传输buffer并播放,true表示整个音频流一次性传输到HAL层播放
.build();
AudioInterrupt audioInterrupt = new AudioInterrupt();
AudioManager audioManager = new AudioManager();
audioInterrupt.setStreamInfo(streamInfo);
audioInterrupt.setInterruptListener(new AudioInterrupt.InterruptListener() {
@Override
public void onInterrupt(int type, int hint) {
if (type == AudioInterrupt.INTERRUPT_TYPE_BEGIN
&& hint == AudioInterrupt.INTERRUPT_HINT_PAUSE) {
renderer.pause();
} else if (type == AudioInterrupt.INTERRUPT_TYPE_BEGIN
&& hint == AudioInterrupt.INTERRUPT_HINT_NONE) {
} else if (type == AudioInterrupt.INTERRUPT_TYPE_END && (
hint == AudioInterrupt.INTERRUPT_HINT_NONE
|| hint == AudioInterrupt.INTERRUPT_HINT_RESUME)) {
renderer.play();
} else {
}
}
});
audioManager.activateAudioInterrupt(audioInterrupt);