鴻蒙OS 音頻播放開發(fā)指導(dǎo)

2020-09-18 14:27 更新

場景介紹

音頻播放的主要工作是將音頻數(shù)據(jù)轉(zhuǎn)碼為可聽見的音頻模擬信號并通過輸出設(shè)備進(jìn)行播放,同時對播放任務(wù)進(jìn)行管理。

接口說明

接口名 描述
AudioRenderer(AudioRendererInfo audioRendererInfo, PlayMode pm) throws IllegalArgumentException 構(gòu)造函數(shù),設(shè)置播放相關(guān)音頻參數(shù)和播放模式,使用默認(rèn)播放設(shè)備。
AudioRenderer(AudioRendererInfo audioRendererInfo, PlayMode pm, AudioDeviceDescriptor outputDevice) throws IllegalArgumentException 構(gòu)造函數(shù),設(shè)置播放相關(guān)音頻參數(shù)、播放模式和播放設(shè)備。
boolean start() 播放音頻流。
boolean write(byte[] data, int offset, int size) 將音頻數(shù)據(jù)以 byte 流寫入音頻接收器以進(jìn)行播放。
boolean write(short[] data, int offset, int size) 將音頻數(shù)據(jù)以 short 流寫入音頻接收器以進(jìn)行播放。
boolean write(float[] data, int offset, int size) 將音頻數(shù)據(jù)以 float 流寫入音頻接收器以進(jìn)行播放。
boolean write(java.nio.ByteBuffer data, int size) 將音頻數(shù)據(jù)以 ByteBuffer 流寫入音頻接收器以進(jìn)行播放。
boolean pause() 暫停播放音頻流。
boolean stop() 停止播放音頻流。
boolean release() 釋放播放資源。
AudioDeviceDescriptor getCurrentDevice() 獲取當(dāng)前工作的音頻播放設(shè)備。
boolean setPlaybackSpeed(float speed) 設(shè)置播放速度。
boolean setPlaybackSpeed(AudioRenderer.SpeedPara speedPara) 設(shè)置播放速度與音調(diào)。
boolean setVolume(ChannelVolume channelVolume) 設(shè)置指定聲道上的輸出音量。
boolean setVolume(float vol) 設(shè)置所有聲道上的輸出音量。
static int getMinBufferSize(int sampleRate, AudioStreamInfo.EncodingFormat format, AudioStreamInfo.ChannelMask channelMask) 獲取Stream播放模式所需的buffer大小。
State getState() 獲取音頻播放的狀態(tài)。
int getRendererSessionId() 獲取音頻播放的 session ID。
int getSampleRate() 獲取采樣率。
int getPosition() 獲取音頻播放的幀數(shù)位置。
boolean setPosition(int position) 設(shè)置起始播放幀位置。
AudioRendererInfo getRendererInfo() 獲取音頻渲染信息。
boolean duckVolume() 降低音量并將音頻與另一個擁有音頻焦點(diǎn)的應(yīng)用程序混合。
boolean unduckVolume() 恢復(fù)音量。
SpeedPara getPlaybackSpeed() 獲取播放速度、音調(diào)參數(shù)。
boolean setSpeed(SpeedPara speedPara) 設(shè)置播放速度、音調(diào)參數(shù)。
Timestamp getAudioTime() 獲取播放時間戳信息。
boolean flush() 刷新當(dāng)前的播放流數(shù)據(jù)隊(duì)列。
static float getMaxVolume() 獲取播放流可設(shè)置的最大音量。
static float getMinVolume() 獲取播放流可設(shè)置的最小音量。
StreamType getStreamType() 獲取播放流的音頻流類型。

開發(fā)步驟

  1. 構(gòu)造音頻流參數(shù)的數(shù)據(jù)結(jié)構(gòu) AudioStreamInfo,推薦使用 AudioStreamInfo.Builder 類來構(gòu)造,模板如下,模板中設(shè)置的均為 AudioStreamInfo.Builder 類的默認(rèn)值,根據(jù)音頻流的具體規(guī)格來設(shè)置具體參數(shù)。

   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();

以真實(shí)的播放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();

  1. 使用創(chuàng)建的音頻流構(gòu)建音頻播放的參數(shù)結(jié)構(gòu)AudioRendererInfo,推薦使用AudioRendererInfo.Builder類來構(gòu)造,模板如下,模板中設(shè)置的均為AudioRendererInfo.Builder類的默認(rèn)值,根據(jù)音頻播放的具體規(guī)格來設(shè)置具體參數(shù)。

   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();

以真實(shí)的播放pcm流為例:

   AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(audioStreamInfo)
       .audioStreamOutputFlag(AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_DIRECT_PCM) // pcm格式的輸出流
       .bufferSizeInBytes(100)
       .distributedDeviceId("E54***5E8") // 使用分布式設(shè)備E54***5E8播放
       .isOffload(false) // false表示分段傳輸buffer并播放,true表示整個音頻流一次性傳輸?shù)紿AL層播放
       .build();

  1. 根據(jù)要播放音頻流指定 PlayMode,不同的 PlayMode 在寫數(shù)據(jù)時存在差異,詳情見[步驟7],其余播放流程是無區(qū)別的。并通過構(gòu)造函數(shù)獲取 AudioRenderer 類的實(shí)例化對象。

  1. 使用構(gòu)造函數(shù)獲取 AudioRenderer 類的實(shí)例化對象,其中[步驟2],[步驟3]中的數(shù)據(jù)為構(gòu)造函數(shù)的必選參數(shù),指定播放設(shè)備為可選參數(shù),根據(jù)使用場景選擇不同的構(gòu)造函數(shù)。

  1. (可選)構(gòu)造音頻播放回調(diào),首先構(gòu)造對象 AudioInterrupt,其中 setInterruptListener 方法的入?yún)⑿枰獙?shí)現(xiàn)接口類 InterruptListener, setStreamInfo 方法使用[步驟1]的 AudioStreamInfo 作為入?yún)?。然后調(diào)用 AudioManager 類的 activateAudioInterrupt(AudioInterrupt interrupt)方法進(jìn)行音頻播放回調(diào)注冊。代碼示例如下:

   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);

  1. 調(diào)用 AudioRenderer 實(shí)例化對象的 start() 方法啟動播放任務(wù)。

  1. 將要播放的音頻數(shù)據(jù)讀取為 byte 流或 short 流,對于選擇 MODE_STREAM 模式的 PlayMode,需要循環(huán)調(diào)用 write 方法進(jìn)行數(shù)據(jù)寫入。對于選擇 MODE_STATIC 模式的 PlayMode,只能通過調(diào)用一次 write 方法將要播放的音頻數(shù)據(jù)全部寫入,因此該模式限制在文件規(guī)格較小的音頻數(shù)據(jù)播放場景下才能使用。

  1. (可選)當(dāng)需要對音頻播放進(jìn)行暫?;蛲V箷r,調(diào)用 AudioRenderer 實(shí)例化對象的 pause() 或 stop() 方法進(jìn)行暫停或停止播放。

  1. (可選)調(diào)用 AudioRenderer 實(shí)例化對象的 setSpeed 調(diào)節(jié)播放速度,setVolume 調(diào)節(jié)播放音量。

  1. 播放任務(wù)結(jié)束后,調(diào)用 AudioRenderer 實(shí)例化對象的 release() 釋放資源。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號