学习指南:如何快速上手媒体生态一致体验开发
过去开发者们在使用多媒体能力时,往往会遇到这样的问题,比如:为什么我开发的相机不如系统相机的效果好?为什么我的应用和其他的音乐一起发声了,我要怎么处理?以及我应该怎么做才能在系统的播控中心里可以看到呢?对于开发者的这些疑问,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系类函数的功能就是将一个程序替换成另外一个程序。 然后就会出现下面的问题: 首先父进程对应的环境变量的信息是从bash中来的,因为我们自己写的父进程在运行的时候首先就要成为bash的子进程。这里我们将…...
扩散模型实战(十):Stable Diffusion文本条件生成图像大模型
推荐阅读列表: 扩散模型实战(一):基本原理介绍 扩散模型实战(二):扩散模型的发展 扩散模型实战(三):扩散模型的应用 扩散模型实战(四ÿ…...
LaTex编写伪代码,并实现根据所在章编号(连字符),例如算法1-1
1 首先导入包: 按需要添加或者删除option,但是algochapter是必须的。 \usepackage[linesnumbered,ruled,algochapter]{algorithm2e}各个option的作用如下: 您好,这是Bing。我可以帮您解释algorithm2e包中这几个option的意思。&a…...
vue.js javascript js判断是值否为空
检查一个对象(Object)是否为空,即不包含任何元素。Javascript 中的对象就是一个字典,其中包含了一系列的键值对(Key Value Pair)。检查一个对象是否为空,等价于检查对象中有没有键值对。 1、如…...
网页开发如何实现简易页面跳动/跳转,html课堂练习/作业,页面ABC的相互跳转
先建一个文件夹,文件夹包含三个文件夹,三个文件夹分别包含各自的代码。(可以只建一个文件夹,文件夹包含各页面代码) 页面1的代码: <head> <meta http-equiv"Content-Type" content"text/html; charsetu…...
某大型房地产公司绩效面谈项目成功案例纪实
——开展有效的绩效面谈,促进和完善管理工作 【客户行业】房地产行业;国有企业 【问题类型】绩效面谈改进 【客户背景】 某大型房地产公司是某国企集团的省级分公司,集团公司现拥有北京、上海、广州、山东等8大区域公司,现有员…...
BGP联盟和团体属性实验
目录 一、实验拓扑 二、实验要求 三、实验步骤 1、IP地址配置 2、ospf配置 3、BGP建邻 4、宣告网段 5、配置团体属性 一、实验拓扑 二、实验要求 1、按照图示配 IP 地址,R2,R3,R4,R5分别配 Loopbacke 口地址作为OSPF的Ro…...
代码随想录-刷题第二天
977. 有序数组的平方 题目链接:977. 有序数组的平方 思路:双指针思想,数组是有序的且含有负数,其中元素的平方一定是两边最大。定义两个指针,从两端开始向中间靠近,每次比较两个指针的元素平方大小&#…...
DAY59 503.下一个更大元素II + 42. 接雨水
503.下一个更大元素II 题目要求: 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数&am…...
【如何将任何直流电机变成伺服电机】
【如何将任何直流电机变成伺服电机】 1 前沿2 伺服电机工作原理3 如何制作定制伺服电机4 AS5600 编码器 – 磁性旋转位置传感器5 定制伺服电机电路图6 PCB设计7 自定义伺服3D模型8 定制伺服齿轮箱的 3D 打印零件9 对控制器进行编程9.1 引导加载程序刻录9.2 代码上传9.3 源代码9…...
单片机语音芯片在工业控制中的应用优势
单片机语音芯片,这一智能化的代表产品,不仅在家庭和消费电子领域发挥着重要的作用,更为工业控制领域注入了新的活力。将单片机语音芯片与语音交互技术相结合,为工业设备的控制和监测提供了前所未有的解决方案。 首先,…...
【开源】基于Vue.js的高校实验室管理系统的设计和实现
项目编号: S 015 ,文末获取源码。 \color{red}{项目编号:S015,文末获取源码。} 项目编号:S015,文末获取源码。 目录 一、摘要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分支结构】
👨💻博客主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】🌏题目描述🌏输入格…...
Eclipse切换中文环境
PACK包链接 地址,进入后可以看到不同版本的包。 要选择跟自己Eclipse版本一致的包,比如我的Eclipse启动界面如下,我就要找Helios的包( Juno、Indigo、Helios、Kepler这些具体怎么划分的我也不清楚)。 在线安装 打…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
