音视频技术在手机上的应用与挑战

  //  

编者按:随着手机相机功能日益强大,4k,8k,各类特色短视频的拍摄,编辑、播放需求日益增长,短视频应用的火爆也对当前的手机音视频技术提出了更高的要求,如何更好地提高用户体验成为了行业共同的命题。LiveVideoStackCon 2023 上海站邀请了小米的吴昊,从一名开发者的角度为大家分享他关于手机端音视频技术的一些思考与经验。

文/吴昊

整理/LiveVideoStack

大家好,本次我将从手机厂商音视频SDK开发的角度和大家分享工作中我总结的一些经验,也虚心接收更好的建议。

1c7c40462e9968eca90b27b9aa93c735.png

目前我们的主要工作是开发小米内部自用的多媒体组件,它支持小米天气、相册、文管、短信、视频的业务领域涉及的本地播放、网络播放、音乐播放、图片浏览、视频编辑和新场景探索等功能。

b9185acf9491c47eced32e438b96c8b9.png

本次分享将分为五部分:一是从厂商角度介绍对手机音视频现状的理解;二是分享对平衡体验和资源占用的一些工作经验;三是基于网络播放场景列举具体的优化实例;四是介绍我日常使用的开源资源;最后进行一些未来展望。

-01-

手机音视频现状

01c44ce6a70d59e89e845d027a616d25.png

提起手机音视频,大家的第一印象可能是上面列举的抖音、快手、爱奇艺和小米视频等在线视频平台,其中我们的小米视频是一个聚合平台,用户可以通过它观看各大流媒体平台的视频资源。

f85245eea12cf3fbb3de6f56de701e8d.png

而手机厂商在此基础上还需重点关注本地视频播放应用的开发和优化。如上图所示,我们对小米手机的相册应用丰富了各种各样的功能,如视频变速播放、编辑、图片Seekbar浏览等。

此外,近年来各大厂商对手机影像的内卷之势也愈演愈烈,为了充分发挥硬件实力也在不断加强相机应用的各种功能。

80586f4ebdf8ebeef21e66d2de654d5c.png

我个人认为,当前的手机音视频应用具备以上几个特点:第一是便携性,这有助于提高用户粘度;第二是多功能性,除了单纯的播放功能外还要具备各种剪辑编辑相关的能力;第三是高清晰度,这是当今用户的基本需求;第四是实时性,保证用户可以随时随地使用;社交性和互动性可以为微信等社交应用提供服务。

-02-

性能与体验

5682cb6aa801f63726b668e871a7bc9d.png

接下来分享我个人对平衡体验和资源占用的一些优化经验。在此之前首先向大家推荐小米公司的官方应用小米社区。我们的产品经理和研发会不时参与社区讨论,并从社区话题中选取大家感兴趣的新功能进行立项研发,欢迎小米用户们积极发表自己的想法和建议。

2d1d780c82c58143fd1978b3bb9e06fc.png

依据自网络和小米社区的调研结论,我们发现对于音视频应用。用户主要关注以上几点特性:一是满足用户的画质需求;二是需要支持各种不同的视频格式;三是除播放外应具备更多的功能(如视频编辑等);四是要保证播放的流畅度;五是要提高应用稳定性;六是要尽可能节约设备电量。

b10ab9f07ebdc5f757ffbb5a295e1d2d.png

通过分析提炼用户需求,我们在技术上将其转换为具体的优化方案。

3935614c70000082b85d20e118013cc5.png

我们认为可以从以上六个方面来展开优化。

86be3be5a75237c1a0b48bb0997bbb94.png

首先,控制包体积有效缩短了APK的下载时间,使用户可以更快地安装应用程序;其次是有利于节约手机设备的存储空间;第三是更小的APK启动速度更快,应用程序响应更迅速,提高了用户体验;最后,压缩APK体积减轻了传输时占用的网络带宽,节约了厂商的网络和存储成本。

3bb1b98a463068e96202bfdae9c17e3e.png

以上是我总结的几项优化方案:一是精简动态库符号表;二是去除无用代码,依据场景需求优化调用逻辑,减少代码调用层级;三是对FFmpeg进行定制化编译。

388e137f2696f647624353d61639db81.png

内存占用优化一是可以有效控制因应用占用内存大,内存堆积溢出导致的OOM,或是容易被系统清理的问题;二是减少频繁GarbageCollection (GC)导致的应用卡顿、掉帧现象;三是从手机厂商角度需尽量避免原生应用内存占用大,变相挤压第三方应用运行环境。

91c373edbc5f8d6a6cc54699dac0f142.png

针对安卓平台,首先可以使用Android studio、dumpsys或meminfo等工具对应用进行内存占用分析,明确大内存分配的代码并评估必要性,为后续优化提供决策依据;

二是减少频繁内存创建销毁,借助jemalloc等内存分配器,可以实现对一些重复对象的复用;

三是减少数据的拷贝流转。

bb1e1cd070d8437abd1e813c627f5ffb.png

作为手机厂商,应用功耗是我们高度关注的一项指标,控制功耗首先有利于减少手机的充电次数,延长电池寿命;其次可以减少手机发热,降低硬件损耗;三是发热更少可以避免手机CPU频繁降频,有利于提高设备的整体性能和相应速度。

c5e919bee28ce07bf5aaed4781e37940.png

控制功耗首先可以在不影响应用运行的前提下尽量降低网络访问频率;第二要充分考虑VPU、CPU和GPU的特性,合理分配硬件资源;第三要做好无用线程的排查;第四是可以依据实际情况将显示模式切换为surfaceview。

c595ba0cbdb410d73dc905a8cdca2000.png

从优化SDK网络播放的角度,提升流畅性可以采取以下措施:

一是做好视频文件的数据调整,如注意mp4文件moov box的排列顺序等;

二是可以采用数据预缓存;三是采用视频预渲染;四是优先考虑硬解。

4e781639b53a22a333a0d120f7a3b842.png

提升应用稳定性首先可以在平时的工作中保证随时自动化测试的条件,提高效率;二是要重视预防和监控,可以成立一些代码评审监控机制;三是针对发现的问题要做好举一反三。

1a782c5f0f2ec115e832a9b7d6a73c01.png

丰富应用的特色功能是维持用户粘度的关键。做好这点首先要注意多和业务相关的各方交流讨论,广开思路;二是要及时关注其他平台的特色功能,并考虑手机应用场景及实现技术,研究移植的可行性;三是从自身角度努力提升技术实力,多关注新兴技术,与时俱进。

-03-

场景案例

0ebed5394afeb8b165f280d0129a5b62.png

接下来介绍一个基于网络播放场景的优化案例。在该案例中,业务方对网络播放的起播速度提出了更高要求。

由于向业务方最初提供的SDK集成了在线、本地视频播放和视频编辑等功能,本身体积过重,优化空间有限,因而我们决定基于纯网络播放推出专门的播放器内核,提高起播速度。

15fdf7dd205143448d372b8cfd609ee4.png

各位开发者在规划优化方案前要注意做好调研,与产品方做好沟通,明确具体优化需求,本次该案例从业务方角度提出的需求包括起播速度快、SDK体积小、快速切换和内存小四项。

从开发者角度,为了便于后续成果复用,响应用户可能提出的额外需求,有必要对SDK接口的简单化和可拓展性做出考虑。

df282d9c35f5265dd90dd12c0ff767b9.png

基于以上需求我们进行了架构选型调研。综合考虑开发时间,适配难度,后期维护以及成果复用的最大化,最终决定基于原有播放器框架进行精简及模块化,并就稳定性及起播耗时等核心指标进行专项开发。

54213e31c7d3c85cfaad9af62f5f407a.png

我们从以上几方面着手压缩SDK体积。首先是分离原播放器中与网络播放场景无关的功能;其次是有针对性的选取满足用户需求的网络协议、封装格式和编码格式;最后是针对网络播放场景简化原有判断逻辑。

0a955cd52e3323a875b548480dc723f8.png

播放器架构优化前后的对比如上所示。

600036a80b7886969c306dcb7facae70.png

在该案例基础上,我们正在考虑将原有体积重,集成各种功能的播放器SDK解耦为功能池,后续依据不同用户的场景需求进行针对性的架构定制。

970402e71a0fadf3958c3c97c81ba4ab.png

对优化内存占用我们采取了以上措施:一是通过内存分析找到高占用的代码,进行针对性优化;二是进行缓存区优化,如自定义内存管理、进行缓存区调优等;三是针对Android平台采用MediaCodec直接送显;最后是将显示模式切换为surfaceview。

a850d70a9f8465f7ddb54e986a330d32.png

在该案例中,缩短起播时间是业务方的核心需求。我们对不同起播时间给用户带来的感受进行了分析,结论如上表所示。

视频起播从SDK开始到显示播放需经历以上五个阶段,我们在各个阶段采用了一些相对简单的优化策略。

82fbbe79af42ee3d7abb44a50a4ddbeb.png

首先在申请url地址阶段,可以在部分场景下提前获取视频url;在DNS解析阶段,可以酌情考虑采用host缓存,缩短解析时间;在连接服务器阶段,可以考虑进行服务端调优;在数据缓存阶段,可以提前缓存部分数据;在解码显示阶段可以选用支持快速解码的解码器。

4acb7462df969b24d2ba7850a138c09c.png

针对手机侧优化我们采用了以上方案。

4c8f6af540b21da7d2112fbb9b994a31.png

经过测试,我们在该案例中选择预缓存待播视频的开头1到2秒,大家在实际工作中可以结合场景需求自行调整需要缓存的时长。

8917a09f4ad0add37de639c636998228.png

通过复用提前缓存时分配的缓冲区buffer,可以有效降低起播缓存区的水位线,提高抗网络抖动能力。

3e388e1602b42530f0c426edf1198566.png

针对快速切换播放多个视频的场景可以采用播放器多实例方案。在前一个视频播放时,提前创建另一个播放器加载下一个视频,后续以此类推。

4308d46a7f3abdb183bef19c402b7afe.png

鉴于精确seek受网络条件影响可能会拖慢画面送显,我们会基于用户主观体验设置时间阈值(该案例下为900ms),如果精确seek所需时间超出该值则先送显该时点下能够解码的画面,避免长时间黑屏等待。

0a234829d09c9bb7b8925c6c982fdecc.png

换个角度考虑,针对相同问题,从资源侧进行优化有时效果要胜于SDK侧方案。

d29fb94580f94fa28b492b0d47c5461b.png

在验证优化可行性时,我使用apache2搭设了自有服务器辅助测试,其中上图右侧展示了设置网速限制的过程。

ba2a8f43eb77f8f8c7f662976c313c29.png

我发现在预缓存请求网络MP4时,会出现MP4文件头和文件尾来回请求的情况,这增加了播放耗时。

216e52110d853b5950526765d91e3488.png

这实际上是包含视频索引信息的moov在MP4文件中后置导致的。

在使用FFmpeg将其改为前置后,缓存机制可正常生效,短视频起播明显加快。

1b241fe5203030e6a9b91bd51a9a92de.png

调整moov位置后的MP4文件box tree如上图所示。

be99a576797f50d7574a490d0d51f682.png

moov会随着视频时长的增加而变大,例如上图中两小时左右的视频moov体量达到了约4MB。由于播放前需全部下载,导致起播速度仍然较慢。

9c6f402b60b747dc9a802625879d3d1f.png

为了缩短长视频起播时间,我考虑将mp4改为ts流,使播放器可以从视频流的任一片段独立解码,但导致seek的速度较慢。

通过改为使用HLS流,使起播和seek速度都获得了大幅提升。

cceb95e1c1e75331061732e36e1c51cc.png

综上,代码优化需要我们明确需求、逐项拆解从而精准施策。

同时要注意与各方形成合力,从多角度进行分析,还要考虑代码的模块化。

-04-

开源资源

785c960ee6e03f06642fb655886d4a16.png

接下来介绍几个我日常较多使用的音视频开源软件。

bb3ea97708d06898c9b863c677d279c1.png

Mp4box是一个可以在线解析、查看MP4 box结构的工具。

cde6401555ebf352a4db6714a064f1c4.png

Bento4是一款用于读写MP4文件的专业开源库。

0f567e2065a8bbb1bf233e706ebf5baf.png

YUView是我个人强烈推荐的一款码流分析软件,它支持带封装视频解析和显示、支持H.264/H.265/H.266/AV1裸码流解析和显示。

7dbbf95620f46d3ded2abf238cab95a0.png

它支持查看H.265流的详细码流分析信息,包括Slice个数、CU划分、CU模式类别、参考帧索引、运动矢量等等。

0246ea66bdeadde3f2935bb1c8b7e15b.png

它支持对比两段视频。

78b725069ede914d3a3e89c24a4f75a7.png

它支持类似mediainfo的媒体信息显示。

80b41cb5161b14f1aeb8b65089fdee54.png

它支持各种媒体编码信息查询。

f77089a70448bcc29526f8725586d8a2.png

它支持查看码流变化曲线。

d871d5e2c7bb687e8fff1bd0ab807332.png

biTStream由一系列C语言的头文件组成,它是在MIT许可证下发布的,可以辅助进行代码字节和结构解析。

-05-

未来展望

2b6b21078a39cfaf0cff9302d71878fa.png

最后从个人角度分享一些未来展望。一是随着AR/VR技术的不断发展,未来音视频可能会更加注重增强现实和虚拟现实的体验;二是5G技术的到来会加快音视频的传输速度,为应用创新带来更多可能性;三是AI技术的发展将为音视频应用带来更多可能。

我今天的分享就到这里,谢谢大家!


7天倒计时!深圳站大会亮点前瞻!

8c8ebe6459fd1f59aba0c5087cca33ff.png

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

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

相关文章

蓝桥杯 大小写转换

islower/isupper函数 islower和issupper是C标准库中的字符分类函数&#xff0c;用于检查一个字符是否为小写字母或大写字母 需要头文件< cctype>,也可用万能头包含 函数的返回值为bool类型 char ch1A; char ch2b; //使用islower函数判断字符是否为小写字母 if(islower(…

SpringMVC 进阶

SpringMVC 进阶 一、拦截器 SpringMVC 中 Interceptor 拦截器的主要作⽤是拦截⽤⼾的请求并进⾏相应的处理。⽐如通过它来进⾏权限验证&#xff0c;或者是来判断⽤⼾是否登陆等操作。对于 SpringMVC 拦截器的定义⽅式有两种&#xff1a; 实现接⼝&#xff1a;org.springfram…

如何在3DMax中使用超过16个材质ID通道?

3DMAX效果通道扩展插件EffectsChannelEx教程 3DMax的材质ID通道允许我们生成渲染元素&#xff0c;这些元素可用于在合成或其他软件中产生处理或特殊效果。如对渲染或动画进行颜色校正。你可以在Photoshop中为你的静态3D渲染图像做这件事。或者使用After Effects、Blackmagic Fu…

竞赛选题 目标检测-行人车辆检测流量计数

文章目录 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 行人车辆目标检测计数系统 …

JAVA小游戏 “拼图”

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 创建一个代码类 和一个运行类 代码如下&#xff1a; package heima;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import jav…

企业微信机器人定时发送图文信息,后续无需人工操作

企业微信群机器人是企业微信的内置功能&#xff0c;可以理解为是一个群提醒通知工具&#xff0c;接收数据并自动发送信息到企业微信群中。 数环通实现打通定时器和企业微信机器人的对接&#xff0c;定时执行自动化流程&#xff0c;无需人工干预&#xff0c;实现工作流程自动化&…

【EI会议征稿】2024年电气技术与自动化工程国际学术会议 (ETAE 2024)

2024年电气技术与自动化工程国际学术会议 (ETAE 2024) 2024 International Conference on Electrical Technology and Automation Engineering 2024年电气技术与自动化工程国际学术会议 (ETAE 2024) 将于2024年3月8-10日在中国杭州召开。电气工程及其自动化和人们的日常生活…

电磁场与电磁波part5--均匀平面波在无界空间的传播

目录 1、相位速度 2、波阻抗 3、理想介质中均匀平面波的传播特点 4、色散现象 5、导电媒质中均匀平面波的传播特点 6、趋肤效应 7、电磁波的极化 1、相位速度 电磁波的等相位面在空间中的移动速度&#xff08;相速&#xff09; 在自由空间&#xff08;自由空间的光速&a…

SpringBoot——入门及原理

SpringBoot用来简化Spring应用开发&#xff0c;约定大于配置&#xff0c;去繁从简&#xff0c;是由Pivotal团队提供的全新框架。其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff08;有特殊需求可以添加自己的配置覆盖默认配…

linux上交叉编译qt库

linux上交叉编译qt库 Qt程序从X86平台Linux移植到ARM平台Linux需要做什么 1.在ubuntu上使用qt的源码交叉编译出Qt库 2.将编译好的库拷贝到开发板上并设置相应的环境变量&#xff08;库路径啥的&#xff09; 前两步一劳永逸&#xff0c;做一次就行 3.X86上写好程序代码&…

浅谈多回路电表在荷兰光伏系统配电项目中的应用

1.背景信息 Background&#xff1a; 随着全球化石能源&#xff08;石油&#xff0c;煤炭&#xff09;越来越接近枯竭&#xff0c;污染日趋严重&#xff0c;气候日益变暖等问题&#xff0c;全球多个国家和地区相继出台了法规政策&#xff0c;推动了光伏产业的发展。但是现有的光…

UE5 - ArchvizExplorer - 数字孪生城市模板 - 功能修改

数字孪生项目&#xff0c;大多是双屏互动&#xff0c;而非下方菜单点击&#xff0c;所以要做一番改造 参考&#xff1a;https://blog.csdn.net/qq_17523181/article/details/133853099 1. 去掉提示框 打开BP_MasterMenu_Widget&#xff0c;进入EventGraph&#xff0c;断开Open…

给折腿的罗技G512键盘换键帽

文章目录 1\. 引言2\. 操作2.1. 用打火机烤2.2. 用钳子拔出来2.2.1. 拔出成功2.2.2. 放大细看2.3. 更换键帽 1. 引言 G512的轴采用的是塑料连接&#xff0c;特别容易腿折在里面&#xff0c;换着的时候&#xff0c;得先把这个卡在里面的塑料腿拿出来才行 放大效果图 2. 操作 可…

Spring Boot中使用Redis进行大数据缓存

Spring Boot中使用Redis进行大数据缓存 在Spring Boot中使用Redis进行大数据缓存是一种常见的做法&#xff0c;因为Redis是一种高性能的内存数据库&#xff0c;适用于缓存大量数据。以下是说明和示例代码&#xff0c;演示如何在Spring Boot项目中使用Redis进行大数据缓存。 步…

龙讯旷腾PWmat发PRL:多k点计算的NAMD方法应用于小型超胞与在等效的大型超胞中进行的单个Γ点模拟之间的一致性

文章信息 作者信息&#xff1a;郑帆&#xff0c;汪林望 通信单位&#xff1a;上海科技大学 中国科学院半导体所 背景导读 固态材料中的超快载流子动力学在能源材料、光电子学、传感器和量子材料等领域起着关键作用。随着超快实验技术在固态系统中载流子动力学研究中的快速发…

纯CSS动态渐变文本特效

如图所示&#xff0c;这是一个炫酷的文本渐变效果&#xff0c;如同冰岛的极光一般。本次的文章让我们逐步分解代码&#xff0c;了解其实现原理。 基于以上动图效果可以分析以下是本次动效实现的主要几点&#xff1a; 文本中有多个颜色的动画每个颜色显示的半径不同&#xff0…

MCU内存基础知识

文章目录 一、存储器分类二、C语言内存分区内存区三、STM32启动文件分析四、应用分析 一、存储器分类 RAM&#xff08;Random Access Memory) &#xff1a;掉电之后就丢失数据&#xff0c;读写速度块 ROM (Read Only Memory) &#xff1a;掉电之后仍然可以保持数据 单片机的RA…

Springboot 项目启动类放置位置

文章目录 Springboot 项目启动类放置位置springboot 默认包扫描机制启动类放在特定位置springboot 启动注解理解配置启动类扫描特定的包1、 ComponentScan2、利用 SpringBootApplication 注解的 scanBasePackages 属性 Springboot 项目启动类放置位置 如果我们使用 IDEA 或者 …

将Agent技术的灵活性引入RPA,清华等发布自动化智能体ProAgent

近日&#xff0c;来自清华大学的研究人员联合面壁智能、中国人民大学、MIT、CMU 等机构共同发布了新一代流程自动化范式 “智能体流程自动化” Agentic Process Automation&#xff08;APA&#xff09;&#xff0c;结合大模型智能体帮助人类进行工作流构建&#xff0c;并让智能…

Openlayer【二】—— 绘制不同的点、线以及给其添加监听事件

Openlayer【二】—— 绘制不同的点、线以及给其添加监听事件 接上篇&#xff1a;OpenLayer初始化 在openlayer当中&#xff0c;图层Layer与地图源Source是一对一的关系。当创建了一个图层Layer&#xff0c;相应的需要给图层添加地图源Source&#xff0c;然后将图层Layer添加到…