WebSocket+MSE——HTML5 直播技术解析

作者 | 刘博(又拍云多媒体开发工程师)

当前为了满足比较火热的移动 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 协议中的那些概念都和 WebSocket 没有关联,唯一关联的是使用 HTTP 协议的 101 状态码进行协议切换时,使用的 TCP 端口是 80,可以绕过大多数防火墙的限制。

WebSocket+MSE——HTML5 直播技术解析

WebSocket 握手

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

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

> Connection: UpgradeUpgrade: protocol-name[/protocol-version]

登录后复制

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

> HTTP/1.1 101 Switching ProtocolsConnection: upgradeUpgrade: 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 自己的 http://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和

HTML5 和

不支持流

不支持 DRM 和加密

很难自定义控制, 以及保持跨浏览器的一致性

编解码和封装在不同浏览器支持不同

MSE 是解决 HTML5 的流问题。

Media Source Extensions(MSE)是 Chrome、Safari、Edge 等主流浏览器支持的一个新的Web API。MSE 是一个 W3C 标准,允许 JavaScript 动态构建

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

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

Browser Support

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

WebSocket+MSE——HTML5 直播技术解析

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

fMP4

比较常用的视频封装格式有 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(Online MPEG4 Parser )分析后的截图 ▽

WebSocket+MSE——HTML5 直播技术解析

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

WebSocket+MSE——HTML5 直播技术解析

我们可以看到 non-fragment mp4 的最顶层 box 类型非常少,而 fragment mp4 是由一段一段的 moof+mdat 组成的,它们已经包含了足够的 metadata 信息与数据, 可以直接 seek 到这个位置开始播放。也就是说 fMP4 是一个流式的封装格式,这样更适合在网络中进行流式传输,而不需要依赖文件头的metadata。

Apple在WWDC 2016 大会上宣布会在 iOS 10、tvOS、macO S的 HLS 中支持 fMP4,可见fMP4 的前景非常的好。

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

MSE JavaScript API

从高层次上看,MSE 提供了

一套 JavaScript API 来构建 media streams

一个拼接和缓存模型

识别一些 byte 流类型

WebM

ISO Base Media File Format

MPEG-2 Transport Streams

MSE 内部结构

WebSocket+MSE——HTML5 直播技术解析

MSE 本身的设计是不依赖任务特定的编解码和容器格式的,但是不同的浏览器支持程度是不一样的。

可以通过传递一个 MIME 类型的字符串到静态方法:

> MediaSource.isTypeSupported来检查。比如 ▽MediaSource.isTypeSupported('audio/mp3'); // falseMediaSource.isTypeSupported('video/mp4'); // trueMediaSource.isTypeSupported('video/mp4; codecs="avc1.4D4028, mp4a.40.2"'); // true

登录后复制

获取 Codec MIME string 的方法可以通过在线的 [mp4info](http://nickdesaulniers.github.io/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 TIME

最后阶段,展示两个demo,分别是 MSE Vod Demo、MSE Live Demo

MSE Vod Demo

展示利用 MSE 和 WebSocket 实现一个点播服务

后端读取一个 fMP4 文件,通过 WebSocket 发送给 MSE,进行播放

WebSocket+MSE——HTML5 直播技术解析

展示利用 MSE 和 WebSocket 实现一个直播服务

后端代理一条 HTTP-FLV 直播流,通过 WebSocket 发送给 MSE,进行播放

前端 MSE 部分做了很多工作, 包括将 flv 实时转封装成了 fMP4,这里引用了 videojs-flow 的实现

Refs

WebSocket

rfc6455

HTTP Upgrade

WebSocket API

MDN WebSocket

videojs-flow

MSE

W3C

MDN MSE

HTML5 Codec MIME

又拍直播云是基于又拍云内容分发网络为直播应用提供超低延迟、高码率、高并发的整套从推流端到播放端的一站式解决方案。包括实时转码,实时录制,分发加速,水印,截图,秒级禁播,延时直播等功能。直播源站支持自主源站或又拍云源,为支持用户在不同终端播放,支持 RTMP、HLS、HTTP-flv 播放输出。

详情了解:https://www.upyun.com/products/live

推荐阅读:

无连麦,不直播,都在说的直播利器连麦互动到底是啥?
技术干货|移动直播六大关键技术详解
又拍直播云SDK,自带美颜、滤镜、消噪、人声增益等功能
又拍直播云功能处理篇:转码、录制、视频水印、视频截图
又拍直播云功能基础篇:推流和拉流、多协议输出、多访问方式、回源端口自定义
又拍直播云功能高级篇:防盗链、秒级禁播、自动鉴黄、API接口

以上就是WebSocket+MSE——HTML5 直播技术解析的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2910896.html

(0)
上一篇 2025年3月11日 04:37:07
下一篇 2025年3月11日 04:37:24

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • WEB前端规范命名的介绍

    头部 header —————-用于头部主要内容 main ————用于主体内容(中部)左侧 main-left —&#…

    编程技术 2025年3月11日
    200
  • Html5语义化标签及兼容性处理详解

    页眉 主要用于页面的头部的信息介绍,也可用于板块头部 页面上的一个标题组合 一个标题和一个子标题,或者标语的组合 妙味课堂 带您进入富有人情味的IT培训 立即学习“前端免费学习笔记(深入)”; 导航 (包含链接的的一个列表) 链接链接 妙味…

    编程技术 2025年3月11日
    200
  • 利用JSSDK在网页中获取地理位置

    复制一份jssdk环境,创建一份index.html文件,结构如图7.1所示。   图7.1  7.1节文件结构 在location.js中,封装“getLocation”接口,如下:   01wxJSSDK.location = func…

    2025年3月11日 编程技术
    200
  • HTML5盒子模型的使用方法

    盒子模型。 盒子由 margin、border、padding、content 四部分组成。 margin :外边距 立即学习“前端免费学习笔记(深入)”;   border:边框   padding:内边距 (内容与边框的距离)   co…

    2025年3月11日 编程技术
    200
  • 零基础学习HTML5

    1个html5基础入门教程,4个html5小项目教程,带你零基础入门学习html5。 【HTML5基础入门】 教程将会介绍HTML5中的新特性,包括结构标签、新型表单标签、文件操作、Canvas、本地存储等。适合对前端编程有兴趣,已经学了H…

    2025年3月11日 编程技术
    200
  • vue全分析–Vue+Vue-router+Vuex+axios

    vue有多优秀搭配全家桶做项目有多好之类的咱就不谈了,直奔主题。 一、Vue   系列一已经用vue-cli搭建了Vue项目,此处就不赘述了。 二、Vue-router   Vue的路由,先献上文档()。 立即学习“前端免费学习笔记(深入)…

    2025年3月11日 编程技术
    200
  • h5之scrollIntoView用法详解

      如果滚动页面也是dom没有解决的一个问题。为了解决这个问题,浏览器实现了一下方法,以方便开发人员如何更好的控制页面的滚动。在各种专有方法中,html5选择了scrollintoview()作为标准方法。scrollintoview()可…

    2025年3月11日
    200
  • ios加载html5 audio标签时遇到的问题分享

    html5 audio标签在ios 微信浏览器中是无法自动播放的,最近在做一个小的项目遇到这个问题,安卓和pc都是正常的,唯独ios不行,查阅了很多资料,找到了以下方法,也许不是最好用的方法,如果有更方便的方法,尽请留言: html部分: …

    编程技术 2025年3月11日
    200
  • h5实现QQ聊天气泡的实例介绍

    这篇文章主要介绍了html5实现qq聊天气泡效果,用 html/css 做了个类似qq的聊天气泡,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 今天自己用 HTML/CSS 做了个类似QQ的聊天气泡,以下是效果图: 以下说下关键地方的样…

    2025年3月11日 编程技术
    200
  • HTML5 canvas学习的实例介绍

    1.html5中的canvas标签的创建 window.onload = function(){ createCanvas(); } function createCanvas(){ var canvas_width= 200, canva…

    编程技术 2025年3月11日
    200

发表回复

登录后才能评论