前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >video_replay如何捕获和回放WebRTC视频流

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

作者头像
LiveVideoStack
发布2021-09-02 11:18:54
1.6K0
发布2021-09-02 11:18:54
举报
文章被收录于专栏:音视频技术音视频技术

视频编码问题常常是最难解决的问题之一,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
复制
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
复制
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
复制
 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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档