HTML5 直播协议之 WebSocket 和 MSE

当前为了满足比较火热的移动 Web 端直播需求, 一系列的 HTML5 直播技术迅速的发展了起来.

常见的可用于 HTML5 的直播技术有 HLS, WebSocket 与 WebRTC. 今天我要向大家介绍一下 WebSocket 与 MSE 相关的内容, 并在最后通过一个实际的例子, 来展示其具体的用法.

大纲

  • WebSocket 协议介绍.
  • WebSocket Client/Server API 介绍.
  • MSE 介绍.
  • fMP4 介绍.
  • Demo 展示.

WebSocket

通常的 Web 应用都是围绕着 HTTP 的请求/响应模型而构建的. 所有的 HTTP 通信都是通过客户端来控制的, 都是由客户端向服务器发出一个请求, 服务器接收和处理完毕后再返回结果给客户端, 客户端再将数据展现出来. 这种模式不能满足实时应用的需求, 于是出现了 SSE, Comet 等 “服务器推” 的长连接技术.

WebSocket 是直接基于 TCP 连接之上的通信协议, 可以在单个 TCP 连接上进行全双工的通信. WebSocket 在 2011 年被 IETF 定为标准 RFC 6455, 并被 RFC 7936 所补充规范, WebSocket API 被 W3C 定为标准.

WebSocket 是独立的创建在 TCP 上的协议, HTTP 协议中的那些概念都不复存在, 和 HTTP 的唯一关联是使用 HTTP 协议的 101 状态码进行协议切换, 使用的 TCP 端口是 80, 可以用于绕过大多数防火墙的限制.

WebSocket 握手

为了更方便地部署新协议,HTTP/1.1 引入了 Upgrade 机制, 它使得客户端和服务端之间可以借助已有的 HTTP 语法升级到其它协议. 这个机制在 RFC7230 的 6.7 Upgrade ) 一节中有详细描述.

要发起 HTTP/1.1 协议升级,客户端必须在请求头部中指定这两个字段:

Connection: Upgrade
Upgrade: protocol-name[/protocol-version]

如果服务端同意升级, 那么需要这样响应:

HTTP/1.1 101 Switching Protocols
Connection: upgrade
Upgrade: protocol-name[/protocol-version]

[... data defined by new protocol ...]

可以看到, HTTP Upgrade 响应的状态码是 101 , 并且响应正文可以使用新协议定义的数据格式.

WebSocket 握手就利用了这种 HTTP Upgrade 机制. 一旦握手完成,后续数据传输就直接在 TCP 上完成.

WebSocket JavaScript API

目前主流的浏览器提供了 WebSocket 的 API 接口, 可以发送消息(文本或者二进制)给服务器, 并且接收事件驱动的响应数据.

Step1 检查浏览器是否支持 WebSocket.

if(window.WebSocket) {
	// WebSocket代码
}

Step2 建立连接

var ws = new WebSocket('ws://localhost:8327');

Step3 注册回调函数以及收发数据

分别注册 WebSocket 对象的 onopen, onclose, onerror 以及 onmessage 回调函数.

通过 ws.send() 来进行发送数据, 这里不仅可以发送字符串, 也可以发送 Blob 或 ArrayBuffer 类型的数据.

如果接收的是二进制数据,需要将连接对象的格式设为 blob 或 arraybuffer.

ws.binaryType = 'arraybuffer';

WebSocket Golang API

服务器端 WebSocket 库我推荐使用 Google 自己的 golang.org/x/net/websocket , 可以非常方便的与 net/http 一起使用.

可以将 websocket 的 handler function 通过 websocket.Handler 转换成 http.Handler , 这样就可以跟 net/http 库一起使用了.

然后通过 websocket.Message.Receive 来接收数据, 通过 websocket.Message.Send 来发送数据.

具体代码可以看下面的 Demo 部分.

MSE

在介绍 MSE 之前, 我们先看看 HTML5 <audio> 和 <video> 有哪些限制.

HTML5

标签的限制

  • 不支持流.
  • 不支持 DRM 和加密.
  • 很难自定义控制, 以及保持跨浏览器的一致性.
  • 编解码和封装在不同浏览器支持不同.

MSE 是解决 HTML5 的流问题.

Media Source Extensions (MSE) 是一个主流浏览器支持的新的 Web API. MSE 是一个 W3C 标准, 允许 JavaScript 动态的构建 <video> 和 <audio> 的媒体流. 他定义了对象, 允许 JavaScript 传输媒体流片段到一个 HTMLMediaElement.

通过使用 MSE, 你可以动态地修改媒体流而不需要任何的插件. 这让前端 JavaScript 可以做更多的事情, 我们可以在 JavaScript 进行转封装, 处理, 甚至转码.

虽然 MSE 不能让流直接传输到 media tags 上, 但是 MSE 提供了构建跨浏览器播放器的核心技术, 让浏览器通过 JavaScript API 来推音视频到 media tags 上.

现在每个客户端平台都开始逐步开放流媒体相关的 API: Flash 平台有 Netstream, Android 平台有 Media Codec API, 而 Web 上对应的就是标准的 MSE. 由此可以看出, 未来的趋势是在客户端可以做越来越多的事情.

Browser Support

通过 caniuse 来检查是否浏览器支持情况.

通过 MediaSource.isTypeSupported() 可以进一步地检查 codec MIME 类型是否支持.

比较常用的视频封装格式有 webm 和 fMP4.

WebM 和 WebP 是两个姊妹项目, 都是由 Google 赞助的. 由于 WebM 是基于 Matroska 的容器格式, 所以天生是流式的, 很适合用在流媒体领域里.

下面着重介绍一些 fMP4 格式.

我们都知道 MP4 是由一系列的 Boxes 组成的. 普通的 MP4 的是嵌套结构的, 客户端必须要从头加载一个 MP4 文件, 才能够完整播放, 不能从中间一段开始播放.

而 fMP4 由一系列的片段组成, 如果你的服务器支持 byte-range 请求, 那么, 这些片段可以独立的进行请求到客户端进行播放, 而不需要加载整个文件.

为了更加形象的说明这一点, 下面我介绍几个常用的分析 MP4 文件的工具.

  • gpac 原名 mp4box, 是一个媒体开发框架, 在其源码下有大量的媒体分析工具可以使用, testapps
  • mp4box.js 是 mp4box 的 Javascript 版本.
  • bento4 一个专门用于 MP4 的分析工具.
  • mp4parser 在线 MP4 文件分析工具.

fragment mp4 vs non-fragment mp4

下面一个 fragment mp4 文件通过 mp4parser 分析后的截图

下面一个 non-fragment mp4 文件通过 mp4parser 分析后的截图

Apple 在今年的 WWDC 大会上宣布会在 iOS 10, tvOS, macOS 的 HLS 中支持 fMP4.

值得一提的是, fMP4, CMAF, ISOBMFF 其实都是类似的东西.

MSE JavaScript API

从高层次上看, MSE 提供了 * 一套 JavaScript API 来构建 media streams. * 一个拼接和缓存模型. * 识别一些 byte 流类型: * WebM * ISO Base Media File Format * MPEG-2 Transport Streams

MSE 内部结构

MSE 本身的设计是不依赖任务特定的编解码和容器格式的, 但是不同的浏览器支持程度是不一样的. 可以通过传递一个 MIME 类型的字符串到静态方法: MediaSource.isTypeSupported 来检查.

比如:

MediaSource.isTypeSupported('audio/mp3'); // false
MediaSource.isTypeSupported('video/mp4'); // true
MediaSource.isTypeSupported('video/mp4; codecs="avc1.4D4028, mp4a.40.2"'); // true

获取 Codec MIME string 的方法可以通过在线的 mp4info 或者使用命令行 mp4info test.mp4 | grep Codecs

可以得到类似如下结果:

 mp4info fmp4.mp4| grep Codec
    Codecs String: mp4a.40.2
    Codecs String: avc1.42E01E

当前, H.264 + AAC 的 MP4 容器在所有的浏览器都支持.

普通的 MP4 文件是不能和 MSE 一起使用的, 需要将 MP4 进行 fragment 化.

检查一个 MP4 是否已经 fragment 的方法

mp4dump test.mp4 | grep "\[m"

如果是 non-fragment 会显示类似信息.

 mp4dump nfmp4.mp4 | grep "\[m"
[mdat] size=8+50873
[moov] size=8+7804
  [mvhd] size=12+96
    [mdia] size=8+3335
      [mdhd] size=12+20
      [minf] size=8+3250
    [mdia] size=8+3975
      [mdhd] size=12+20
      [minf] size=8+3890
            [mp4a] size=8+82
    [meta] size=12+78

如果已经 fragment, 会显示如下类似信息.

 mp4dump fmp4.mp4 | grep "\[m" | head -n 30
[moov] size=8+1871
  [mvhd] size=12+96
    [mdia] size=8+312
      [mdhd] size=12+20
      [minf] size=8+219
            [mp4a] size=8+67
    [mdia] size=8+371
      [mdhd] size=12+20
      [minf] size=8+278
    [mdia] size=8+248
      [mdhd] size=12+20
      [minf] size=8+156
    [mdia] size=8+248
      [mdhd] size=12+20
      [minf] size=8+156
  [mvex] size=8+144
    [mehd] size=12+4
[moof] size=8+600
  [mfhd] size=12+4
[mdat] size=8+138679
[moof] size=8+536
  [mfhd] size=12+4
[mdat] size=8+24490
[moof] size=8+592
  [mfhd] size=12+4
[mdat] size=8+14444
[moof] size=8+312
  [mfhd] size=12+4
[mdat] size=8+1840
[moof] size=8+600

把一个 non-fragment MP4 转换成 fragment MP4.

可以使用 FFmpeg 的 -movflags 来转换

对于原始文件为非 MP4 文件

ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy -movflags frag_keyframe+empty_moov bunny_fragmented.mp4

对于原始文件已经是 MP4 文件

ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov fragmented.mp4

或者使用 mp4fragment

mp4fragment input.mp4 output.mp4

demo

  • MSE Vod Demo 展示利用 MSE 和 WebSocket 实现一个点播服务.
  • MSE Live Demo 展示利用 MSE 和 WebSocket 实现一个直播服务.

MSE VOD Demo

Your browser does not support the video tag.

MSE Live Demo

Your browser does not support the video tag.

Refs

WebSocket

 

来自:http://akagi201.org/post/websocket-mse/

时间: 2024-10-26 06:07:21

HTML5 直播协议之 WebSocket 和 MSE的相关文章

RTMP HLS HTTP 直播协议一次看个够

直播从2016年一路火到了2017年,如今要在自己的App里加入直播功能,只要找一个现成的SDK就行了,什么拍摄.美颜.推流,一条龙服务.不过作为直播身后最重要的部分:推流协议,很多人并不是很清楚.如果你也对直播感兴趣,想要了解他背后的各种机制,可以先从这篇文章中了解一下推流协议开始. 单纯从技术角度来看,能够实现直播功能协议中,比较常用的是RTMP HLS HTTP这种技术.但具体到应用场景,他们又会有一些不同的选择. RTMP Real Time Messaging Protocol实时消息

消息称微软与服务提供商签电视直播协议

[赛迪网讯]9月20日消息,据国外媒体报道,微软正在与至少两家以上的服务提供商就通过微软Xbox Live为电视直播服务的协议进行谈判.参与谈判的服务提供商包括Comcast和Verizon,这两家服务商都通过FiOS光纤系统提供电视服务. 有消息称,这些交易协议或将在1个月内达成.有了这项服务之后,用户就不再需要安装独立机顶盒.此外,用户不仅可以通过必应搜索找到需要的节目,而且可以使用Kinect控制器来处理和播放节目. 据消息人士透露,在英国,微软已经与英国天空广播公司(BSkyB)达成了类

苹果将首次采用HTML5直播发布会

苹果今天宣布,将第一次采用HTML5内置的HTTP Live流媒体视频直播最新音乐产品发布会,这意味着可以用苹果iOS 3以上版本和Mac OS X Snow Leopard观看(当然所有支持HTML5的浏览器均可),发布会开始时间为美东部时间下午一点,Apple.com将全程直播.   本次发布会直播是一次HTML5大负荷流媒体承载能力的一次练兵,用户不需要安装任何插件即可以观看.苹果一直对HTML5持支持态度,以至于让Adobe的流媒体方案至今无法进入其移动设备. 声明:CSDN登载此文出于

Python实现同时兼容老版和新版Socket协议的一个简单WebSocket服务器_python

最近在做的一个项目中需要使用到HTML5中引入的WebSocket技术,本来以为应该很容易就能搞定,谁知道在真正上手开发了以后才发现有很多麻烦的地方,虽然我们是一个以前端开发和设计见长的团队,而且作为一个二手程序猿又长期不被待见,但是为了让有同样需求的朋友少走些弯路,我还是决定把实现方法贴在这个地方. 关于WebSocket的基本概念,维基百科上解释的很清楚,而且网上也能搜出来一大把,这里就略过不表,直接进入正题. 这次的问题首先有一个前提,就是得用Python来实现这个服务器,如果对具体语言没

HTML5 学习总结(五)——WebSocket与消息推送

B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不需要与客户端长时间建立一个通信链接,但不容易直接完成实时的消息推送功能,如聊天室.后台信息提示.实时更新数据等功能,但通过polling.Long polling.长连接.Flash Socket以及HTML5中定义的WebSocket能完成该功能需要. 一.Socket简介 Socket又称"套接字",应用程序通常通过

websocket实现握手协议

问题描述 websocket实现握手协议 在websocket握手协议中是所有的客户端都可以访问服务器吗?如果不是该怎么给他添加限制条件呀! 解决方案 是的所有的客户端都可以访问服务器 如果你需要限制某些用户,就加一个登录过程 解决方案二: 客户端和服务器都要支持websocket协议才行.比如tomcat7开始才支持websocket协议. 解决方案三: 怎么只加一个登录过程呀!origin跟的后面是什么呢?

WebSocket协议

一个WebSocket的简单Echo例子:例子代码来自:http://www.websocket.org/echo.html 使用一个文本编辑器,把下面代码复制保存在一个 websocket.html 文件中,然后只要在浏览器中打开它,页面就会使用 websocket 自动连接,发送一个消息,显示接受到的服务器响应,然后关闭连接. <!DOCTYPE html>   <meta charset="utf-8" />   <title>WebSocke

关于UCloud直播云所有技术细节都在这里了(二)

上篇我们讲述了如何让直播内容以"最短"路径从主播到观众上,传输层面获得最低延迟,在本篇中我们会介绍直播应用层协议及传输层协议的选择以及对直播体验影响的分析 . 直播协议选择 国内常见公开的直播协议有几个:RTMP.HLS.HDL(HTTP-FLV).RTP,我们来逐一介绍. RTMP协议:是Adobe的专利协议,现在大部分国外的CDN已不支持.在国内流行度很高.原因有几个方面:1.开源软件和开源库的支持稳定完整.如斗鱼主播常用的OBS软件,开源的librtmp库,服务端有nginx-r

直播未来属于RTMP还是HTTP?

直播未来属于RTMP还是HTTP? HTTP 传视频比 RTMP 实现起来简单?HTTP 延迟太高? 答:直播通讯未来是属于html5的.   1,协议使用份额 如今国内90%的面向大众的直播平台都是采用的rtmp和httpflv的混合,hls很少,而国外大部分采用的dash,少部分用hls和其他协议. 2,先简单的描述下这些协议 httpflv:这种直播传输实际上就是利用的flv文件的特点,只需要一个matedata和音视频各自header,后面的音视频数据就可以随意按照时间戳传输,当然视频得