Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >video_replay如何捕获和回放WebRTC视频流

video_replay如何捕获和回放WebRTC视频流

作者头像
LiveVideoStack
发布于 2021-09-02 03:18:54
发布于 2021-09-02 03:18:54
2K00
代码可运行
举报
文章被收录于专栏:音视频技术音视频技术
运行总次数:0
代码可运行

视频编码问题常常是最难解决的问题之一,video_replay工具可以帮助分析定位故障。视频协作平台pixip的工程师Stian Selnes撰文,详解了如何通过video_replay来捕获、分析视频的。LiveVideoStack对本文进行了摘译。

在数据包有丢失的环境下进行视频解码不是一件容易的事。Chrome 58中引入了一种新的视频抖动缓冲区,这导致最新版的Chrome在视频显示时一直有问题。由于该问题只在某些数据包丢失时才会出现,因此调试难度很大。为此,webrtc.org提供了一个名为video_replay的工具来复现和分析这些棘手问题。

当看到Stian Selnes提交的一个版本中视频显示仍然有问题时,我将这个工具告诉了他。将视频流轻松重现后,谷歌的WebRTC视频团队很快就解决了这个bug。不过,这一过程的记录做得不是很好,所以我们请Stian重现了抓取必要数据和使用该工具进行操作的过程。Stian目前在pexip工作,他有超过10年的实时通信处理经验。他在媒体协议栈领域有非常丰富的经验,特别是在视频编解码以及其他类型的信号处理、网络协议和错误恢复能力等方面。

WebRTC包含了一个非常好用但鲜为人知的工具——video_replay。事实证明,在调试视频解码问题时,这个工具非常好用。它的目的是什么呢?为了在发现异常行为之后能容易地重复捕获WebRTC呼叫,video_replay将捕获的RTP流视频作为输入文件,然后离线使用WebRTC框架来解码数据,最后在屏幕上显示输出的结果。

例如,最近我正在研究一个问题,有一个版本的Chrome显示输入的视频时突然出了上面这样的问题。最终,使用video_replay调试后,WebRTC的团队发现,Chrome中实现抖动缓冲区的部分出现了一个错误,这导致视频流在某些情况下显示会有异常。这种看似随机数据导致的错误其实是VP8解码器的内部状态引起的。

视频编码问题常常是最难解决的问题之一。最初,我自己写了一个测试方法,每20次调用中大约复现1次这样的问题。使用这种方法重现问题是非常耗时的,效果通常也不好,最终也没有给WebRTC团队解决该问题起到什么作用。

为了可以多次重现这个问题,我设法使用wireshark捕获到一个失败的呼叫,然后使用video_replay工具来分析。这样我就有了一个每次都能重现这个罕见的问题测试用例。当一个问题具有重复性的时候,解决问题和打补丁就非常轻松啦!这是典型的双赢局面。

在这篇文章中,我将通过一个例子来演示如何使用video_replay,包括如何来捕捉一个WebRTC呼叫的RTP通信数据,识别和提取接收到的视频流,最后如何导入到video_replay中来实现在屏幕上显示捕获的视频。

捕获未加密的RTP数据

video_replay将输入的文件导入到RTP协议栈、协议包解析设备和解码器中,不过目前还没有能力解密加密呼叫使用的SRTP包。Chrome和Firefox都支持加密呼叫,但是解密WebRTC呼叫却不是一个简单的过程。尤其是SRTP进行秘钥分发时使用DTLS来保密共享,因此该秘钥难以获得。为此,最好用Chromium或Chrome Canary,因为它们有一个可以禁用SRTP加密的选项。启动浏览器时添加命令行标志–disable-webrtc-encryption即可,如果在窗口的顶部看到警告信息,说明你使用的浏览器不支持命令行标志。注意,这要求双方在通话都不能加密,否则会话将无法连接。

首先,使用Wireshark捕获数据包。在会话开始发送媒体数据之前就要打开捕获功能,这一点很重要,因为这可以将整个流都能记录下来。如果捕获的数据中丢失了流的开头,视频解码器将无法解码。

第二,打开一个选项卡,进入chrome://webrtc-internals (或者Fippo最新的webrtc-externals).。呼叫之前首先做这个,以获取所有需要的信息,特别是SDP协商信息(如果想深入分析该问题,请见webrtchacks SDP分析指导)。

最后,就是呼叫了。我们以appr.tc为例,但适用于任何使用WebRTC的呼叫。打开第二标签进入https://appr.tc/?IPv6 = false。由于目前video_replay尚没有IPv6相关的解决方案,因此在这个例子中,我将其禁用,希望该问题能很快解决。

现在,加入一个直播室。当第二个参与者加入同一个房间时,RTP将开始流动。不管谁先加入,除非chrome://webrtc-internals看起来有异常。下面的截图是在拨号进入现有房间时拍摄的。

收集信息

为了从接收到的流中成功获得RTP包,并能顺利使用video_replay播放,我们需要收集一些关于RTP流的细节信息。有几种方法可以做到这一点,我坚信最重要的是下面这几个:

  • Video codec 视频编码
  • RTP SSRC RTP SSRC
  • RTP payload types RTP 载荷类型
  • IP address and port IP地址和端口

使用webrtc-internals来收集统计信息

首先,扩大接收到的视频流的统计表,给一个类似于ssrc_4075734755_recv这样的命名。统计表可能不止一个,一般第二个是音频流,还可能有一对以_send为后缀的表,里面是发送流的等效统计信息。视频流接收的统计表可以根据_recv后缀和mediaType=video来识别出来。分别记下ssrc、googCodecName 和transportId属性,例如4075734755、VP9和channel-audio-1。

你可能会问为什么的视频流和音频通道有相同的transportid?这表示使用了BUNDLE来使音频和视频共享通道。如果BUNDLE没有协商和使用,音频和视频将使用单独的通道。

下一步,我们将查看协商的SDP以获得RTP有效载荷类型(PT)。除了PT使用的视频编解码器,我们还必须找到RED的PT标记,这个PT是WebRTC用来封装的视频包的。SDP描述了视频客户端的接收能力,因此为了找到接收到的有效负载类型,我们必须查看浏览器向另一个参与者提供的SDP类型。

这可以通过扩展的setlocaldescription API调用找到,找到M =video的部分和后面每个支持的编解码器的PT的rtpmap定义。由于我们的视频编解码器的VP9,我们会关注的属性是a=rtpmap:98 / 90000和a= rtpmap:102 red/9000,这告诉我们,VP9和RED的有效载荷类型分别为98和102。

如果你正在寻找发送流而不是接收的信息,你应该看看其他参与者通过setRemoteDescription的扩展字段标记了什么。事实上,载荷字段的类型应该是对称的,所以无论你看setlocaldescription或setremotedescription无关紧要,但在实时视频通信的世界,没人什么都知道,所以最好是都看一下。

为了在Wireshark中快速确定正确的RTP流,需要知道IP地址和使用端口。远程或本地地址并不重要,只要使用适当的wireshark过滤就行。对于这个示例,我们将使用本地地址,因为我们希望提取所接收的流,所以它是数据包的目的地。在chrome://webrtc-internals 的Conn-audio 和 Conn-video部分包含了连接的统计信息。处于活跃状态的用粗体突出显示,根据上一步提到的transportid我们就可以知道要看视频还是音频通道。

为了在我们的例子中找到本地地址,我们需要扩大conn-audio-1-0,并且注意googlocaladdress,其值为10.47.4.245:52740。

Wireshark中的RTP标记

现在,为了在我们的呼叫中方便地识别和提取所接收的视频流,我们已经收集了所有必要的信息。Wireshark可能会将捕获的RTP数据包简单地以UDP数据包来显示。我们想告诉Wireshark这些是RTP包,所以我们可以将其导出为rtpdump格式。

首先,使用地址和端口显示过滤器,例如ip.dst = = 10.47.4.245和udp.dstport = = 52740。然后,右击一个数据包,选择解码为,然后选择RTP。

其次,选择菜单电话→RTP →RTP流,列出列表中的所有RTP流。我们接收到的视频流中的SSRC连同其他流的一起列出来,选择并导出为rtpdump格式。(video_replay还支持PCAP格式,但由于其对各种链路层的支持非常有限,我一般推荐使用rtpdump。)最后我们有一个文件只包含接收的视频数据包,可以将其导入到video_replay中。

建立WebRTC 和 video_replay

使用之前,需要从WebRTC源码生成video_replay。如何设置环境、获取代码和编译等一般性的说明可以从https://webrtc.org/native-code/development中查到。注意,为了能生成video_replay工具,在编译时需要将其明确指定为一个目标。总之,在确定必要的软件已经安装了之后,下面的命令可以获得代码和生成video_replay:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1mkdir webrtc-checkout
2cd webrtc-checkout/
3fetch --nohooks webrtc
4gclient sync
5cd src
6gn gen out/Default
7ninja -C out/Default video_replay

使用video_replay重放捕捉信息

最后重播捕获的流,并希望之前它是如何在appr.tc中的状态可以准确地显示出来。我们的示例做到这一点的最小命令行是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1out/Default/video_replay -input_file received-video.rtpdump -codec VP9 -media_payload_type 98 -red_payload_type 102 -ssrc 4075734755

(注意:媒体payload_type参数之前命名为payload)

根据之前的说明, 命令行的参数也非常容易理解。

video_replay参数

如果你的目标是重现WebRTC出现问题后的bug,对于某些问题,将rtpdump连同命令行参数一起进行重放将有巨大的帮助。如果你想多做一些自己的video_replay调试,有几个命令行选项可能会很有用。

让我们看看当前的帮助文本并解释不同选项的作用。编写这一文件时,../../webrtc/video/replay.cc的标记有如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1-abs_send_time_id (RTP extension ID for abs-send-time) type: int32 default: -1
 2-codec (Video codec) type: string default: "VP8"
 3-decoder_bitstream_filename (Decoder bitstream output file) type: string default: ""
 4-fec_payload_type (ULPFEC payload type) type: int32 default: -1
 5-input_file (input file) type: string default: ""
 6-out_base (Basename (excluding .yuv) for raw output) type: string default: ""
 7-payload_type (Payload type) type: int32 default: 123
 8-payload_type_rtx (RTX payload type) type: int32 default: 98
 9-red_payload_type (RED payload type) type: int32 default: -1
10-ssrc (Incoming SSRC) type: uint64 default: 12648429
11-ssrc_rtx (Incoming RTX SSRC) type: uint64 default: 195939069
12-transmission_offset_id (RTP extension ID for transmission-offset) type: int32 default: -1

下面是关于它们的更多解释:

快捷方法

当你熟悉上面的过程时,你可以使用一些快捷方式来提高效率。首先,你可以使用Wireshark中查看RTP视频包而不必使用chrome://webrtc-internals。大多数视频包通常超过1000字节,而音频数据包一般也就几百字节。将解码的视频数据包使用RTP协议在Wireshark中处理,可以同时显示SSRC和有效载荷类型。Wireshark不能自动确定是RED有没有用,但是可以从经验中猜到,因为有效载荷类型一般不会在通话之间改变。

其次,如果你的video_replay支持pcap,你可以将原有pcap直接导入video_replay中。由于忽略了所有未知的数据包,命令行输出可能会有很多错误,但它可以解码并显示指定的流。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LiveVideoStack 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
技术解码丨Webtrc中RTCP使用及相关指标计算
在RFC3550中,除了定义了⽤来进⾏实时数据传输的 RTP 协议外,还定义了 RTCP 协议,⽤来反馈会话传输质量、⽤户源识别、控制 RTCP 传输间隔。在 Webrtc 中,通过 RTCP 我们可以实现发送数据/接收数据的反馈,传输控制如丢包重传、关键帧请求,⽹络指标 RTT、丢包率、抖动的计算及反馈,拥塞控制相关的带宽 反馈,以及⽤户体验相关的⾳视频同步等等。为了让开发者获取以上数据指标,Webrtc 提供了统⼀的接⼝调用,如在GoogleChrome中,可以通过 RTCPeerConnection
腾讯即时通信IM
2021/04/19
2.6K0
WebRTC中的RTP协议、RTCP协议、DSP协议
实时互动直播系统必须使用UDP作为数据传输的协议,为什么一定是UDP。TCP是一种可靠的传输协议,会保证在传输的过程中不丢包,UDP传输的速度快,但是不可靠,尤其是用户网络质量很差的情况下,会出现大量的丢包,基本无法保证音视频的服务质量。
码农帮派
2021/01/12
2.7K0
WebRTC中的RTP协议、RTCP协议、DSP协议
WebRTC架构图说明
网上也有很多资料说这张图在webRTC的官网上,但是很多童鞋根本就找不到。这是因为很多童鞋没有进行访问国外网站:WebRTC架构说明英文文档:https://webrtc.github.io/webrtc-org/architecture/
音视频开发进阶
2020/09/04
6.4K0
WebRTC架构图说明
WebRTC中的信令和内网穿透技术 STUN / TURN
Translated from WebRTC in the real world: STUN, TURN and signaling. 最近刚接触到WebRTC,网上看到这篇介绍WebRTC的文章不错,仔细读了读还算有用,分享出来能帮到一些刚入门的人也挺好的,翻译不好的地方可以直接看原文。
全栈程序员站长
2022/09/13
6.4K0
WebRTC中的信令和内网穿透技术 STUN / TURN
WebRTC技术概览
WebRTC(Web Real-Time Communication)是基于标准化技术的行业性项目,
呱牛笔记
2023/05/02
1.4K0
WebRTC技术概览
RTP协议与实战
在实时音视频通话中,我们通常使用 UDP 作为传输层协议,使用 RTP 协议包荷载音视频数据,RTP(Real-time Transport Protocol)是一种在 Internet 上传输多媒体数据的应用层协议,它通常建立在 UDP 之上(也可以建立在 TCP 上)。UDP 协议没有序号等信息,而 RTP 协议可以补充许多音视频传输必要的信息,让音视频数据到达对端后可以重新组合完整,RTP 本身只保证实时数据的传输,并不能提供可靠传输保证,也没有流量控制,拥塞控制机制,它通常与 RTCP 配合使用以提供这些服务。
全栈程序员站长
2022/09/13
1.5K0
RTP协议与实战
通过WebRTC进行实时通信-通过RTCPeerConnection传输视频
RTCPeerConnection 是调用WebRTC传输音视频和交换数据的API。这个例子是在同一个页面中两个RTCPeerConnection对象之间建立连接。没有什么实际价值,但却能很好的证明RTCPeerConnection是如何工作的。
音视频_李超
2020/04/02
5.7K0
SDP在RTSP、国标GB28181、WebRTC中的实践
注意的是SDP虽然具备这些能力参数信息的描述功能,但是SDP并不是传输协议,需要用RTSP、SIP、HTTP等协议进行承载传输、交换,如果大家协调好了之后,就可以建立会话,完成真实的音视频码流传输,再完成解码和播放。
潇湘落木
2020/11/12
2.2K0
SDP在RTSP、国标GB28181、WebRTC中的实践
在Google Chrome WebRTC中分层蛋糕式的VP9 SVC
作者 / Sergio Garcia Murillo,Gustavo Garcia
LiveVideoStack
2021/09/02
1.1K0
在Google Chrome WebRTC中分层蛋糕式的VP9 SVC
融云技术分享:基于WebRTC的实时音视频首帧显示时间优化实践
本文由融云技术团队原创投稿,作者是融云WebRTC高级工程师苏道,转载请注明出处。
JackJiang
2020/09/28
1.4K0
实时AV1 SVC——释放WebRTC的真正力量
原文链接 / http://webrtcbydralex.com/index.php/2021/01/29/real-time-av1-svc-unleashing-the-true-power-of-webrtc/
LiveVideoStack
2021/03/26
2.2K0
实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析
本文由ELab技术团队分享,原题“浅谈WebRTC技术原理与应用”,有修订和改动。
JackJiang
2022/01/10
1.9K0
实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析
快直播-基于WebRTC升级的低延时直播
随着直播行业的快速发展,直播带货秒杀和在线教育答题等应用场景对直播延时的要求越来越严苛。今天的技术解码就由费伟老师为大家带来腾讯云在快直播方面的一些分享! 随着直播行业的快速发展,特别是在今年疫情的影响下,各种低延时的直播场景得到了爆发性发展。最典型的应用就是直播带货秒杀和在线教育答题。这些应用场景的核心需求就是实时音视频互动,而传统直播技术基于HLS、FLV/RTMP协议具有秒级别的延时,高延时是制约互动效果的关键因素。快直播就是针对传统直播协议高延时的痛点,基于WebRTC技术实现毫秒级延
腾讯云音视频
2020/12/14
7K0
WebRTC 点对点直播
作者:villainthr WebRTC 全称为:Web Real-Time Communication。它是为了解决 Web 端无法捕获音视频的能力,并且提供了 peer-to-peer(就是浏览器
腾讯IVWEB团队
2017/03/13
10.5K0
不需要SFU实现WebRTC联播实践
https://webrtchacks.com/a-playground-for-simulcast-without-an-sfu/
LiveVideoStack
2021/09/01
8110
WebRTC的现状和未来(下)
可拓展视频编码(SVC)可以说是处理来自同一发送者的多个媒体流以处理组呼叫中每个接收者的不同条件的更好方法。在许多方面,它也被认为更复杂。Sergio&Gustavo对此主题发表了精彩的文章。
LiveVideoStack
2021/01/19
1.1K0
构建轻量级H.264 WebRTC堆栈
https://webrtchacks.com/what-i-learned-about-h-264-for-webrtc-video-tim-panton/
LiveVideoStack
2021/09/01
9730
WebRTC 入门指南
WebRTC (Web Real-Time Communications) 是由谷歌开源并推进纳入 W3C 标准的一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。WebRTC 包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建点对点(Peer-to-Peer)的数据分享和电话会议成为可能。
ihoey
2020/07/27
1.6K0
Web前端WebRTC攻略(三) 传输协议UDP/RTP/RTC
导语 | 音视频时代,WebRTC在形形色色的产品和业务场景下均有落地。在熟悉如何在浏览器获取设备的音视频数据和WebRTC是如何将获取的音视频数据进行网络传输的同时,我们更要夯实一下网络传输协议相关的基础知识,这能帮助我们更深入地学习WebRTC。推荐和前端音视频专题中的文章一起食用。 1. 传输层协议:TCP vs. UDP 我们都知道HTTP协议,运行于TCP协议之上,是万维网的运转的基础。作为一名前端开发,我们似乎理所应当熟悉HTTP、TCP协议,以致于HTTP状态码、报文结构、TCP三次握手、四次
用户1097444
2022/06/29
4K0
Web前端WebRTC攻略(三) 传输协议UDP/RTP/RTC
【OpenIM原创】简单轻松入门 一文讲解WebRTC实现1对1音视频通信原理
WebRTC(Web Real-Time Communication)是 Google于2010以6829万美元从 Global IP Solutions 公司购买,并于2011年将其开源,旨在建立一个互联网浏览器间的实时通信的平台,让 WebRTC技术成为 H5标准之一。我们看官网(https://webrtc.org)的介绍
OpenIM
2021/08/12
1.8K0
推荐阅读
相关推荐
技术解码丨Webtrc中RTCP使用及相关指标计算
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验