HTML5 视频直播(三)

发表于 5年以前  | 总阅读数:2016 次

连续写了两篇有关视频直播的文章之后,有同学问我为什么没有 WebRTC 相关内容。实际上一开始我就说过,我的需求是在移动 WEB 端上直播视频,而移动端浏览器现阶段对「WebRTC 的支持度」非常不乐观,所以我就直接无视它了。但我一时为了标题美观,活生生地把「移动 WEB 端」写成了「HTML5」,所以为了严谨我还是补上这一篇吧。

WebRTC(Web Real-Time Communication),中文一般翻译为「Web 实时通信」。它由一组标准、协议和 JavaScript API 组成,用于实现端到端的音视频及数据共享。与其他浏览器通信机制不同,WebRTC 通过 UDP 传输数据,而我们早已熟知的 XMLHttpRequest、WebSocket 都基于 TCP。

纵观整个浏览器市场,其实只有 Google 和 Mozilla 两家公司对 WebRTC 比较上心,Firefox 22 和 Chrome 23 就开始就支持了它;Microsoft 是搞了自己的一套标准,后续可能会跟 WebRTC 融合,但至少 IE 不会支持现阶段的 WebRTC 标准;Apple 也许是因为有 FaceTime 可以很好地实现 Apple 设备间的多媒体通讯,压根就没打算在 Safari 中增加对 WebRTC 的支持;至于 Opera,换内核后基本等同于 Chrome,这下更要被人无视了。

初识 WebRTC

WebRTC 涉及到很多复杂技术,不过好在浏览器已经把大多数复杂工作抽象成为下面三个 API:

  • MediaStream:获取音频和视频流;
  • RTCPeerConnection:音频和视频数据通信;
  • RTCDataChannel:任意应用数据通信;

MediaStream 对应的是 JS 里的 navigator.getUserMedia() 方法,它负责从底层平台获取音视频流。音视频流经过 WebRTC 音视频引擎的自动优化、编码和解码,就可以直接用或传输到各种目的地用。这里有个 Demo,就是用 getUserMedia 获取视频流,再把每一帧都转成 ASCII 字符播放。总之 MediaStream API 设计得很简单,使用起来也很方便。

RTCPeerConnection 用来建立和维护端到端连接,并提供高效的音视频流传输。整个 WebRTC 提供的 API 中,要数这个最复杂:

首先,要建立端到端连接,不可避免要解决 NAT 穿透问题,RTCPeerConnection 为此引入了 ICE(Interactive Connectivity Establishment)框架。ICE 致力于在端之间建立一条有效的通道,优先直连,其次用 STUN 协商,再不行只能用 TURN 转发。

STUN(Session Traversal Utilities for NAT)协议,解决了三个问题:1)获得外网 IP 和端口;2)在 NAT 中建立路由条目,绑定外网端口,使得到达外网 IP 和端口的入站分组能找到应用程序,不被丢弃;3)定义了一个简单的 keep-alive 机制,保证 NAT 路由条目不会因为超时而被删除。STUN 服务器必须架设在公网上,可以自己搭建,也可以使用第三方提供的公开服务,例如 Google 的「stun:stun.l.google.com:19302」。

TURN(Traversal Using Relays around NAT)协议,依赖外网中继设备在两端之间传递数据。简单说就是通过两端都可以访问的 TURN 服务转发消息,间接把两端连起来。TURN 还会尝试使用 TCP 建立,而不仅仅是 UDP,可靠性大大增强,带宽成本也随着大幅提升。根据 Google 的统计,UDP 服务中,有 8% 左右的情况下需要 TURN。

其次,要建立端到端的信道,还是需要借助服务端来交换和协商一些信息,这个过程被称之为 Signaling。WebRTC 并没有规则 Signaling 必须使用某种协议,而把选择权交给了应用程序。我们可以选用不同方式(XMLHttpRequest、WebSocket),采用已有的 SIP、Jingle、ISUP 等发信协议,来建立信道。

通常,在 WebRTC 应用中,建立信道这一步都是优先走 WebSocket,并支持降级为 HTTP。一来支持 WebRTC 的浏览器肯定都支持 WebSocket;二来 WebSocket 实时性更好一些。特别需要注意的是,WebSocket 只用来辅助建立端到端连接,一旦连接建立,信源在端到端之间的传输就完全不需要服务端了(当然 TURN 这种中继模式就另当别论)。

RTCDataChannel 用来支持端到端的任意应用数据交换。建立 RTCPeerConnection 连接之后,除了可以传输音视频流,还可以打开一个或多个信道用来传输任何文本或二进制内容,这就是 RTCDataChanel。DataChannel API 在使用上跟 WebSocket 非常类似,功能上都可以用来在端到端之间传输数据,但是本质上他们还是有区别的:

首先,WebRTC 端与端之间是对等的,DataChannel 可以由任何一方发起;这与 WebSocket 连接只能由客户端发起不同; 其次,WebSocket 的会话层协议 TLS 是可选的;而 WebRTC 的会话层协议 DTLS 是必须的,这表明通过 WebRTC 传输的数据一定会被加密; 再者,WebSocket 运行在 TCP 之上,每条消息天然有序并可靠;而 DataChannel 可以通过 SCTP 的交付属性选项来指定消息是有序还是乱序,是可靠还是部分可靠,部分可靠时还可以指定使用超时重传还是计数重传策略。

现阶段 DataChannel 运行在下列协议之上:

  • SCTP(Stream Control Transmission Protocol),流控制传输协议,提供了一些与 TCP 类似的特性;
  • DTLS(Datagram Transport Layer Security),传输内容加密,UDP 版的 TLS;
  • UDP(User Datagram Protocol),用户数据报协议,整个 WebRTC 的基础;

这里我并不打算完整地介绍如何从零开始使用 WebRTC,类似的文章网上大把。这里推荐几篇文章,后几篇中文的出自同一个作者,写得比较通俗易懂:

  • Getting Started with WebRTC
  • 使用WebRTC搭建前端视频聊天室----入门篇
  • 使用WebRTC搭建前端视频聊天室----信令篇
  • WebRTC的RTCDataChannel
  • 使用WebRTC搭建前端视频聊天室----点对点通信篇
  • 使用WebRTC搭建前端视频聊天室----数据通道篇

另外还推荐《Web 性能权威指南》这本书,它的第 3 章「UDP 的构成」和第 18 章「WebRTC」对 UDP 内网穿透和 WebRTC 有比较详细的介绍。

一对多直播

前面说过,WebRTC 是用来解决端到端的实时通信问题,也就是说它很适合用在网络电话这种需要双向视频通话的场景上。网上大部分 WebRTC 的 Demo 也都是在页面上放两个 Video,分别来播 localStream 和 RemoteStream。那么究竟 WebRTC 能否用来实现单向一对多直播呢?当然可以,而且貌似还很简单:

  • 首先必须有一个专门负责调用 getUserMedia 采集音视频的页面,我称之为信源服务;
  • 打开直播页面时,建立到信源服务的 PeerConnection,并通过 DataChannel 通知信源服务;
  • 信源服务收到通知后,通过对应 PeerConnection 的 addStream 方法提供直播流;
  • 直播页面监听 PeerConnection 的 onaddstream 事件,将获得的直播流用丢给 Video 播放;

为了方便,我使用了 PeerJS 这个开源项目来验证上面这个过程。PeerJS 对 WebRTC Api 进行了封装,使用更简单。它还提供了用来辅助建立连接的 Signaling 服务,在官网注册一个 Api Key 就能用。也可以通过 PeerJS Server 搭建自己的服务,只需要通过 npm install peer 装好 peer 后,再通过下面这行命令启动就可以了:


peerjs --port 9000 --key peerjs

启动好 Peer Server,在页面中引入 peer.js 就可以开始玩了。首先实现信源服务:


//由于其它端都要连它,指定一个固定的 ID

    var peer = new Peer('Server', {
        host: 'qgy18.qgy18.com', 
        port: 9003, 
        path: '/',
        config: {
            'iceServers': [
                  { url: 'stun:stun.l.google.com:19302' }
            ]
        }
    });

    navigator.getUserMedia({ audio: false, video: true }, function(stream) {
        window.stream = stream;
    }, function() { /*...*/ });

    peer.on('connection', function(conn) {
        conn.on('data', function(clientId){
            var call = peer.call(clientId, window.stream);

            call.on('close', function() { /*...*/ });
        });
    });

然后就是直播服务:


//随机生成一个 ID

    var clientId = (+new Date).toString(36) + '_' + (Math.random().toString()).split('.')[1];

    var peer = new Peer(clientId, {
        host: 'qgy18.qgy18.com', 
        port: 9003, 
        path: '/',
        config: {
            'iceServers': [
                  { url: 'stun:stun.l.google.com:19302' }
            ]
        }
    });

    var conn = peer.connect('Server');

    conn.on('open', function() {
        conn.send(clientId);
    });

    peer.on('call', function(call) {
        call.answer();
        call.on('stream', function(remoteStream) {
            var video = document.getElementById('video');
            video.src = window.URL.createObjectURL(remoteStream);
        });

        call.on('close', function() { /*...*/ });
    });

直播页面通过指定 ID 的方式跟信源服务建立端到端连接,然后通过 DataChannel 告诉信源服务自己的 ID,信源服务收到消息后,主动把直播流发过来,直播页面应答后播放就可以了。整个过程原理就这么简单,这里有一个「完整的 Demo」。

看完上面的 Demo,你也许会想原来使用 WebRTC 直播这么简单,随便找台带摄像头的电脑,开个浏览器就能提供直播服务,那还搞 HLS、RTMP 什么的干嘛。

实际上,现实并没有那么美好,这个 Demo 也就玩玩儿还可以,真正使用起来问题还大着呢!

首先,虽然说在 WebRTC 直播方案中,服务端只扮演桥梁的工作,实际数据传输直接发生在端到端之间,但前面说过仍然会有 8% 的情况完全不能直连。要保证服务的高可用性,还是得考虑部署 TURN 这种复杂而昂贵的中转服务。

其次,Chrome 对每个 Tab 允许连接的终端数有限制,最多 256 个。实际上,在我最新的 Retina Macbook Pro 上,差不多有 10 个连接时,Chrome 就开始变得无比卡,风扇呼呼地转,内存被吃掉 6G,CPU 一直跑满,网络吞吐开始忙不过来,直播服务也开始变得极其不稳定。

所以实际使用方案中,一般还是需要 Media Server 的支持,把「端到多端」变成「端到 Media Server 到多端」的架构。Media Server 可以有更好的性能和带宽,可以自己实现 WebRTC 协议,也就有了支持更多用户的可能。

我找到一个名为 Janus 的 WebRTC Gateway,这个开源项目用 C 语言实现了对 WebRTC 的支持。Janus 自身实现得很简单,提供插件机制来支持不同的业务逻辑,配合官方自带插件就可以用来实现高效的 Media Server 服务。

Janus 官方提供的 Demo 在这里,我也尝试在我的 VPS 上部署了一套。Janus 有个 Streaming 插件,可以接受 GStreamer 推送的音视频流,然后通过 PeerConnection 推送给所有的用户。由于 GStreamer 可以直接读摄像头,也就不用再走 WebRTC 的 MediaStream 获取视频,这样架构就变成了传统的服务器到端了。整个过程比较复杂和曲折,这里不写了,有兴趣的同学可以单独找我讨论。

专题「好玩的 HTML5」的其他文章 »

  • 利用图片传输数据的另类思路 (Mar 10, 2016)
  • 像素化你的代码 (Sep 19, 2015)
  • HTML5 视频直播(二) (Apr 25, 2015)
  • HTML5 视频直播(一) (Apr 24, 2015)
  • 1.5kb 代码让图片抖起来 (Aug 11, 2014)
  • [彩蛋]这是什么? (Dec 13, 2012)
 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:8月以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:8月以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:8月以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:8月以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:8月以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:8月以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:8月以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:8月以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:8月以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:8月以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:8月以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:8月以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:8月以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:8月以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:8月以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:8月以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:8月以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:8月以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:8月以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:8月以前  |  398次阅读  |  详细内容 »
 相关文章
为Electron程序添加运行时日志 4年以前  |  19600次阅读
Node.js下通过配置host访问URL 5年以前  |  5632次阅读
用 esbuild 让你的构建压缩性能翻倍 4年以前  |  5368次阅读
 目录