鸿蒙媒体开发系列06——输出设备与音频流管理
头像 蓝亭书序 2026-08-25 17:45:05    发布
0 浏览 0 点赞 0 收藏

1、音频输出设备管理

有时设备同时连接多个音频输出设备,需要指定音频输出设备进行音频播放,此时需要使用AudioRoutingManager接口进行输出设备的管理。

👉🏻 创建一个AudioRoutingManager

在使用AudioRoutingManager管理音频设备前,需要先导入模块并创建实例。代码如下:


import audio from '@ohos.multimedia.audio';  // 导入audio模块

let audioManager = audio.getAudioManager();  // 需要先创建AudioManager实例

let audioRoutingManager = audioManager.getRoutingManager();  // 再调用AudioManager的方法创建AudioRoutingManager实例


目前支持的音频输出设备分别有:

    • EARPIECE:听筒,枚举值为1
    • SPEAKER:扬声器,枚举值为2
    • WIRED_HEADSET:有线耳机(有麦克风),枚举值为3
    • WIRED_HEADPHONES:有线耳机(无麦克风),枚举值为4
    • BLUETOOTH_SCO:蓝牙设备SCO连接,值为7
    • BLUETOOTH_A2DP:蓝牙设备A2DP连接,值为8
    • USB_HEADSET:USB耳机,带麦克风,值为22

👉🏻 获取输出设备信息

使用getDevices()方法可以获取当前所有输出设备的信息。


audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => {
  console.info('Promise returned to indicate that the device list is obtained.');
});


👉🏻 监听设备连接状态变化

可以设置监听事件来监听设备连接状态的变化,当有设备连接或断开时触发回调:


// 监听音频设备状态变化
audioRoutingManager.on('deviceChange', audio.DeviceFlag.OUTPUT_DEVICES_FLAG, (deviceChanged) => {
  console.info('device change type : ' + deviceChanged.type);  // 设备连接状态变化,0为连接,1为断开连接
  console.info('device descriptor size : ' + deviceChanged.deviceDescriptors.length);
  console.info('device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceRole);  // 设备角色
  console.info('device change descriptor : ' + deviceChanged.deviceDescriptors[0].deviceType);  // 设备类型
});

// 取消监听音频设备状态变化
audioRoutingManager.off('deviceChange', (deviceChanged) => {
  console.info('Should be no callback.');
});


👉🏻 设置激活输出类型

可以通过setCommunicationDevice(deviceType: CommunicationDeviceType, active: boolean, callback: AsyncCallback<void>): void 方法设置通信设备激活状态,使用callback方式异步返回结果。代码如下:


audioRoutingManager.setCommunicationDevice(audio.CommunicationDeviceType.SPEAKER, true, (err) => {
  if (err) {
    console.error(`Failed to set the active status of the device. ${err}`);
    return;
  }
  console.info('Callback invoked to indicate that the device is set to the active status.');
});


其中 deviceType 为输出设备类型,我们在前文中提到过,不再展开说明。

2、音频播放流管理

对于播放音频类的应用,开发者需要关注该应用的音频流的状态以做出相应的操作,比如监听到状态为播放中/暂停时,及时改变播放按钮的UI显示。

👉🏻 读取或监听应用内音频流状态变化

方法1:直接查看AudioRenderer的state:


let audioRendererState = audioRenderer.state;
console.info(`Current state is: ${audioRendererState }`)


方法2:注册stateChange监听AudioRenderer的状态变化:


audioRenderer.on('stateChange', (rendererState) => {
  console.info(`State change to: ${rendererState}`)
});


获取state后可对照AudioState来进行相应的操作,比如更改暂停播放按钮的显示等。

👉🏻 读取或监听所有音频流变化

如果部分应用需要查询获取所有音频流的变化信息,可以通过AudioStreamManager读取或监听所有音频流的变化。

如下为音频流管理调用关系图:

图片

在进行应用开发的过程中,开发者需要使用getStreamManager()创建一个AudioStreamManager实例,进而通过该实例管理音频流。开发者可通过调用on('audioRendererChange')监听音频流的变化,在音频流状态变化、设备变化时获得通知。同时可通过off('audioRendererChange')取消相关事件的监听。另外,开发者可以主动调用getCurrentAudioRendererInfoArray()来查询播放流的唯一ID、播放流客户端的UID、音频流状态等信息。


2.1、具体步骤

1. 创建AudioStreamManager实例。

在使用AudioStreamManager的API前,需要使用getStreamManager()创建一个AudioStreamManager实例。


import audio from '@ohos.multimedia.audio';
let audioManager = audio.getAudioManager();
let audioStreamManager = audioManager.getStreamManager();


2. 使用on('audioRendererChange')监听音频播放流的变化。如果音频流监听应用需要在音频播放流状态变化、设备变化时获取通知,可以订阅该事件。


audioStreamManager.on('audioRendererChange',  (AudioRendererChangeInfoArray) => {
  for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) {
    let AudioRendererChangeInfo = AudioRendererChangeInfoArray[i];
    console.info(`## RendererChange on is called for ${i} ##`);
    console.info(`StreamId for ${i} is: ${AudioRendererChangeInfo.streamId}`);
    console.info(`Content ${i} is: ${AudioRendererChangeInfo.rendererInfo.content}`);
    console.info(`Stream ${i} is: ${AudioRendererChangeInfo.rendererInfo.usage}`);
    console.info(`Flag ${i} is: ${AudioRendererChangeInfo.rendererInfo.rendererFlags}`); 
    for (let j = 0;j < AudioRendererChangeInfo.deviceDescriptors.length; j++) {
      console.info(`Id: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].id}`);
      console.info(`Type: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceType}`);
      console.info(`Role: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceRole}`);
      console.info(`Name: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].name}`);
      console.info(`Address: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].address}`);
      console.info(`SampleRates: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]}`);
      console.info(`ChannelCount ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]}`);
      console.info(`ChannelMask: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelMasks}`);
    }
  }
});


3. (可选)使用off('audioRendererChange')取消监听音频播放流变化。


audioStreamManager.off('audioRendererChange');
console.info('RendererChange Off is called ');


4. (可选)使用getCurrentAudioRendererInfoArray()获取所有音频播放流的信息。

该接口可获取音频播放流唯一ID,音频播放客户端的UID,音频状态以及音频播放器的其他信息。


async function getCurrentAudioRendererInfoArray(){
  await audioStreamManager.getCurrentAudioRendererInfoArray().then( function (AudioRendererChangeInfoArray) {
    console.info(`getCurrentAudioRendererInfoArray  Get Promise is called `);
    if (AudioRendererChangeInfoArray != null) {
      for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) {
        let AudioRendererChangeInfo = AudioRendererChangeInfoArray[i];
        console.info(`StreamId for ${i} is: ${AudioRendererChangeInfo.streamId}`);
        console.info(`Content ${i} is: ${AudioRendererChangeInfo.rendererInfo.content}`);
        console.info(`Stream ${i} is: ${AudioRendererChangeInfo.rendererInfo.usage}`);
        console.info(`Flag ${i} is: ${AudioRendererChangeInfo.rendererInfo.rendererFlags}`);  
        for (let j = 0;j < AudioRendererChangeInfo.deviceDescriptors.length; j++) {
          console.info(`Id: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].id}`);
          console.info(`Type: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceType}`);
          console.info(`Role: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].deviceRole}`);
          console.info(`Name: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].name}`);
          console.info(`Address: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].address}`);
          console.info(`SampleRates: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]}`);
          console.info(`ChannelCount ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]}`);
          console.info(`ChannelMask: ${i} : ${AudioRendererChangeInfo.deviceDescriptors[j].channelMasks}`);
        }
      }
    }
  }).catch((err) => {
    console.error(`Invoke getCurrentAudioRendererInfoArray failed, code is ${err.code}, message is ${err.message}`);
  });
}



【注意】对所有音频流状态进行监听的应用需要申请权限ohos.permission.USE_BLUETOOTH,否则无法获得实际的设备名称和设备地址信息,查询到的设备名称和设备地址(蓝牙设备的相关属性)将为空字符串。



©本站发布的所有内容,包括但不限于文字、图片、音频、视频、图表、标志、标识、广告、商标、商号、域名、软件、程序等,除特别标明外,均来源于网络或用户投稿,版权归原作者或原出处所有。我们致力于保护原作者版权,若涉及版权问题,请及时联系我们进行处理。
分类
HarmonyOS
地址:北京市朝阳区北三环东路三元桥曙光西里甲1号第三置业A座1508室 商务内容合作QQ:2291221 电话:13391790444或(010)62178877
版权所有:电脑商情信息服务集团 北京赢邦策略咨询有限责任公司
声明:本媒体部分图片、文章来源于网络,版权归原作者所有,我司致力于保护作者版权,如有侵权,请与我司联系删除

京ICP备:2022009079号-2

京公网安备:11010502051901号

ICP证:京B2-20230255