Heim >Web-Frontend >H5-Tutorial >WebSocket+MSE – Analyse der HTML5-Live-Broadcast-Technologie

WebSocket+MSE – Analyse der HTML5-Live-Broadcast-Technologie

巴扎黑
巴扎黑Original
2017-06-23 14:45:594370Durchsuche

Autor |. Liu Bo (ebenfalls Paiyun Multimedia Development Engineer)

Um der relativ großen Nachfrage nach mobilen Web-Live-Übertragungen gerecht zu werden, wurde derzeit schnell eine Reihe von HTML5-Live-Übertragungstechnologien entwickelt.

Zu den gängigen Live-Streaming-Technologien, die mit HTML5 verwendet werden können, gehören HLS, WebSocket und WebRTC. Heute werde ich Ihnen die technischen Punkte im Zusammenhang mit WebSocket und MSE vorstellen und abschließend die spezifische Verwendung anhand eines Beispiels demonstrieren.

Artikelübersicht

  • Einführung in das WebSocket-Protokoll

  • Einführung in die WebSocket-Client/Server-API

  • MSE-Einführung

  • fMP4-Einführung

  • Demo-Anzeige

WebSocket

Übliche Webanwendungen basieren auf dem HTTP-Anfrage-/Antwortmodell. Die gesamte HTTP-Kommunikation wird über den Client gesteuert. Der Client sendet eine Anfrage an den Server. Nachdem der Server sie empfangen und verarbeitet hat, sendet er das Ergebnis an den Client zurück und der Client zeigt die Daten an. Da dieser Modus die Anforderungen von Echtzeitanwendungen nicht erfüllen kann, sind „Server-Pushing“-Technologien für lange Verbindungen wie SSE und Comet entstanden.

WebSocket ist ein Kommunikationsprotokoll, das auf einer TCP-Verbindung basiert und eine Vollduplex-Kommunikation über eine einzelne TCP-Verbindung durchführen kann. WebSocket wurde 2011 von der IETF als Standard RFC 6455 festgelegt und durch RFC 7936 ergänzt. Die WebSocket-API wurde vom W3C als Standard festgelegt.

WebSocket ist ein unabhängig von TCP erstelltes Protokoll. Die einzige Korrelation besteht darin, dass bei Verwendung des 101-Statuscodes des HTTP-Protokolls der verwendete TCP-Port verwendet wird ist 80, wodurch die meisten Firewall-Einschränkungen umgangen werden können.

WebSocket Handshake

Um neue Protokolle bequemer bereitzustellen, führt HTTP/1.1 den Upgrade-Mechanismus ein, der es Client und Server ermöglicht, vorhandenes HTTP zu verwenden Die Syntax wurde auf andere Protokolle aktualisiert. Dieser Mechanismus wird ausführlich in RFC7230, Abschnitt 6.7 Upgrade beschrieben.

Um ein HTTP/1.1-Protokoll-Upgrade zu initiieren, muss der Client diese beiden Felder im Anforderungsheader angeben ▽

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

Wenn der Server dem Upgrade zustimmt , dann müssen Sie wie folgt antworten ▽

> HTTP/1.1 101 Switching Protocols
Connection: upgrade
Upgrade: protocol-name[/protocol-version]
[... data defined by new protocol ...]

Wie Sie sehen können, lautet der Statuscode der HTTP-Upgrade-Antwort 101 und der Antworttext kann über das neue Protokoll Datenformat definiert werden.

WebSocket-Handshake nutzt diesen HTTP-Upgrade-Mechanismus. Sobald der Handshake abgeschlossen ist, erfolgt die anschließende Datenübertragung direkt über TCP.

WebSocket-JavaScript-API

Derzeit bieten gängige Browser eine WebSocket-API-Schnittstelle, die Nachrichten (Text oder Binär) an den Server senden und ereignisgesteuerte Antwortdaten empfangen kann.

Schritt 1. Prüfen Sie, ob der Browser WebSocket unterstützt

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

Schritt 2 🎜 >

Schritt 3. Registrieren Sie die Rückruffunktionen und senden und empfangen Sie Daten
> var ws = new WebSocket('ws://localhost:8327');
Registrieren Sie die Rückruffunktionen onopen, onclose, onerror und onmessage des WebSocket-Objekts.

Daten über ws.send() senden. Hier können nicht nur Zeichenfolgen, sondern auch Daten vom Typ Blob oder ArrayBuffer gesendet werden.

Wenn Binärdaten empfangen werden, muss das Format des Verbindungsobjekts auf Blob oder Arraybuffer eingestellt werden.

WebSocket Golang API
ws.binaryType = 'arraybuffer';

Für die serverseitige WebSocket-Bibliothek empfehle ich die Verwendung von Googles eigenem , das ist sehr praktisch. Wird mit net/http verwendet. Sie können die Handlerfunktion von WebSocket auch über websocket.Handler in http.Handler konvertieren, sodass sie mit der net/http-Bibliothek verwendet werden kann.

Empfangen Sie dann Daten über websocket.Message.Receive und senden Sie Daten über websocket.Message.Send.

Den spezifischen Code finden Sie im Demo-Bereich unten.

MSE

Bevor wir MSE einführen, schauen wir uns zunächst die Einschränkungen von HTML5b97864c2e0ef2353a16c4d64c7734e92 an.

Einschränkungen für HTML54218491fec31d29458f32c3ffee1002b-Tags

  • Streaming wird nicht unterstützt

  • DRM und Verschlüsselung sind nicht unterstützt

  • Steuerelemente lassen sich nur schwer anpassen und die browserübergreifende Konsistenz beibehalten

  • Codierungs- und Kapselungsunterstützung ist in verschiedenen Browsern unterschiedlich

MSE löst das Streaming-Problem von HTML5.

Media Source Extensions (MSE) ist eine neue Web-API, die von gängigen Browsern wie Chrome, Safari und Edge unterstützt wird. MSE ist ein W3C-Standard, der es JavaScript ermöglicht, Medienströme für e26e9bceaa3cecafde05584c3fef9fba dynamisch zu erstellen. Es definiert Objekte, die es JavaScript ermöglichen, Medienstream-Fragmente an ein HTMLMediaElement zu übertragen.

Durch die Verwendung von MSE können Sie Medienströme dynamisch ändern, ohne dass Plugins erforderlich sind. Dadurch kann Front-End-JavaScript mehr tun – Neupacken, Verarbeiten und sogar Transkodieren in JavaScript.

Obwohl MSE Streams nicht direkt an Medien-Tags übertragen kann, stellt MSE die Kerntechnologie für die Erstellung browserübergreifender Player bereit, die es Browsern ermöglicht, Audio und Video über JavaScript-APIs an Medien-Tags zu übertragen.

Browser-Unterstützung

Überprüfen Sie mit caniuse, ob Browser-Unterstützung verfügbar ist.

Sie können weiter überprüfen, ob der Codec-MIME-Typ über MediaSource.isTypeSupported() unterstützt wird.

fMP4

Die am häufigsten verwendeten Videokapselungsformate sind WebM und fMP4.

WebM und WebP sind zwei Schwesterprojekte, die beide von Google gesponsert werden. Da WebM ein auf Matroska basierendes Containerformat ist, ist es von Natur aus Streaming und eignet sich sehr gut für den Einsatz im Bereich Streaming Media.

Im Folgenden liegt der Schwerpunkt auf dem fMP4-Format.

Wir alle wissen, dass MP4 aus einer Reihe von Boxen besteht. Gewöhnliches MP4 hat eine verschachtelte Struktur. Der Client muss eine MP4-Datei von Anfang an laden, bevor sie vollständig abgespielt werden kann, und die Wiedergabe kann nicht im mittleren Abschnitt beginnen.

Und fMP4 besteht aus einer Reihe von Fragmenten. Wenn der Server Bytebereichsanforderungen unterstützt, können diese Fragmente unabhängig vom Client zur Wiedergabe angefordert werden, ohne die gesamte Datei zu laden.

Um diesen Punkt anschaulicher zu veranschaulichen, stelle ich im Folgenden einige häufig verwendete Tools zur Analyse von MP4-Dateien vor.

gpac, früher bekannt als mp4box, ist ein Medienentwicklungs-Framework. Es enthält eine große Anzahl von Medienanalysetools, die in Testapps verwendet werden können 🎜>mp4box.js, ist die Javascript-Version von mp4box;

  • bento4, ein Analysetool speziell für MP4;

  • mp4parser, eine Online-MP4-Datei Analysetool.

  • Fragment-MP4 VS Nicht-Fragment-MP4

  • Das Folgende ist ein Screenshot einer Fragment-MP4-Datei, die von mp4parser (Online MPEG4 Parser) analysiert wurde▽

Das Folgende ist ein Screenshot einer nicht fragmentierten MP4-Datei, die von mp4parser analysiert wurde ▽

Wir können das obere Feld der nicht fragmentierten MP4-Datei sehen. fragment mp4 Es gibt nur sehr wenige Typen, und fragment mp4 besteht aus moof+mdat-Segmenten. Sie enthalten bereits genügend Metadateninformationen und Daten, und Sie können direkt zu dieser Position suchen und mit der Wiedergabe beginnen. Mit anderen Worten, fMP4 ist ein Streaming-Kapselungsformat, das sich besser für das Streaming im Netzwerk eignet, ohne auf Metadaten im Dateiheader angewiesen zu sein.

Apple gab auf der WWDC 2016 bekannt, dass es fMP4 in HLS in iOS 10, tvOS und macOS unterstützen wird. Es ist ersichtlich, dass die Aussichten für fMP4 sehr gut sind.

Es ist erwähnenswert, dass fMP4, CMAF und ISOBMFF eigentlich ähnliche Dinge sind.

MSE-JavaScript-API

Auf hohem Niveau bietet MSE

eine Reihe von JavaScript-APIs zum Erstellen von Medienströmen

  • Ein Stitching- und Caching-Modell

  • Identifiziert einige Byte-Stream-Typen

  • WebM

  • ISO-Basismediendateiformat

  • MPEG-2-Transportströme

  • Interne MSE-Struktur


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 TIME

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

MSE Vod Demo

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

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

展示利用 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 播放输出。

详情了解:

推荐阅读:

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

Das obige ist der detaillierte Inhalt vonWebSocket+MSE – Analyse der HTML5-Live-Broadcast-Technologie. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn