鸿蒙媒体开发系列06——输出设备与音频流管理

如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。

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,否则无法获得实际的设备名称和设备地址信息,查询到的设备名称和设备地址(蓝牙设备的相关属性)将为空字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值