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

  //  

编者按:随着手机相机功能日益强大,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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android 13 - Media框架(14)- OpenMax(二)

这一节我们将来解析 media.codec 这个 HIDL service 究竟提供了什么服务,服务是如何启动的。 1、main 函数 我们先来看 frameworks/av/services/mediacodec/main_codecservice.cpp: int main(int argc __unused, char** argv) {strcpy(argv[0], "…

微服务 Spring Cloud 7,Nacos配置中心的Pull原理,附源码

目录 一、本地配置二、配置中心1、以Nacos为例:2、Pull模式3、也可以通过Nacos实现注册中心 三、配置中心提供了哪些功能四、如何操作配置中心1、配置注册2、配置反注册3、配置查看4、配置变更订阅 五、主流的微服务注册中心有哪些,如何选择?…

76基于matlab的免疫算法求解配送中心选址问题,根据配送地址确定最佳配送中心地址位置。

基于matlab的免疫算法求解配送中心选址问题,根据配送地址确定最佳配送中心地址位置。数据可更换自己的,程序已调通,可直接运行。 76matlab免疫算法配送中心选址 (xiaohongshu.com)

常见Web安全

一.Web安全概述 以下是百度百科对于web安全的解释: Web安全,计算机术语,随着Web2.0、社交网络、微博等等一系列新型的互联网产品的诞生,基于Web环境的互联网应用越来越广泛,企业信息化的过程中各种应用都架设在Web平台…

SpringCloud总结

注:本文并不涉及具体功能是怎么实现的,而只是微服务技术栈的整体总结和理解。 目录 一.基础概念--认识微服务 1.单体架构 2.分布式架构 3.微服务 4.SpringCloud 二.服务的拆分原则 三.RestTemplate--实现不同服务之间的通信与远程调用 四.Eurek…

5 redis的GEO操作

一、GEO Redis 3.2版本提供了GEO(地理信息定位)功能,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。 有效纬度从-85.05112878度到85.05112878度 注意:当坐标位置超出上述指定范围时,将会返回一个错误。 …

RTMP协议和源码解析

一、背景 实时消息传输协议(Real-Time Messaging Protocol)是目前直播的主要协议,是Adobe公司为Flash播放器和服务器之间提供音视频数据传输服务而设计的应用层私有协议。RTMP协议是目前各大云厂商直线直播业务所公用的基本直播推拉流协议&a…

高防CDN为什么可以防DDOS攻击

CDN的全称是ContentDeliveryNetwork,即内容分发网络,顾名思义,它是一个分布式节点网络(也称为边缘服务器),CDN节点具有缓存内容的功能,使用户可以在不获取源服务器数据的情况下就近获取所需内容,提高客户访…

【LeetCode每日一题合集】2023.9.25-2023.10.1(⭐LFU缓存Java数据流花期内花的数量)

文章目录 460. LFU 缓存⭐(数据结构题)解法1——平衡树 哈希表(TreeSet HashMap) O ( l o g n ) O(logn) O(logn)解法2——双哈希表 双向链表 O ( 1 ) O(1) O(1) (LRU缓存的升级版) 2582. 递枕头解法—…

SpringCloud微服务注册中心:Nacos介绍,微服务注册,Ribbon通信,Ribbon负载均衡,Nacos配置管理详细介绍

微服务注册中心 注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就这里找到服务的地址,进行调用。 微服务注册中心 服务注…

LV.12 D18 中断处理 学习笔记

一、ARM的异常处理机制及工程代码结构 1.1异常概念 处理器在正常执行程序的过程中可能会遇到一些不正常的事件发生 这时处理器就要将当前的程序暂停下来转而去处理这个异常的事件 异常事件处理完成之后再返回到被异常打断的点继续执行程序。 1.2异常处理机制 不同的处…

2023/11/19总结

项目进度: 地址管理: 显示菜品 购物车相关功能 然后最近在看 支付宝沙盒支付的相关功能,打算把支付给做了 。界面做的不是很好看 ,但是后续会改成 手机端的。

丹麦能源袭击预示着更关键的基础设施成为目标

5 月,22 个丹麦能源部门组织在与俄罗斯 Sandworm APT 部分相关的攻击中受到损害。 丹麦关键基础设施安全非营利组织 SektorCERT 的一份新报告描述了不同的攻击者群体利用合勤防火墙设备中的多个关键漏洞(包括两个零日漏洞)侵入工业机械&…

【Android Jetpack】DataStore的介绍

DataStore Jetpack DataStore是一种数据存储解决方案,允许您使用协议缓冲区存储键值对或类型化对象。DataStore使用Kotlin协程和Flow以异步、一致的事务方式存储数据。 注意:如果您需要支持大型或复杂数据集、部分更新或参照完整性,请考虑使…

配置iTerm2打开自动执行命令

打开iTerm2,commado,打开profies->edit profies,点击号,创建一个新的profile 在新的profile中填写 name:随意 command:Login Shell Send text at start:执行脚本的命令,不想写路…

C# Winform围棋棋盘

C# Winform简单的围棋棋盘vs2008winform小游戏C#vs2010winform棋盘C#窗体小游戏 这是一个简单的围棋棋盘小游戏,使用C# Winform编写棋盘界面,玩家可以在空白的交叉点上下棋子 项目获取: 项目获取:typora: typora/img (gitee.co…

【Android Jetpack】Hilt的理解与浅析

文章目录 依赖注入DaggerHiltKoin添加依赖项Hilt常用注解的含义HiltAndroidAppAndroidEntryPointInjectModuleInstallInProvidesEntryPoint Hilt组件生命周期和作用域如何使用 Hilt 进行依赖注入 本文只是进行了简单入门,博客仅当做笔记用。 依赖注入 依赖注入是一…

SQL基础理论篇(七):多表关联的连接算法

文章目录 简介Nested LoopsMerge JoinHash Join总结参考文献 简介 多表之间基础的关联算法一共有三种: Hash JoinNested LoopsMerge Join 还有很多基于这三种基础算法的变体,以Nested Loops为例,就有用于in和exist的半连接(Nes…

基于Python+OpenCV+Tensorflow图像迁移的艺术图片生成系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统![请添加图片描述](https://img-blog.csdnimg.cn/dbda87069fc14c24b71c1eb4224dff05.png)四. 总结 一项目简介 基于PythonOpenCVTensorfl…

ARouter出现 there‘s no route matched in group问题排查

在使用ARouter时候会出现找不到映射路径的问题,这里给兄弟们总结下踩过的坑 所有用到的模块都要有填写依赖 android {defaultConfig {......javaCompileOptions {annotationProcessorOptions {arguments [AROUTER_MODULE_NAME: project.getName()]}}} } ... depe…