【AICon 全球人工智能与大模型开发与应用大会】改变 AI 时代下写代码的模式 >>> 了解详情
写点什么

极致首帧播放方案:零首帧解决方案

字节跳动视频云技术团队-琨君

  • 2023-03-04
    北京
  • 本文字数:3142 字

    阅读完需:约 10 分钟

极致首帧播放方案:零首帧解决方案

背景介绍


首帧时间,是指用户从点击开始播放到视频首帧画面展现出来的时间。「零首帧」并不是真的 0 毫秒启播,而是用户几乎感知不到有首帧时间的存在,在我们的播放质量埋点中对应小于 100ms 以内的首帧时间。在我们的播放器中,在各环节提供了极致的首帧优化方法,在条件允许符合时,可以将首帧时间压缩到 100ms 以下,用户感知到的就是完全平滑播放,没有首屏的顿感。当然在现实业务中,有些场景是无法使用所有的优化条件的,比如在随机播放的场景不能进行预加载、某些场景不适合使用播放器复用技术等。结合实际业务场景,尽量多的使用我们提供的优化能力,就可以使大部分用户体验为零首帧情况。


首帧的构成


首帧的概念,首帧对于视频播放体验的影响

首帧时间,是视频类应用的一个重要核心指标,也是影响用户观看体验的核心因素之一。举个例子,如果一个视频需要花好几秒时间才加载出首帧,大部分用户都等不到首帧加载出来就放弃播放了。因此,优化视频播放的首帧时间是极其重要的。



上面这幅图是一个视频点击播放的整个流程,可以看出首帧时间主要包含这么几个部分: 获取视频播放链接,网络建连,下载视频头部数据,音视频解码和渲染。本文将从视频播放的整个过程出发,介绍首帧优化的一些通用方案。同时在本文最后,会以长视频场景播放和带历史进度的起播为例,介绍面向场景的首帧优化


通用的首帧优化方法

获取播放地址


播放地址随 feed 下发

视频播放的第一步就是获取视频资源的播放链接,通常而言,视频资源会有唯一标识 video id , 在点播的服务端会有一个根据 video id 信息获取播放链接的服务,如果 app server 端能够调用 vod 服务生成播放地址,然后将播放地址随 feed 流一起下发,则省去了客户端的一次网络请求耗时。


网络建连


DNS 预解析,预连接、连接复用,https TLS 1.3 false start, session 复用 0RTT

在拿到播放地址之后,播放器会去与 cdn 建连,首先会进行 DNS 解析。而为了防止 DNS 劫持,大部分客户端会采取 HTTPDNS 的方式做 DNS 解析,这又会涉及到一个网络请求的耗时。我们可以采取 DNS 预解析的策略,比如 app 启动时,服务端就可以提前下发 app 可能用到的域名,客户端则可以对这几个域名提前做 DNS 解析,并做缓存。在 HTTP 1.1 中支持连接复用,因此我们可以预先创建几个与 CDN 的 socket 连接,然后在播放时直接复用连接即可。另外,为了应对内容劫持,在部分地区播放开启了 https,而 https 相比于 http 多了 TLS 握手的过程,这个握手过程会给视频首帧多引入 2 个 RTT 。通过 TLS False Start 加上 session 复用,可以做到 0RTT 握手。


音视频首包


减少 probe、moov 位置

在播放器与 CDN 完成建连后,播放器就开始下载视频文件, 首先播放器会尝试探测视频文件的格式、编码等信息。如果视频源经过服务端统一转码,那么就可以省去这个探测的过程。同时,值得一提的是,常见的 mp4 视频文件,有一个 moov box,这里面会存储音视频流 track 信息比如解码信息、以及音视频帧与文件对应的关系(用于 seek ),因此通常播放器都会先下载 moov 的数据。而 moov 的位置则会对起播造成一定的影响。举个例子,如果 moov 在文件尾部,当下载了视频前面部分数据,发现 moov 没找到,就去尾部查找 moov,这样就又多了两次网络请求。对于这个问题,我们可以通过转码将 moov 挪到视频文件的头部,从而缩短首帧耗时。


音视频解码


解码器异步初始化、解码器复用

通常情况下,在播放器读取到视频数据,拿到视频的解码信息后就可以开始创建解码器解码了。不过解码器创建这个过程,尤其是在 Android 平台上 MediaCodec 的创建是一个比较耗时的操作。这里我主要介绍两个优化: 解码器异步初始化和复用。如果 app server 提前把视频的解码信息传递给播放器,那么播放器就可以在建连的同时去异步初始化解码器,这样就可以减小硬解创建耗时的影响。而解码器复用则可以完全消除这个耗时,顺着这个思路,我们可以做播放器线程的复用甚至整个播放器的复用,这些方法都可以大幅优化首帧耗时。


起播水位


理论上,要做到极致首帧,可以当视频首帧解码完成就直接播放。但是实践发现,这样做会导致视频播放的卡顿增多,尤其是视频起播后 1~3s 的卡顿增加。经过大量的实验,我们发现,如果对视频起播做一定限制,比如让起播之前缓存一定的数据,这样可以大幅减少卡顿,同时对首帧的影响不大,并且可以显著提升用户的观看时长和观看 vv。


预加载


预加载是一种常见的首帧优化措施,我们可以提前下载视频数据的一部分以达到快速起播的目的。但是什么时候去预加载、预加载多少、并行预加载数量等都是实际需要考虑的问题。首先是预加载时机的问题,对于 15s 的短视频而言,完全可以等到当前视频加载完成之后再启动预加载,这样预加载就不会和当前视频的播放抢占带宽。但是如果一个视频时长超过 1min ,我们就得重新考虑预加载时机的问题了,具体来说,我们需要考虑当前播放视频的可用缓存、当前网络的下载速度、当前视频的码率以及即将预加载视频的码率、并行预加载数量,通过这些数据我们能够构建一个模型去预测接下来视频播放的卡顿状况,如果大概率是不会发生卡顿,则可以开启预加载,反之则不启用或者暂停预加载。另外一个问题,预加载多少,直观认识,至少得保证首帧能加载出来。一个粗略的估算方法是 moov 大小加上视频的平均码率 * 预加载时长,这样就可以通过服务端下发 moov 头大小及视频的平均码率,然后在 app 端上通过实验去调整预加载时长参数,进而调整预加载大小。


预渲染


原理介绍

预加载只能够将网络请求的耗时消除掉,但播放器还是需要经历解复用、解码、渲染的步骤,在中低端机器有 200ms 以上的耗时。如果能够将视频的首帧提前渲染好而不播放,将会缩减掉这部分的耗时。而预渲染则是提前将视频的首帧渲染出来的技术。具体来说,预渲染会提前解码出视频首帧,并且将首帧渲染出来,但是这个过程中音频不会播放出来。举个例子,在小视频场景上,当滑动视频卡片时,就已经开始启动预渲染,在卡片滑动过程中,视频的首帧很可能就已经通过预渲染加载出来,这样当卡片滑到中央时,则直接启动播放,这时候用户基本上感受不到视频的加载。


结合使用场景的优化


前面提到各种首帧优化的手段都是比较通用的策略,而面向场景的优化也是极为重要的,在本文接下来的部分会介绍两种场景下的起播优化: 1.长视频场景的播放优化 2.带历史进度的起播优化。


长视频场景优化


mp4 格式介绍,moov 大小与时长关系

短视频通常采用 mp4 这种视频格式,前面也提到过 moov 的下载是 mp4 视频起播的重要条件,而 moov 的大小则与视频时长正相关,粗略统计 moov 的大小约为 40KB/min 。这样 1h 的长视频 moov 头就有 2.4MB ,如果平均网速 1MB/s ,则需要 2.4 秒的加载时间,这对于弱网用户而言是极差的体验。而 fmp4 这种视频格式则能很好解决这个问题,fmp4 将一个完整的视频拆分成若干个小的片段,而每个片段的索引则存在于 sidx box 中,这样起播所需要的数据量就大幅下降,从而缩短了首帧耗时。另外,长视频往往有前贴广告,我们也可以在前贴广告播放器期间,结合预渲染提前加载正片首帧。


带历史进度的起播


关键帧起播

在中长视频中有一个功能是记住历史进度播放,通常的实现方式是 seek 到历史进度前面最近的一个关键帧,然后把视频帧塞给解码器,在解码器中做丢帧处理,直到 pts 到了指定的历史进度。假设这个视频的码率是 4Mbps ,视频的 GOP 大小为 5s ,那么这种场景的起播最坏情况需要额外下载 4 * 5=20Mb 的数据。如果我们限制只在关键帧位置起播,则可以避免这些额外数据的下载,从而显著缩短首帧的耗时。


总结


本文主要按照首帧的各个阶段分别介绍了对应的优化方案,也简单介绍了预加载和预渲染这两个优化首帧的利器,在文章最后针对长视频以及历史进度起播这两种场景,介绍了对应的优化手段。

2023-03-04 19:007148
用户头像
鲁冬雪 InfoQ 主编

发布了 322 篇内容, 共 176.7 次阅读, 收获喜欢 264 次。

关注

评论

发布
暂无评论
发现更多内容

【墨菲安全实验室】Microsoft Teams 远程代码执行漏洞 (CVE-2023-29330)

墨菲安全

安全 漏洞 网络安全、 Microsoft Teams

【墨菲安全实验室】Microsoft Exchange Server 远程代码执行漏洞(CVE-2023-38182)

墨菲安全

网络安全 安全 漏洞 Microsoft Exchange

大型集团公司如何打破“信息孤岛”问题?

优秀

打破信息孤岛 消除信息孤岛 信息孤岛

确保数据一致性:单一可信数据源(SSOT)的概念与5个应用示例

龙智—DevSecOps解决方案

ssot single source

〔支付接入〕微信的 h5 支付和 jsapi 支付

极客飞兔

微信支付 支付 经验分享 H5支付 jsapi支付

百度、NVIDIA、Intel……各大厂商集结,共话文心与飞桨共享生态下的大模型训推部署创新实践计划

飞桨PaddlePaddle

人工智能 百度飞桨 硬件生态 WAVE SUMMIT

电动汽车安全概述

DevOps和数字孪生

电动汽车 汽车安全

嵌入式软件开发为什么需要DevOps?

DevOps和数字孪生

DevOps 嵌入式软件

IoTDB 小白“踩坑”心得:入门安装部署篇

Apache IoTDB

龙智Atlassian认证专家、Perforce技术专家将于ACT汽车电子与软件技术周带来主题演讲,分享嵌入式开发中的最佳实践与工具链构建

龙智—DevSecOps解决方案

汽车电子 ACT汽车电子与软件技术周

如何在Confluence上设置到期日提醒?Confluence到期日提醒插件重要更新发布,优化表格提醒,增加屏蔽提醒功能

龙智—DevSecOps解决方案

confluence插件

Dragonfly 发布 v2.1.0 版本!

SOFAStack

AI 算法 后端 基础设施 分发

面部表情识别在医疗领域的应用

来自四九城儿

【墨菲安全实验室】Microsoft Office Visio 远程执行代码漏洞(CVE-2023-36865)

墨菲安全

网络安全 安全 漏洞 Microsoft Office Visio

【低代码预研】通过低代码平台开发应用程序

互联网工科生

软件开发 低代码 应用开发 JNPF

值得收藏!堪称神器的30个插件

Finovy Cloud

插件 渲染 建模 maya 3d建模

14个前端开发者应该知道的实用网站

高端章鱼哥

前端 提高效率 前端开发工具

KeyShot 2023.2 Pro for mac(3D渲染和动画制作软件) v12.1.1.12激活版

mac

苹果mac Windows软件 KeyShot Pro 动画软件

腾讯云大数据ES:结合AI大模型与向量检索的新一代云端检索分析引擎

腾讯云大数据

ES

【墨菲安全实验室】WPS Office 存在代码执行漏洞

墨菲安全

网络安全 安全 漏洞 WPS Office

PP-ChatOCR:基于文心大模型的通用图像关键信息抽取利器,开发提效 50%!

飞桨PaddlePaddle

人工智能 百度飞桨

【华秋干货铺】电源PCB设计汇总

华秋电子

一文走进时序数据库性能测试工具 TSBS

KaiwuDB

性能测试 时序数据库 KaiwuDB

实现分布式事务:Java与MySQL的XA事务协调

树上有只程序猿

Java MySQL 数据库 分布式 XA

几个提高性能的小特性

这我可不懂

数据库 postgresql LOCALE

聊聊低代码的本质,是应用开发的未来吗?

高端章鱼哥

低代码 应用开发 JNPF

详解低代码和无代码的区别

这我可不懂

低代码 无代码 应用开发 JNPF

【墨菲安全实验室】Apache Traffic Server Range 标头验证不当(CVE-2023-33934)

墨菲安全

Apache 网络安全 安全

甭提ChatGPT了,这个新的AI助手将永远改变人们的工作方式

互联网工科生

人工智能 AI 机器人

巧用Maya轴心操作小技巧,工作事半功倍!

3DCAT实时渲染

maya制作技巧 3D软件教程

【墨菲安全实验室】Zoom Desktop Client for Windows <5.14.5 权限升级漏洞(CVE-2023-36541)

墨菲安全

网络安全 安全 Zoom 漏洞 墨菲安全

极致首帧播放方案:零首帧解决方案_语言 & 开发_InfoQ精选文章