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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2147832.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 爬虫 selenium 笔记

todo 阅读并熟悉 Xpath, 这个与 Selenium 密切相关、 selenium selenium 加入无图模式&#xff0c;速度快很多。 from selenium import webdriver from selenium.webdriver.chrome.options import Options# selenium 无图模式&#xff0c;速度快很多。 option Options() o…

栈、队列、链表

基于《啊哈&#xff01;算法》和《数据结构》&#xff08;人民邮电出版社&#xff09; 本博客篇幅较多&#xff0c;读者根据目录选择&#xff0c;不理解的可留言和私信。 栈、队列、链表都是线性结构。 三者都不是结构体、数组这种数据类型&#xff0c;我认为更像是一种算法…

面试必备!值得收藏!不容错过的100+ 大语言模型面试问题及答案

引言 大语言模型&#xff08;LLMs&#xff09;现在在数据科学、生成式人工智能&#xff08;GenAI&#xff0c;即一种借助机器自动产生新信息的技术&#xff09;和人工智能领域越来越重要。这些复杂的算法提升了人类的技能&#xff0c;并在诸多行业中推动了效率和创新性的提升。…

Windows如何查看已缓存的DNS信息

Windows server 2016如何查看已缓存的DNS信息 在Windows server 2016系统下&#xff0c;如何查看已缓存的DNS信息呢? 1.打开“运行”&#xff0c;输入cmd&#xff0c;点击“确定” 2.在命令行界面输入ipconfig /displaydns&#xff0c;按回车即可查看已缓存的dns信息

9月26日云技术研讨会 | SOA整车EE架构开发流程及工具实施方案

面向服务的架构&#xff08;Service Oriented Architecture, SOA&#xff09;实施需要复杂的基础技术作为支撑&#xff0c;伴随着整车硬件资源的集中化、车载以太网等高速通信技术在车内的部署&#xff0c;将在未来一段时间内成为行业技术研究和市场布局的热点。 近年来&#x…

分享几种方式获取免费精致的Live2d模型

文章目录 1、 Live2D官方示例数据集&#xff08;可免费下载&#xff09;2、模之屋3、unity商店4、直接b站搜索5、youtube6、BOOTH完结 1、 Live2D官方示例数据集&#xff08;可免费下载&#xff09; 官方提供了一些 Live2D实例模型给大家下载使用 地址&#xff1a;https://ww…

房屋租赁系统源码分享:SpringBoot + Vue 免费分享

这是一套使用 SpringBoot 与 Vue 开发的房屋租赁系统源码&#xff0c;站长分析过这套源码&#xff0c;推测其原始版本可能是一个员工管理系统&#xff0c;经过二次开发后&#xff0c;功能被拓展和调整&#xff0c;现已完全适用于房屋租赁业务。 源码说明&#xff1a; 该系统功…

一键生成高级感PPT封面,首推这个在线AI生成PPT软件!

PPT封面怎么做&#xff1f; ppt封面的重要性不言而喻&#xff0c;就像写文章讲究的“凤头”&#xff0c;一个漂亮的PPT封面&#xff0c;可以吸引观众的注意力&#xff0c;让人有意愿驻足下来听你演讲&#xff0c;才会有后面更多的故事发生。 漂亮的ppt封面怎么做&#xff1f;…

dll文件丢失怎么恢复?10种dll修复方法任你选,一次学会!

dll文件丢失怎么恢复&#xff1f;dll文件丢失在多个Windows 版本中都是常见的问题&#xff0c;包括win7/win8/win10和 win11。这类错误通常与一些特定的dll文件有关&#xff0c;比如MSVCR110.DLL、MSVCR71.DLL、d3compiler_43.DLL、LogiLDA.DLL、MSVCP140.DLL、api-ms-win-crt-…

组装电脑-电脑配置

键盘、鼠标&#xff1a;买一百多的机械盘。 主板 电脑台式机主板是计算机最基本的同时也是最重要的部件之一&#xff0c;它在整个计算机系统中扮演着举足轻重的角色。以下是对它的详细介绍&#xff1a; 基础功能&#xff1a; 主板作为计算机的核心部件&#xff0c;负责连接和…

【图像检索】基于颜色模型的图像内容检索,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于颜色模型的图像内容检索&#xff0c;用matlab实现。 一、案例背景和算法介绍 这…

inBuilder低代码平台新特性推荐-第二十四期

今天给大家带来的是 inBuilder 低代码平台新特性推荐第二十四期 ——表单格式支持流程配置。 场景介绍&#xff1a; 如下图所示&#xff0c;目前支持在流程设计上的不同节点设置表单字段的必填、显隐等属性控制&#xff0c;不必在表单设计上进行配置&#xff0c;从而减少了开…

VS Code远程连接虚拟机

VS Code远程连接虚拟机 1.下载vscode2.打开VS Code下载Remote-SSH插件1.修改相关信息 3.虚拟机检查或安装ssh4.检查虚拟机服务是否安装成功5.开启ssh&#xff0c;并检查是否开启成功 1.下载vscode 2.打开VS Code下载Remote-SSH插件 1.修改相关信息 2. 3.虚拟机检查或安装ssh…

同一个单元格内包含标签和文本框

<!DOCTYPE html> <html> <head> <title>单元格内包含标签和文本框</title> <style> /* 可选的CSS样式&#xff0c;用于美化表格 */ table { width: 50%; /* 设置表格宽度为页面宽度的50% */ border-collapse: collapse; /* 合并…

【JSrpc破解前端加密问题】

目录 一、背景 二、项目介绍 三、JSrpc 处理前端加密步骤 一、背景 解决日常渗透测试、红蓝对抗中的前端密码加密问题&#xff0c;让你的爆破更加丝滑&#xff1b;降低js逆向加密的难度&#xff0c;降低前端加密逻辑分析工作量和难度。 二、项目介绍 运行服务器程序和js脚本…

解锁生命活力密码!帕金森患者的专属锻炼秘籍,让每一步都稳健前行

在这个快节奏的时代&#xff0c;健康成为了我们最宝贵的财富之一。然而&#xff0c;对于帕金森病患者而言&#xff0c;身体的逐渐僵硬、运动能力的下降&#xff0c;似乎给生活按下了减速键。但请相信&#xff0c;科学的锻炼方法&#xff0c;就是那把重启生命活力的钥匙&#xf…

时间复杂度的常用符号+渐进时间复杂度分析

时间复杂度的常用符号 Θ \Theta Θ 如果 f ( n ) Θ ( g ( n ) ) f(n)\Theta(g(n)) f(n)Θ(g(n))&#xff0c;则 f ( n ) f(n) f(n) 与 g ( n ) g(n) g(n) 同阶。&#xff08;阶是指 f ( n ) f(n) f(n) 的指数&#xff0c;比如 n 2 n^2 n2 高于 n n n&#xff09; O O …

OJ在线评测系统 登录页面开发 前端后端联调实现全栈开发

前端 登录页面就是一个让用户输入账号和密码的表单 使用acro组件 先写布局 <a-form-item field"userAccount" label"账号"><a-input v-model"form.userAccount" placeholder"请输入账号" /></a-form-item><a-…

msvcp140.dll丢失如何解决?msvcp140.dll丢失的多种解决方法

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcp140.dll丢失”。这个错误通常会导致某些应用程序无法正常运行&#xff0c;给用户带来很大的困扰。那么&#xff0c;当我们遇到msvcp140.dll丢失的情况时&#xff0c;应该如何解决呢&a…

office2016 增强版 KMS

第一步&#xff1a; 用管理员权限登陆&#xff1a;Windows PowerShell &#xff08;安装最新的 PowerShell&#xff0c;了解新功能和改进&#xff01;https://aka.ms/PSWindows&#xff09; 第二步&#xff1a; C:\Windows\system32> cd C:\Program Files\Microsoft Off…