在线视频协同:探究画面帧的准确性

编者按:视频协作平台会涉及网络、编解码等众多技术栈,并且要支持各类终端。其中一个关键能力是实现毫秒级的同步,这对于视频协作平台十分重要。本文来自分秒帧 web多媒体开发工程师耿学岩的投稿,详解了实现毫秒级同步遇到的两个挑战和解决方案。最后,如果你有一定的经验和思考又乐于分享,欢迎通过 editors@livevideostack.com 投稿给我们。

文/耿学岩

背景

分秒帧是一个音视频生产协作平台,其中用户可以通过在视频的某个时间点提出意见或分享来沟通对视频的修改意见。由于客户有时需要对时间精确到帧进行定位,我们需要保证不同转码视频在播放时,时间定位能够精确到毫秒级别。在满足这一要求的同时,我们还必须考虑不同网络条件、不同端和不同使用场景。我们在解决这些问题的过程中发现了一些问题,本文将对这些问题进行讨论。

为什么需要画面帧的准确性?

图片

图:用户发送的批注

图片

图:审阅者看到的

当用户发送批注需要审阅者根据批注意见做出修改时,如果没有画面校准,此时审阅者一脸黑人问号, 哪来的“T” ? 然后再私下沟通吗?信息存在误差, 审阅批注就毫无意义。

问题一:保证浏览器中 Video 标签时间定位在 pause 时的准确性

当用户在播放视频时暂停,并对视频进行批注,然后继续播放时,有时会发现定位回原始批注时间点时画面会有一帧的偏差。这是因为,我们在暂停时记录了视频的当前时间(即 currentTime)并通过 seek() 方法回到该时间点,但是这个方法并不能保证回到的画面完全准确。

现象

暂停批注时 没有矫正currentTime,当批注发送成功后,自动跳回批注点,画面发生了变化,以下是用户所不想看到的画面:

JS代码如下:

JavaScript
var videoDom =  document.getElementsByTagName('video')[0]
videoDom.pause()
var currenttime = videoDom.currentTime
videoDom.currentTime = currentTime // 此时画面有概率发生改变

问题产生原因

我们在解决这个问题时发现,这个问题是由 JavaScript 执行机制导致的。在浏览器中,JavaScript 是单线程执行的。当我们调用 pause 方法时,实际上是将该操作添加到了事件队列中。当事件轮询到这个暂停操作时,才会真正执行 pause 方法。而在这个过程中,获取 currentTime 的操作已经完成了。这就导致了两个操作之间的时间差。如果这个时间差恰好发生在视频帧切换的时候,就会导致画面偏差一帧。

举个例子,如果一个视频有 25 帧,那么第 0-40ms 是第一帧画面,第 41-80ms是第二帧画面,以此类推。

图片

当用户在播放第一帧画面时按下暂停按钮,我们认为JavaScript 会立即执行逻辑并通知 Video 标签停止播放,但实际上暂停操作会被加入事件队列中等待执行。如果暂停操作前面还有其他事件正在排队,等执行到暂停操作时就会有一定的时间差。如果这个时间差恰好发生在第 41 ms,画面会跳到下一帧画面。但是,我们拿到的currentTime还是第一帧画面的。

解决方案

为了确保在暂停时和查看批注时 currentTime 的一致性,我们在暂停时对 currentTime 进行了矫正。这样,当用户暂停时进行批注,然后再设置 currentTime查看批注时,就不会出现画面偏差问题。通过这种方式,我们就能保证画面在暂停时和查看批注时的准确性。

问题二:HLS流中视频 duration 值变化异常

在我们的应用中,我们需要确保各端的视频总时长和总帧数一致。为了实现这个目的,我们通常会在浏览器 Video 标签的 durationchange 事件触发时获取视频总时长,并通过帧率计算出总帧数。durationchange 事件是当视频总时长发生改变时触发的。当视频加载前,总时长为默认值"NaN",当视频加载完成后,durationchange 事件触发,总时长会变成视频的实际总时长。

在加载和播放视频时,浏览器会用Video标签来追踪视频的状态。共有五个状态,分别是:[1]。

在视频加载和播放过程中,浏览器Video标签的 readyState 会发生变化。在这个过程中,MP4文件和HLS文件的 duration 变更时机是不同的。

MP4

在 MP4 文件的加载过程中,durationchange 事件会在资源开始加载(loadstart)之后,在元数据已加载(loadedmetadata)之前触发。此时,浏览器会解析 MP4 文件中的 moov box,并获取视频时长。因此,在 durationchange 事件触发时,可以获取到较为准确的 duration 。

HLS

我们发现在加载 HLS 流时,浏览器 video 标签的 duration 会发生多次变更。

第一次变更在loadstart之后 loadedmetadata 之前 并且 readyState === 0 时调用,此时已拿到相对准确的 duration,≈ ffmpeg取到的 durantion。

举个例子,ffmpeg截图如下:

图片

第二次变更在loadstart之后 loadedmetadata 之前 并且 readyState === 1 时调用,此时拿到的时长由 m3u8 文件解析得到。

第三次变更在加载到最后一片 ts 时调用。我们发现这三次变更的时长并不一致。因此我们需要在这三次变更中取一个更准确的时长作为视频时长。

举个例子,三次时长比较:

图片

HLS三次取值时长不一致的原因

第一次:在loadstart后loadedmetadata前readyState === 0时调用,视频的实际时长已被解析出来,时机和机制类似于MP4文件(第一次调用时就可以获取到duration的值)。

第二次:在loadstart后loadedmetadata前readyState === 1时调用,hls.js解析完m3u8索引文件并通过#EXTINF计算出视频的实际时长。

举个例子,以下是一个m3u8文件信息:

图片

第三次:当加载完最后一片ts 此时所有音频和视频帧信息已经可以全部拿到。

举个例子,以下是帧信息:

图片

图片

图片

图片

best\_effort\_timestamp_time :媒体流中的一个标识符,用于标识每一帧的时间戳。

pkt\_duration\_time :媒体流中的一个标识符,用于标识每一帧的持续时间。

通常,best\_effort\_timestamp\_time 和 pkt\_duration_time 会用在音视频同步、流量控制、缓存等方面。[2]

尾音频/视频信息中的 best\_effort\_timestamp\_time 和 pkt\_duration\_time 可用来计算音频/视频的结束时长。在这个案例中,音频结束时长由 best\_effort\_timestamp\_time 和 pkt\_duration\_time 相加所得(即 96.230300 + 0.023211 = 96.253511),视频结束时长也是如此(即 96.229778 + 0.016667 = 96.246445)。

我们发现,音频结束时长 - 音频首个best\_effort\_timestamp_time约等于第三次获取的duration。具体来说,音频的结束时间比视频的结束时间长,同时音频的第一个时间戳早于视频的第一个时间戳。为了包含最完整的时间长度,需要将音频和视频时间戳中的最小值和最大值来进行计算。这种情况可能出现在音频和视频的录制或处理过程中,需要进行相应的调整以确保两者之间的同步和一致性。

参考资料

1.https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement/readyState

2. https://www.jianshu.com/p/c9b772233056

248 声望
67 粉丝
0 条评论
推荐阅读
专访瑞声科技应用软件开发总监陆其明:当一名老兵决定重新上路
编者按:从互联网公司到智能终端解决方案公司,陆其明的这次转变可能难以被人理解。但经济大环境的影响和个人的技术困境还是让他义无反顾地走向一个未知的世界。正如黄仁勋日前所言,“撤退”对聪明人来说并不容易...

LiveVideoStack阅读 169

封面图
【音视频】摄像头
IP Camera主要指那些可以直接接入Internet的摄像头,一般不需要专门的PC支持,可以归类于嵌入式设备。多用于监控,如公路上各个路口的监控设备。价格相对较高

看见了阅读 824

出海无从下手?看社交泛娱乐出海「第一趁手工具」怎么说
经过近几年的发展,如今的互联网出海已经是截然不同的命题。开头引导语:移步【融云全球互联网通信云】回复“地图”限量免费领《社交泛娱乐出海作战地图》

融云RongCloud阅读 696

音视频通讯QoS技术及其演进
QoS(Quality of Service)是服务质量的缩写,指一个网络能够利用各种基础技术,为指定的网络通信提供更好的服务能力,是网络的一种安全机制,是用来解决网络延迟和阻塞等问题的一种技术,包括流分类、流量监管、...

阿里云视频云阅读 492

封面图
“易+”开源 | 基于 ijkplayer 的 LLS-Player 移动端应用实践
云信低延时直播(Low-Latency Streaming,LLS)是在网易云信标准直播的基础上,依托自研的全球实时传输网 WE-CAN 推出的低延时直播产品方案。在保障低延时的同时,具有极致秒开,低卡顿的特性。同时兼容标准直播...

网易智企阅读 412

封面图
保姆级教程!集成声网 SDK 实现 iOS 平台音视频通话和虚拟背景功能
如果你想实现 iOS 平台的音视频通话,想在音视频通话中添加虚拟背景,那这篇文章完全可以借鉴。使用 swift 语言,集成声网 SDK 实现音视频通话,并调用 enableVirtualBackground 接口添加虚拟背景,小伙伴们赶快...

声网阅读 397

保姆级教程!基于声网 Web SDK实现音视频通话及屏幕共享
前言大家好,我是 @小曾同学,小伙伴们也可以叫我小曾~如果你想实现一对一音视频通话和屏幕共享功能,不妨来看看这篇文章,保姆级教程,不需要从零实现,直接集成声网 SDK 即可轻松上手。本文也分享了我在实践过...

声网阅读 352

248 声望
67 粉丝
宣传栏