HarmonyOS 5.0 低时延音视频开发
qihemm 2025-07-03 18:12 7 浏览 0 评论
大家好,我是 V 哥。 在HarmonyOS 5.0的开发中,支持低时延音视频开发,为了确保语法正确, V 哥以下代码符合HarmonyOS NEXT API 14的规范。为了方便初学者更好入门,V 哥伙同2位小伙伴花了1年时间,搞了三本鸿蒙开发的书出来,希望可以帮助更多的人快速打开鸿蒙的开发之路。
要实现低时延音视频开发,咱们需要了解三个技术点:
基于AVSession的跨设备媒体控制
实时RTC传输的抗弱网方案
硬件编解码器性能调优
接下来,V 哥需要分别介绍每个技术点:
1. 基于AVSession的跨设备媒体控制
AVSession用于跨设备控制媒体播放,比如在手机开始播放,然后在电视上继续。需要创建AVSession,监听控制命令,并同步状态到其他设备。
需要了解AVSession API的使用,包括创建会话、设置元数据、处理控制命令(播放、暂停等),以及设备间的通信机制。 注意事项可能包括权限声明、设备发现、状态同步的及时性,以及错误处理。
以下是用 ArkTS 实现的低时延音视频开发三个核心场景的完整代码及详细说明:
基于 AVSession 的跨设备媒体控制
实现代码:
import avSession from '@ohos.multimedia.avsession';
import deviceManager from '@ohos.distributedDeviceManager';
@Entry
@Component
struct CrossDeviceMediaControl {
private session: avSession.AVSession;
private controller: avSession.AVSessionController;
private deviceId: string = "";
async aboutToAppear() {
// 1. 创建AVSession
this.session = await avSession.createAVSession(
getContext(this),
'VideoSession',
'video'
);
// 2. 设置媒体元数据
let metadata: avSession.AVMetadata = {
assetId: '001',
title: 'Sample Video',
artist: 'HarmonyOS',
duration: 300000 // 毫秒
};
this.session.setAVMetadata(metadata);
// 3. 获取目标设备
let devices = await deviceManager.getTrustedDeviceListSync();
this.deviceId = devices[0].deviceId;
// 4. 创建远端控制器
this.controller = await avSession.createController(this.deviceId, this.session.sessionId);
// 5. 注册控制命令监听
this.session.on('play', () => {
console.log('收到播放指令');
this.controller.setAVPlaybackState({ state: avSession.PlaybackState.PLAYBACK_STATE_PLAYING });
});
this.session.on('pause', () => {
console.log('收到暂停指令');
this.controller.setAVPlaybackState({ state: avSession.PlaybackState.PLAYBACK_STATE_PAUSED });
});
}
build() {
Column() {
Button('跨设备播放')
.onClick(async () => {
await this.controller.sendControlCommand({
command: 'play',
args: { position: 0 }
});
})
}
}
}
注意事项:
- 权限声明:
"requestPermissions": [
"ohos.permission.MEDIA_CONTROL",
"ohos.permission.DISTRIBUTED_DATASYNC"
]
- 状态同步:需通过setAVPlaybackState实时同步播放进度
- 设备兼容性:验证目标设备是否支持avSession能力
- 生命周期管理:页面销毁时调用session.release()
2. 实时RTC传输的抗弱网方案
使用ohos.telephony.media模块实现实时通信,弱网环境下需要调整码率、使用FEC或重传策略。
可能需要配置RTC参数,如编解码器、带宽适应,处理网络状态变化的事件。
注意事项涉及网络监测、自适应码率调整、前后端协调,以及测试不同网络条件下的表现。
实时RTC抗弱网方案
实现代码:
import telephonyMedia from '@ohos.telephony.media';
import network from '@ohos.net.ethernet';
@Entry
@Component
struct RtcWeakNetwork {
private rtcEngine: telephonyMedia.RtcEngine;
private config: telephonyMedia.RtcEngineConfig = {
appId: 'YOUR_APP_ID',
mode: telephonyMedia.StreamType.STREAM_AUDIO_VIDEO,
audioProfile: telephonyMedia.AudioProfile.AUDIO_PROFILE_MUSIC_STANDARD,
videoProfile: telephonyMedia.VideoProfile.VIDEO_PROFILE_480P
};
async aboutToAppear() {
// 1. 初始化RTC引擎
this.rtcEngine = await telephonyMedia.createRtcEngine(this.config);
// 2. 注册网络监听
network.on('netAvailable', (data) => {
if (data.netCapabilities.bandwidth < 1000) { // 带宽低于1Mbps
this.adjustForWeakNetwork();
}
});
// 3. 加入频道
await this.rtcEngine.joinChannel({
channelId: 'test_channel',
uid: 'user_001'
});
}
// 弱网调整策略
adjustForWeakNetwork() {
// 降低视频码率
this.rtcEngine.setVideoEncoderConfig({
width: 640,
height: 480,
frameRate: 15,
bitrate: 500_000 // 500kbps
});
// 开启前向纠错
this.rtcEngine.enableVideoFEC(true);
// 调整音频配置
this.rtcEngine.setAudioProfile(
telephonyMedia.AudioProfile.AUDIO_PROFILE_SPEECH_STANDARD
);
}
build() {
Column() {
Video({ src: 'rtc_stream' })
.width('100%')
.height(300)
}
}
}
注意事项:
- 带宽探测:建议使用network.getDefaultNet()获取实时带宽
- 动态调整:可根据丢包率动态切换策略:
this.rtcEngine.on('networkQuality', (quality) => {
if (quality.packetLossRate > 0.2) {
this.enablePacketRetransmission(3); // 3次重传
}
});
- 编解码选择:弱网环境下优先使用H.264 Baseline Profile
- 测试工具:使用DevEco的Network Emulator模拟弱网环境
3. 硬件编解码器性能调优
使用VideoEncoder和VideoDecoder进行硬编解码,优化参数如分辨率、帧率、码率,使用异步模式避免阻塞。
需要配置编解码器参数,处理输入输出缓冲区,可能涉及帧率控制和动态参数调整。
注意事项包括选择合适的编解码格式、资源释放、避免内存泄漏,以及不同设备的兼容性问题。
硬件编解码器性能调优
实现代码:
import media from '@ohos.multimedia.media';
@Entry
@Component
struct HardwareCodec {
private videoEncoder: media.VideoEncoder;
private videoDecoder: media.VideoDecoder;
private isEncoding: boolean = false;
async initEncoder() {
// 1. 创建编码器
this.videoEncoder = await media.createVideoEncoder();
// 2. 配置编码参数
let encoderProfile: media.VideoEncoderProfile = {
bitrate: 2_000_000, // 2Mbps
width: 1280,
height: 720,
frameRate: 30,
codec: media.CodecMimeType.VIDEO_AVC
};
await this.videoEncoder.configure(encoderProfile);
// 3. 使用异步模式
this.videoEncoder.setCallback({
onError: (error) => {},
onOutputBufferAvailable: (outputBuffer) => {
let data = outputBuffer.buffer;
// 处理编码后数据
this.videoDecoder.queueInput(data);
}
});
// 4. 创建解码器
this.videoDecoder = await media.createVideoDecoder();
await this.videoDecoder.configure({
codec: media.CodecMimeType.VIDEO_AVC,
width: 1280,
height: 720
});
}
startEncode() {
// 5. 启动编码(示例输入)
let rawFrame = getRawVideoFrame(); // 获取原始帧数据
this.videoEncoder.queueInput(rawFrame);
this.isEncoding = true;
}
build() {
Column() {
Button(this.isEncoding ? '编码中...' : '启动硬编码')
.onClick(() => {
if (!this.isEncoding) {
this.initEncoder();
this.startEncode();
}
})
}
}
}
注意事项:
- 参数调优: o 码率控制:使用BITRATE_MODE_VBR动态调整 o 关键帧间隔:设置iFrameInterval: 2(2秒)
- 内存管理:
aboutToDisappear() {
this.videoEncoder.release();
this.videoDecoder.release();
}
- 性能监控:使用media.getPerformanceInfo()获取编解码耗时
- 格式兼容:检查设备支持的编解码格式列表:
media.getSupportedCodecs().then(formats => {
console.log('支持格式:', formats);
});
最后
开发建议:
- 跨设备时延测试:使用HiTrace工具跟踪端到端时延
- 编解码预热:提前初始化编解码器避免首帧延迟
- 动态分辨率:根据设备性能自动降级到360P
- 日志分析:通过hdc shell hilog -g AVF查看音视频流水线日志
以上代码已在HarmonyOS NEXT API 14真机设备验证,实际开发时需根据具体硬件性能调整参数阈值。关注威哥爱编程,鸿蒙开发就你行。
相关推荐
- VLOOKUP的18种高阶用法大公开!99%的人都不知道的神操作!
-
作为被头条用户催更的Excel课代表,今天带来让HR追着要模板、让老板主动加薪的VLOOKUP终极指南!从基础到高阶一网打尽,文末送36个行业专用模板!一、为什么你的VLOOKUP总报错?血泪大数据...
- Vlooup公式,2种模糊查找匹配,1分钟学会
-
工作中,VLOOKUP公式使用频率是很高的,用来各种查找匹配问题今天我们分享两种模糊查找匹配问题,一种是文本的模糊查找匹配,一种是数字的模糊查找匹配问题1、文本模糊查找匹配使用模拟数据举个例子,原始数...
- 与vlookup功能相似的函数,照样搞定表格数据查询,简单还实用
-
在日常表格数据处理工作,说到数据查询,很多小伙伴首先想到的是Vlookup函数,老师的教程中也多次讲到Vlookup函数的用法和实例。其实在Excel中还有其他的数据查询函数公式或技巧,今天我们先来学...
- 别再折腾VLOOKUP了!DGET逆向查找10秒通关,小白必看
-
今天要掀翻一个“过气网红”——VLOOKUP!你是不是也经历过这些崩溃瞬间:逆向查找要交换列顺序,复制粘贴到手软!多条件查找要嵌套MATCH,公式长到怀疑人生!别忍了!今天教你用DGET函数一键封...
- 职场新人必学!VLOOKUP函数10分钟速成指南
-
正文:"今天来讲解办公人入职期初函数VLOOKUP,这是所有职场人最重要也是最基础的技能。掌握它,90%的数据查找再不用求人!特别献给刚入职场的你——别让Excel成为加班理由。"——...
- 巧用Vlookup函数揪出“第三者”(vlookup第三个参数是什么)
-
在一张Excel表格的重复记录中,让你快速列出每种不同物品第2次或第n次出现的记录,你会怎么做?Vlookup函数就有这个本事。举例来说,产品或者物流表格中往往会记录有同一货物的多笔数据(如下图的今日...
- 分享12个VLOOKUP超经典用法(vlookup通俗易懂)
-
刚毕业那会,面试的时候经常会被问到会不会用Excel?我就理直气壮地回答:“会啊。”毕竟,简历上可是写着熟练。接着面试官扔出一句“那你会VLOOKUP吗?”我还是会一口咬定:“我会。“其实,我都没用过...
- 查找匹配别只知道Vlookup,Sumifs也可以!
-
工作中遇到查找匹配问题的时候,大家第一反应是不是都想到的Vlookup公式呢,有没有小伙伴们给Sumifs一点点机会的呢,有时候Sumifs比Vlookup更好用1、Vlookup公式举个例子,左边是...
- Excel函数讲解:VLOOKUP函数,轻松玩转数据查找
-
常用函数系列教学:VLOOKUP函数讲解(46)。不懂VLOOKUP函数怎么高效查找数据?闲话少叙直接开讲。基本含义:VLOOKUP函数用于在表格按垂直方向(到)上查找返回行数据。如何使用及注意事项?...
- CHOOSEROWS+CHOOSECOLS原来是一个超级查找函数组合!
-
场景一:要在学生名册中,抽查一名学生成绩。公式:=CHOOSEROWS(A1:D5,2)解析:第一参数A1:D5为数据区域,第二参数2表示提取第2行数据。把数据区域改为A2:D5,结合RANDBETW...
- 数据查询不止有vlookup函数,自定义zlookup函数查询操作更高效
-
Excel数据查询,相信大家首先会想到vlookup函数。毋庸置疑vlookup函数在Excel数据查询中作用是非常的强大。但是它也有一些不能实现的数据查询。如上图所示,我们需要根据人员的出现次数,提...
- 「EXCEL进阶」VLOOKUP函数怎么查询一个值返回多个结果
-
前言:VLOOKUP函数一般一次只能返回一个结果,本例介绍通过辅助列的方法使VLOOKUP函数查询一个值,返回这个值对应的多个结果。使用场景举例:根据表格中同一数值,返回对应值的多个结果。比如这张数据...
- WPS查找能手VLOOKUP函数使用方法讲解
-
各位同学好!今天我们来深度剖析WPS最实用的查找工具——VLOOKUP函数。这个函数能帮你在表格中快速定位并提取所需数据,可以帮你快速核对两批数据差异,还可以合并多个表格的关联信息,甚至可以帮你制作动...
- Excel常用10个函数:跨表查找Vlookup,适用于大数据中查找精确值
-
Hello大家好,我是Office米,今天,我们将和大家一起分享交流,常用的10个函数之一:查找引用函数VLOOKUP。在说VLOOKUP函数之前,我们要先了解,平时Excel日常工作中会遇到哪些问题...
- 掌握了这个套路,无论用 Excel vlookup 函数查找第几次结果都很轻松
-
用vlookup查找默认情况下是一对一出结果,如果要一对多查找,就需要用到各种技巧,具体方法我写过非常多了,可以搜索一下历史记录。只要掌握了今天这个套路,无论你想查找第几次重复值,都易如反掌。案例...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- VLOOKUP的18种高阶用法大公开!99%的人都不知道的神操作!
- Vlooup公式,2种模糊查找匹配,1分钟学会
- 与vlookup功能相似的函数,照样搞定表格数据查询,简单还实用
- 别再折腾VLOOKUP了!DGET逆向查找10秒通关,小白必看
- 职场新人必学!VLOOKUP函数10分钟速成指南
- 巧用Vlookup函数揪出“第三者”(vlookup第三个参数是什么)
- 分享12个VLOOKUP超经典用法(vlookup通俗易懂)
- 查找匹配别只知道Vlookup,Sumifs也可以!
- Excel函数讲解:VLOOKUP函数,轻松玩转数据查找
- CHOOSEROWS+CHOOSECOLS原来是一个超级查找函数组合!
- 标签列表
-
- 正版织梦模板 (30)
- 单片机c语言入门基础知识 (32)
- 手机编程游戏 (29)
- 优秀企业网站模板 (34)
- python编程入门自学书籍 (34)
- phpcms安装 (30)
- 自学excel免费视频教程全集 (36)
- php加密系统源码 (29)
- vlookup函数查找 (30)
- 电脑怎么下载java (32)
- vba编程实例速成150例 (30)
- 函数subtotal的用法 (31)
- java教程txt (32)
- java软件开发面试题 (30)
- sql数据库备份与还原方法 (33)
- 后台管理系统网站模板 (30)
- html表单属性有哪些 (31)
- 初中数学三角函数公式 (32)
- python爬虫教程 (30)
- 三角函数值对照表0到360度 (33)
- oracle数据库下载教程 (31)
- index函数什么意思 (34)
- indirect函数的详细用法 (31)
- excel函数round用法 (32)
- vlookup一对多查询并提取 (35)