当前位置: 首页 > news >正文

学习指南:如何快速上手媒体生态一致体验开发

过去开发者们在使用多媒体能力时,往往会遇到这样的问题,比如:为什么我开发的相机不如系统相机的效果好?为什么我的应用和其他的音乐一起发声了,我要怎么处理?以及我应该怎么做才能在系统的播控中心里可以看到呢?对于开发者的这些疑问,HarmonyOS 通过提供简单易用体验一致的生态接口,使得开发者可以轻松解决上述问题。下面会按照不同模块逐个进行介绍。

一、相机

1.1 问题背景

相机应用在早期的版本开发时,会发现三方相机和系统相机拍照的效果会有较明显的不一致。如下图对比,可以看到,在色彩/饱和度/纹理细节等方面有一些明显的差异。

三方相机:

系统相机:

1.2 问题原因

那么这一问题是怎么产生的呢?主要有两个原因:

1、系统相机采用了私有通路,从而获取了更好的效果

2、预览流拍照效果差

1.3 问题解决

针对以上问题,系统提出了如下的解决思路:

1、统一接口,统一流程,统一效果:通过统一开发接口和流程,从而使得三方相机和系统相机获取一致的体验

2、分离预览、拍照、录像,明确流定义,让正确的流做正确的事

3、相机管道流水线模型

1.4 代码示例

1、相机基本控制流程如下:

2、示例参考:

使用 PreviewOutput 实现相机预览:

// 1. 创建预览视图XComponent,获取SurfaceIdsurfaceId = xComponent.getXComponentSurfaceId();// 2. 创建预览数据流输出PreviewOutputpreviewOutput = createPreviewOutput(profile, surfaceId);// 3. 添加预览数据流输出到相机会话session.addOutput(previewOutput);

使用 PhotoOutput 实现相机拍照:

// 1. 创建图片接收器ImageReceiver,获取SurfaceIdsurfaceId = imageReceiver.getReceivingSurfaceId();// 2. 创建拍照数据流输出PhotoOutputphotoOutput = createPhotoOutput(profile, surfaceId);// 3. 添加拍照数据流输出到相机会话session.addOutput(photoOutput);

使用 VideoOutput 实现相机录像:

// 1. 创建视频编码器AVRecorder,获取SurfaceIdsurfaceId = avRecorder.getInputSurface();// 2. 创建录像数据流输出VideoOutputvideoOutput = createVideoOutput(profile, surfaceId);// 3. 添加录像数据流输出到相机会话session.addOutput(videoOutput);

更多详细的代码参考:

https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/media/camera-overview.md

二、音视频焦点

2.1 问题背景

音视频应用开发中遇到的很常见的一个场景,就是并发播放,而并发播放的一般解决思路是各个应用对焦点的申请和处理。

传统的焦点管理方法,依赖应用遵守约定好的策略,如果有的应用不遵守,比如不响应或者滥用焦点,就可能会出现不发声或者乱发声的现象,影响了用户的体验。

2.2 解决思路

针对以上的问题,鸿蒙系统改进了焦点管理的设计,提供了统一的焦点处理策略,来规范应用对于焦点的使用,以达成统一的发声体验。

系统中的焦点管理模块会存储一个焦点策略表,定义了不同的场景下,哪些应用可以获取焦点进行播放,哪些应用会失去焦点而停止播放,等等其他策略。

2.3 代码示例

可以通过接口的使用来看一下实际处理策略。

首先,在 A 应用创建并使用 AudioRenderer 播放的时候,系统会自动为其申请焦点,这个是系统的行为。

A 应用播放后,系统的焦点策略会进行判断,如果 A 应用可以抢到焦点,那就会使得失去焦点的应用暂停播放;同时被暂停的应用也会在 INTERRUPT_FORCE 的回调事件中,得到暂停的状态,应用在收到这个事件后,就需要存储并更新应用内的状态。

当 A 应用停止播放,之前被暂停的应用也会收到一个恢复播放的事件,这个事件会在 INTERRUPT_SHARE 中,应用可以进行恢复播放的操作,或者忽略,这个非强制行为。

// 1.AudioRenderer进行播放时,系统会申请焦点audioRenderer.start((err) => {});// 2.注册音频打断事件的回调audioRenderer.on('audioInterrupt', (event) => {  if (event.forceType === audio.InterruptForceType.INTERRUPT_FORCE) {      // 3.强制打断类型:音频相关处理已由系统执行,应用需更新自身状态  } else if (event.forceType === audio.InterruptForceType.INTERRUPT_SHARE) {      // 4.共享打断类型:应用可自主选择执行相关操作或忽略打断事件  }});

更多详细的代码参考:

https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/media/audio-playback-concurrency.md

三、低时延播放

3.1 问题背景

游戏、K 歌、乐器等应用,对于音频的输出时延要求很高,常规的播放通路一般只能达到 60ms 左右甚至更高的时延,无法满足这些应用的使用诉求。

3.2 解决思路

鸿蒙系统提供了低时延通路的设计。如下图所示,在系统中的普通通路之外,新增了一条垂直打通硬件的低时延通路,通过 bypass 框架层直接在 DSP 进行混音,可以达成最低 20ms 的音频输出时延。

同时,为了简化应用的接入,通过在接口中提供不同的参数配置,使开发者可以用一套接口同时支持低时延和普通通路两种播放模式。

3.3 代码示例

可以通过 OH_AudioStreamXXX 接口来进行低时延通路的创建,通过传入不同参数可以设置低时延模式,亦可以设置普通模式,从而使用一套接口来适配不同场景。

同时,低时延模式一般采用来 pull 模式来获取数据,这里提供了一个 callback,需要应用创建并填入。

// 1.创建音频流构造器,设置参数OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_RENDERER);OH_AudioStreamBuilder_SetSamplingRate(builder, rate); // 其他参数设置…// 2.设置低延时模式和数据回调OH_AudioStreamBuilder_SetLatencyMode(builder, AUDIOSTREAM_LATENCY_MODE_FAST) ;OH_AudioStreamBuilder_SetRendererCallback(builder, callback, nullptr);// 3.构造播放的音频流并使用OH_AudioStreamBuilder_GenerateRenderer(builder, &audioRenderer);OH_AudioRenderer_Start(audioRenderer);•OH_AudioRenderer_Release(audioRenderer);

更多详细的代码参考:

https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/media/using-ohaudio-for-playback.md

四、播控能力

4.1 系统能力通过前面所说的焦点管理策略,系统解决了音视频应用并发播放的问题;对于播放中的应用的控制,系统也提供了规范支持。

系统提供了 C/S 模式的播控管理的框架,应用作为客户端,接入 AVSession 的会话端,设置必要的信息;系统的播控中心获取与之对应的会话控制器,获取信息进行展示,以及对应用发送控制命令。

通过标准接口的接入,规范了应用的播放行为;同时通过统一的播控中心的入口,使得用户对于播放的控制做到一键直达。

4.2 代码示例

import AVSessionManager from '@ohos.multimedia.avsession';// 开始创建并激活媒体会话// 创建sessionlet context: Context = getContext(this);async function createSession() {  let type: AVSessionManager.AVSessionType = 'audio';  let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type);  await session.activate();}async function setSessionInfo() {  // 播放器逻辑··· 引发媒体信息与播放状态的变更  // 设置必要的媒体信息  let metadata: AVSessionManager.AVMetadata = {    assetId: '0',    title: 'TITLE',    artist: 'ARTIST'  };  session.setAVMetadata(metadata).then(() => {  }).catch((err: BusinessError) => {  });  // 简单设置一个播放状态 - 暂停 未收藏  let playbackState: AVSessionManager.AVPlaybackState = {    state:AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE,    isFavorite:false  };  session.setAVPlaybackState(playbackState, (err) => {  });}async function setListenerForMesFromController() {  // 一般在监听器中会对播放器做相应逻辑处理  // 不要忘记处理完后需要通过set接口同步播放相关信息,参考上面的用例  session.on('play', () => {    // do some tasks ···  });  session.on('pause', () => {    // do some tasks ···  });}

更多详细的代码参考:

https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/media/avsession-overview.md

相关文章:

学习指南:如何快速上手媒体生态一致体验开发

过去开发者们在使用多媒体能力时,往往会遇到这样的问题,比如:为什么我开发的相机不如系统相机的效果好?为什么我的应用和其他的音乐一起发声了,我要怎么处理?以及我应该怎么做才能在系统的播控中心里可以看…...

037、目标检测-算法速览

之——常用算法速览 目录 之——常用算法速览 杂谈 正文 1.区域卷积神经网络 - R-CNN 2.单发多框检测SSD,single shot detection 3.yolo 杂谈 快速过一下目标检测的各类算法。 正文 1.区域卷积神经网络 - R-CNN region_based CNN,奠基性的工作。…...

【开发流程】持续集成、持续交付、持续部署

一、开发工作流程 假设把开发流程分为以下几个阶段: 编码 -> 构建 -> 集成 -> 测试 -> 交付 -> 部署 如上图所示,持续集成、持续交付、持续部署有着不同的软件自动交付周期。 二、持续集成、持续交付、持续部署 1、持续集成 持续集成…...

Linux——编译器gcc/g++、调试器gdb以及自动化构建工具makefilemake详解

编译器—gcc/g、调试器—gdb以及自动化构建工具—makefile&&make 文章目录 编译器—gcc/g、调试器—gdb以及自动化构建工具—makefile&&make1. 编译器——gcc/g1.1 生成可执行文件与修改默认可执行文件1.2 程序的翻译过程以及对应的gcc选项1.2.1 预处理 gcc -E…...

Android registerForActivityResults使用详解以及实现原理

registerForActivityResult 使用用途是监听Activity结果。 以下是使用样例 //需要传递Request用于解析Intent和解析上个Activity返回的结果 val launchdata = registerForActivityResult<PickVisualMediaRequest, Uri?>(ActivityResultContracts.PickVisualMedia()) {…...

模拟实现一个Linux中的简单版shell

exec系列接口中的环境变量 在之前我们学习了exec系类函数的功能就是将一个程序替换成另外一个程序。 然后就会出现下面的问题&#xff1a; 首先父进程对应的环境变量的信息是从bash中来的&#xff0c;因为我们自己写的父进程在运行的时候首先就要成为bash的子进程。这里我们将…...

扩散模型实战(十):Stable Diffusion文本条件生成图像大模型

推荐阅读列表&#xff1a; 扩散模型实战&#xff08;一&#xff09;&#xff1a;基本原理介绍 扩散模型实战&#xff08;二&#xff09;&#xff1a;扩散模型的发展 扩散模型实战&#xff08;三&#xff09;&#xff1a;扩散模型的应用 扩散模型实战&#xff08;四&#xff…...

LaTex编写伪代码,并实现根据所在章编号(连字符),例如算法1-1

1 首先导入包&#xff1a; 按需要添加或者删除option&#xff0c;但是algochapter是必须的。 \usepackage[linesnumbered,ruled,algochapter]{algorithm2e}各个option的作用如下&#xff1a; 您好&#xff0c;这是Bing。我可以帮您解释algorithm2e包中这几个option的意思。&a…...

vue.js javascript js判断是值否为空

检查一个对象&#xff08;Object&#xff09;是否为空&#xff0c;即不包含任何元素。Javascript 中的对象就是一个字典&#xff0c;其中包含了一系列的键值对&#xff08;Key Value Pair&#xff09;。检查一个对象是否为空&#xff0c;等价于检查对象中有没有键值对。 1、如…...

网页开发如何实现简易页面跳动/跳转,html课堂练习/作业,页面ABC的相互跳转

先建一个文件夹&#xff0c;文件夹包含三个文件夹&#xff0c;三个文件夹分别包含各自的代码。(可以只建一个文件夹&#xff0c;文件夹包含各页面代码) 页面1的代码&#xff1a; <head> <meta http-equiv"Content-Type" content"text/html; charsetu…...

某大型房地产公司绩效面谈项目成功案例纪实

——开展有效的绩效面谈&#xff0c;促进和完善管理工作 【客户行业】房地产行业&#xff1b;国有企业 【问题类型】绩效面谈改进 【客户背景】 某大型房地产公司是某国企集团的省级分公司&#xff0c;集团公司现拥有北京、上海、广州、山东等8大区域公司&#xff0c;现有员…...

BGP联盟和团体属性实验

目录 一、实验拓扑 二、实验要求 三、实验步骤 1、IP地址配置 2、ospf配置 3、BGP建邻 4、宣告网段 5、配置团体属性 一、实验拓扑 二、实验要求 1、按照图示配 IP 地址&#xff0c;R2&#xff0c;R3&#xff0c;R4&#xff0c;R5分别配 Loopbacke 口地址作为OSPF的Ro…...

代码随想录-刷题第二天

977. 有序数组的平方 题目链接&#xff1a;977. 有序数组的平方 思路&#xff1a;双指针思想&#xff0c;数组是有序的且含有负数&#xff0c;其中元素的平方一定是两边最大。定义两个指针&#xff0c;从两端开始向中间靠近&#xff0c;每次比较两个指针的元素平方大小&#…...

DAY59 503.下一个更大元素II + 42. 接雨水

503.下一个更大元素II 题目要求&#xff1a; 给定一个循环数组&#xff08;最后一个元素的下一个元素是数组的第一个元素&#xff09;&#xff0c;输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数&am…...

【如何将任何直流电机变成伺服电机】

【如何将任何直流电机变成伺服电机】 1 前沿2 伺服电机工作原理3 如何制作定制伺服电机4 AS5600 编码器 – 磁性旋转位置传感器5 定制伺服电机电路图6 PCB设计7 自定义伺服3D模型8 定制伺服齿轮箱的 3D 打印零件9 对控制器进行编程9.1 引导加载程序刻录9.2 代码上传9.3 源代码9…...

单片机语音芯片在工业控制中的应用优势

单片机语音芯片&#xff0c;这一智能化的代表产品&#xff0c;不仅在家庭和消费电子领域发挥着重要的作用&#xff0c;更为工业控制领域注入了新的活力。将单片机语音芯片与语音交互技术相结合&#xff0c;为工业设备的控制和监测提供了前所未有的解决方案。 首先&#xff0c;…...

【开源】基于Vue.js的高校实验室管理系统的设计和实现

项目编号&#xff1a; S 015 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S015&#xff0c;文末获取源码。} 项目编号&#xff1a;S015&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实…...

Xrdp+内网穿透实现远程访问Linux Kali桌面

XrdpCpolar实现远程访问Linux Kali桌面 文章目录 XrdpCpolar实现远程访问Linux Kali桌面前言1. Kali 安装Xrdp2. 本地远程Kali桌面3. Kali 安装Cpolar 内网穿透4. 配置公网远程地址5. 公网远程Kali桌面连接6. 固定连接公网地址7. 固定地址连接测试 前言 Kali远程桌面的好处在于…...

【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

Eclipse切换中文环境

PACK包链接 地址&#xff0c;进入后可以看到不同版本的包。 要选择跟自己Eclipse版本一致的包&#xff0c;比如我的Eclipse启动界面如下&#xff0c;我就要找Helios的包&#xff08; Juno、Indigo、Helios、Kepler这些具体怎么划分的我也不清楚&#xff09;。 在线安装 打…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...