65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 WebRTC 从 IP 摄像头广播视频流

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (15投票s)

2014年7月25日

MIT

12分钟阅读

viewsIcon

170823

本文描述了将新的 Web 实时通信技术和 IP 摄像头集成用于在线视频广播目的。部分多媒体,子部分音频和视频。

使用 WebRTC 从 IP 摄像头广播视频流

从技术上讲,IP 摄像头的在线广播并不需要 WebRTC。摄像头本身就可以连接到路由器并在网上发送视频内容。那么,我们为什么要使用 WebRTC 呢? 

至少有两个原因:

  1. 随着观看以太网广播的观众数量的增加,他们会逐渐感受到带宽和摄像头资源的不足,如果观众持续增长的话。
  2. 如上所述,IP 摄像头就是一个服务器。但它使用什么协议将视频传输到浏览器或移动设备呢?很可能,摄像头使用 HTTP 流,视频帧或 JPEG 图像通过 HTTP 传输。然而,HTTP 流并不适合实时视频流。它对于视频点播来说效果很好,在这种情况下,交互性和延迟并不关键。事实上,如果你在看电影,晚 5-10 秒收到内容并不重要。除非你同时和别人一起看。“哦,不!是杰克杀了她!” 爱丽丝在鲍勃看到悲惨结局前 10 秒钟写信告诉鲍勃。

另一种选择是 RTSP/RTP 加 H.264,但在这种情况下,浏览器必须安装视频播放器插件,如 VLC 或 QuickTime。这样的插件就像播放器一样接收和播放视频。但我们需要的是真正的基于浏览器的流媒体,没有任何额外的附加功能。

首先,让我们抓包分析我们的 IP 摄像头,了解它到底发送了什么给浏览器。我们测试的主体是 D-Link DCS 7010L。

您可以在下方详细了解如何安装和配置此摄像头,但现在我们只是检查它如何处理视频流。当我们登录到摄像头的管理面板时,在摄像头的 Web 界面中可以看到以下画面(抱歉是横屏)。

图像在所有浏览器中打开,并且大约每秒出现一次延迟。假设摄像头和笔记本电脑都连接到同一路由器,我们应该期望播放流畅,但事实并非如此。看来 HTTP 是原因。让我们运行 Wireshark 来证实我们的猜测。

在这里,我们可以看到一系列长度为 1514 字节的 TCP 分片。

以及一个包含接受的 JPEG 长度的 HTTP 200 OK 响应。

然后,我们打开 **Chrome / Developer Tools / Network**,并看到通过 HTTP 传输的实时 GET 请求和图像。

我们不想要这种流媒体。它不流畅;它会导致 HTTP 请求来回跳动。摄像头能处理多少这样的请求?我们推测,如果观众超过 10 个,摄像头就会宕机或变得非常卡顿和缓慢。

查看摄像头管理面板的 HTML 源代码,我们可以发现以下代码。

if(browser_IE)
  DW('<OBJECT CLASSID="CLSID:'+AxUuid+'" CODEBASE="/VDControl.CAB?'+AxVer+'#version='+AxVer+'" width="0" height="0" ></OBJECT>');
else
{
  if(mpMode == 1)
    var RTSPName = g_RTSPName1;
  else if(mpMode == 2)
    var RTSPName = g_RTSPName2;
  else if(mpMode == 3)
    var RTSPName = g_RTSPName3;
 
  var o='';
  
    if(g_isIPv6)
    //because ipv6 not support rtsp.
        var host = g_netip;
    else
        var host = g_host;
 
  o+='<object id="qtrtsp_object" width="0" height="0" codebase="http://www.apple.com/qtactivex/qtplugin.cab" ';
        o+='classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" type="video/quicktime">';
  o+='<param name="src" value="http://'+host+":"+g_Port+'/qt.mov" />';
  o+='<param name="autoplay" value="true" />';
  o+='<param name="controller" value="false" />';
  o+='<param name="qtsrc" value="rtsp://'+host+':'+g_RTSPPort+'/'+RTSPName+'"/>';
  o+='</object>';
  //alert(o);
  DW(o);
}

RTSP/RTP——这是我们需要流畅播放视频的内容。但这在浏览器中有效吗?不。或者,如果安装了 QuickTime 插件,它会起作用,但我们想要纯粹的浏览器流媒体。
 

另一个值得提及的选项是 Flash Player,它也可以通过 Wowza 将 RTMP 流转换为 RTSP、RTP、H.264。但 Flash Player 也是一个浏览器插件,尽管比 VLC 或 QuickTime 更受欢迎。

在我们的例子中,我们测试了相同的 RTSP/RTP 重定向,但我们使用了一个兼容 WebRTC 的浏览器作为播放器,没有任何额外的插件或其他设备。我们设置了一个重定向服务器,它将从 IP 摄像头获取视频流,并通过互联网将其广播给任意数量的用户,让他们在 WebRTC 浏览器中观看。

连接 IP 摄像头


如上所述,我们选择了一个非常简单的 D-Link DCS-7010L IP 摄像头。选择它的关键因素是支持 RTSP,因为服务器应该通过此协议从摄像头获取流。

我们用随附的网线将摄像头连接到路由器。摄像头已打开;它识别了路由器并使用 DHCP 获取了 IP 地址。在我们的例子中,它是 192.168.1.34(如果您打开路由器设置,可以看到一个已连接的设备 - DCS 7010L。就这样)。现在是时候测试摄像头了。

在浏览器中打开指定的 IP 地址 192.168.1.34,以进入摄像头的管理 Web 界面。密码默认为空。

正如您所见,摄像头中的视频在管理面板中播放效果很好。尽管如此,我们确实看到了周期性的卡顿。但这就是我们使用 WebRTC 要解决的问题。

 

配置摄像头

首先,我们禁用了身份验证。为了测试目的,我们允许任何人查看广播。为此,请输入 **Setup – Network**,并将 **Authentication** 设置为 **Disable**。

在同一部分,我们检查 RTSP 是否使用了正确的端口。默认端口是 554。输出视频的格式在配置文件中指定。您可以配置最多 3 个配置文件,但我们将使用第一个配置文件 - live1.sdp - 因为它已经配置为 H.264 视频和 G.711 音频。任何设置都可以稍后通过 **Setup – Audio and Video** 进行更改。

现在我们可以通过 RTSP 测试摄像头的操作。打开 VLC Player(或其他支持 RTSP 的播放器——QuickTime、Windows Media Player、RealPlayer 等),然后在“打开 URL”对话框中指定摄像头的 RTSP 地址。在我们的例子中,它是:rtsp://192.168.1.34/live1.sdp

好的,它工作正常。摄像头通过 RTSP 向播放器发送视频流。

顺便说一句,流播放非常流畅,完全没有伪影。我们可以对 WebRTC 抱有同样的期望。

安装服务器

因此,摄像头已安装,并通过桌面播放器进行了测试,并已准备好通过服务器进行广播。使用 whatismyip.com,我们确定了摄像头的外部 IP 地址。它是 178.51.142.223。现在我们需要告诉路由器将所有通过端口 554 发送的 RTSP 请求重定向到 IP 摄像头。

所以我们将相应的设置键入路由器...

...并使用 telnet 检查外部 IP 地址和 RTSP 端口。

telnet 178.51.142.223 554

在确保端口响应后,我们开始安装 WebRTC 服务器。

托管服务由 Amazon EC2 Centos 64 位服务器提供。为了降低性能问题的几率,我们选择了 m3.medium 实例,配有一个 VCPU。

image

当然,也有 Linode 和 DigitalOcean,但这次我们选择了 Amazon。我提前说,Amazon EC2 控制面板需要配置特定端口才能使此示例正常工作。这些是 WebRTC 流量(SRTP、RTCP、ICE)所需的端口以及 RTSP/RTP 流量的端口。如果您决定也进行测试,请确保 Amazon 的入站流量面板看起来像这样。

image

DigitalOcean 在这方面更简单,您只需在防火墙中关闭这些端口,或完全将其禁用。根据我们使用 DO 实例的经验,它们仍然提供静态 IP 并且不会干扰任何 NAT,因此在这里不需要像我们在 Amazon 上那样进行端口设置。

作为将 RTSP/RTP 流广播到 WebRTC 的服务器软件,我们使用了 Flashphoner 的 WebRTC 媒体和广播服务器。该流服务器看起来与 Wowza 非常相似,后者可以通过 Flash 广播 RTSP/RTP。唯一的区别是流实际上是通过 WebRTC 传输,而不是 Flash。从技术上讲,这意味着浏览器和服务器使用 DTLS 通信,建立 SRTP 会话,并将 VP8 编码的流传输给观众。

安装需要 SSH 访问。

剧透:执行命令的完整列表。

1. 下载服务器的安装包。
$wget flashphoner.com/downloads/builds/WCS/3.0/x8664/wcs3_video_vp8/FlashphonerMediaServerWebRTC-3.0/FlashphonerMediaServerWebRTC-3.0.868.tar.gz
2. 解压。
$tar -xzf FlashphonerMediaServerWebRTC-3.0.868.tar.gz
3. 安装。
$cd FlashphonerMediaServerWebRTC-3.0.868
$./install.sh
配置服务器的外部 IP 地址:54.186.112.111 和私有 IP:172.31.20.65。
4. 启动服务器。
$service webcallserver start
5. 检查日志。
$tail — f /usr/local/FlashphonerWebCallServer/logs/server_logs/flashphoner.log
6. 确保服务器正在运行。
$ps aux | grep Flashphoner
7. 安装并启动 Apache。
$yum install httpd
$service httpd start
8. 下载 Web 文件并将其放入 Apache 的默认文件夹 /var/www/html。
cd /var/www/html
$wget github.com/flashphoner/flashphoner_client/archive/wcs_media_client.zip
$unzip webrtc_media_client.zip
9. 在配置文件 flashphoner.xml 中输入服务器的 IP 地址。
10. 停止防火墙。
$service iptables stop

理论上,您应该在第 10 步中配置防火墙中的端口和规则,但为了测试目的,我们只是将其关闭了。

配置服务器

我们的 WebRTC 广播结构如下。

我们已经配置了此图的基本元素。现在我们需要配置“箭头”。

Web 客户端负责浏览器与 WebRTC 服务器之间的互连。可在 github 下载:客户端的 JS、CSS 和 HTML 文件在安装过程中上传到 **/var/www/html**(参见上面第 9 步)。

浏览器-服务器通信在 XML 文件 flashphoner.xml 中配置。我们应该在其中写入服务器的 IP 地址,以便 Web 客户端可以通过 HTML5 Websockets 连接到 WebRTC 服务器(参见第 9 步)。

好的,服务器配置完成了,让我们来测试一下。

在浏览器中打开 Web 客户端主页 index.html(我们需要在 Amazon 服务器上安装 Apache:**yum -y install httpd**)。

http://54.186.112.111/wcs_media_client/?id=rtsp://webrtc-ipcam.ddns.net/live1.sdp

**webrtc-ipcam.ddns.net**——是通过动态 DNS noip.com 获得的免费域名,它只是链接到我们的外部 IP 地址。此外,我们已指示路由器根据 NAT 地址转换规则重定向发送到 192.168.1.34 的 RTSP 请求(见上文)。

参数 **id=rtsp://webrtc-ipcam.ddns.net/live1.sdp** 设置要播放的流的 URL。WebRTC 服务器从 IP 摄像头获取流,处理它们,并通过 WebRTC 广播到浏览器。您的路由器可能支持 DDNS。如果不支持,您可以使用摄像头的选项。

这是 DDNS 在路由器中的支持显示。

image

现在是时候测试系统并查看结果了。

测试

打开浏览器中的链接后,它会连接到 WebRTC 服务器。服务器向 IP 摄像头发送请求以获取视频流。这个过程需要几秒钟。

image

浏览器通过 WebSocket 连接到服务器,然后服务器通过 RTSP 查询摄像头,通过 RTP 获取 H.264 流,将其转码为 VP8 / SRTP 格式,最终由兼容 WebRTC 的浏览器播放。

经过短暂延迟后,我们看到了熟悉的画面。

image

视频的下半部分显示了视频流的 URL。您可以复制它,在另一个浏览器或新标签页中打开。

确保它确实是 WebRTC

如果我们被欺骗了, IP 摄像头中的视频仍然通过 HTTP 传输怎么办?让我们不要仅仅相信图像,而是检查我们实际接收到的流量类型。再次运行 Wireshark 和 Chrome 调试控制台。在 Chrome 控制台中,我们可以看到以下内容:

image

这次没有进出流量,也没有通过 HTTP 传输图像。我们现在看到的是 WebSocket 帧,其中大部分是 ping/pong 类型,以保持 WebSocket 会话的活动。这里有趣的帧是:connect、prepareRtspSession 和 onReadyToPlay——与服务器的连接通过这些确切的阶段进行:首先是 WebSocket 连接,然后是播放请求。

这是 **chrome://webrtc-internals** 显示的内容:

根据图表,我们从 IP 摄像头的比特率为 1Mbps。还有出站流量,很可能是 RTCP 和 ICE 数据包。到 Amazon 服务器的 RTT 大约是 300 毫秒。

现在我们看一下 Wireshark。它清楚地显示了来自服务器 IP 地址的 UDP 流量。下图中的数据包为 1468 字节。这是 WebRTC。特别是,在浏览器中可以看到传输 VP8 视频帧的 SRTP 数据包。此外,我们还可以看到一些 STUN 请求(图片中最下面的数据包——这是 WebRTC ICE 在仔细检查连接)。

值得一提的是,视频播放的延迟相对较低(到数据中心的 ping 约为 260 毫秒)。WebRTC 通过 SRTP/UDP 工作,这是传输数据包最快的方式,与 HTTP、RTMP 和其他类 TCP 的流媒体方法相比。因此,可见延迟应该是 RTT + 缓冲时间、解码时间加上播放延迟。

肉眼看不出任何延迟,这意味着延迟低于 500 毫秒。

下一个测试是连接其他观众。我们打开了 10 个 Chrome 窗口,每个窗口都显示了画面。这导致 Chrome 本身变得迟钝。在另一台计算机上打开的第 11 个窗口中,播放仍然流畅。

WebRTC 在移动设备上

众所周知,Android 平台上的 Chrome 和 Firefox 浏览器也支持 WebRTC。让我们看看我们的广播在那里是否有效。

HTC 智能手机在 Firefox 中显示了来自 IP 摄像头的视频。与桌面相比,播放流畅度没有任何差异。

结论

结果,我们仅用最少的精力就成功实现了从 IP 摄像头到多个浏览器的 WebRTC 在线广播。一切都顺利进行,我们不需要“舞雨”或“巫毒”,也不需要“火箭科学”——只需要基本的 Linux 和 SSH 知识。

广播的质量完全可以接受,而且肉眼看不出延迟。

我们可以得出结论,基于浏览器的 WebRTC 广播绝对值得考虑,因为在我们的案例中,WebRTC 不是一个辅助的附加组件或插件,而是浏览器中播放视频的真正平台。

为什么我们没有普遍看到 WebRTC 的使用呢?

主要障碍可能是编解码器的缺乏。WebRTC 社区和供应商应该努力将 H.264 编解码器嵌入 WebRTC。我们对 VP8 没有意见,但为什么忽略数百万已经支持 H.264 的兼容设备和软件呢?那些该死的专利……

第二个原因是浏览器支持不完整。IE 和 Safari 上的问题仍然悬而未决,因此我们必须使用其他方式进行流媒体播放或使用像 webrtc4all 这样的插件。

未来,我们希望看到许多不需要转码的有趣解决方案,以及许多能够直接播放各种设备流的浏览器。

© . All rights reserved.