Maison  >  Article  >  interface Web  >  WebSocket+MSE——Analyse de la technologie de diffusion en direct HTML5

WebSocket+MSE——Analyse de la technologie de diffusion en direct HTML5

巴扎黑
巴扎黑original
2017-06-23 14:45:594322parcourir

Auteur | Liu Bo (également ingénieur de développement multimédia Paiyun)

Actuellement, afin de répondre à la demande relativement forte de diffusion en direct sur le Web mobile, une série de technologies de diffusion en direct HTML5 ont été rapidement développées.

Les technologies de diffusion en direct courantes pouvant être utilisées avec HTML5 incluent HLS, WebSocket et WebRTC. Aujourd'hui je vais vous présenter les points techniques liés à WebSocket et MSE, et enfin vous démontrer l'utilisation spécifique à travers un exemple.

Aperçu de l'article

  • Introduction au protocole WebSocket

  • Introduction à l'API client/serveur WebSocket

  • Introduction à MSE

  • Introduction à fMP4

  • Affichage de la démonstration

WebSocket

Les applications Web habituelles sont construites autour du modèle de requête/réponse HTTP. Toutes les communications HTTP sont contrôlées via le client. Le client envoie une requête au serveur une fois que le serveur l'a reçue et traitée, il renvoie le résultat au client et le client affiche les données. Comme ce mode ne peut pas répondre aux besoins des applications temps réel, des technologies de connexion longue « poussée par le serveur » telles que SSE et Comet ont vu le jour.

WebSocket est un protocole de communication basé sur une connexion TCP, qui peut effectuer une communication full-duplex sur une seule connexion TCP. WebSocket a été défini comme norme RFC 6455 par l'IETF en 2011 et complété par la RFC 7936. L'API WebSocket a été définie comme norme par le W3C.

WebSocket est un protocole créé indépendamment sur TCP. Les concepts du protocole HTTP ne sont pas liés à WebSocket. La seule corrélation est que lors de l'utilisation du code d'état 101 du protocole HTTP pour la commutation de protocole, le port TCP utilisé. est de 80, ce qui permet de contourner la plupart des restrictions du pare-feu.

WebSocket Handshake

Afin de déployer plus facilement de nouveaux protocoles, HTTP/1.1 introduit le mécanisme de mise à niveau, permettant au client et au serveur d'utiliser certains protocoles HTTP existants. la syntaxe est mise à niveau vers d’autres protocoles. Ce mécanisme est décrit en détail dans la RFC7230, section 6.7 Mise à niveau.

Pour lancer une mise à niveau du protocole HTTP/1.1, le client doit préciser ces deux champs dans l'en-tête de la requête ▽

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

Si le serveur accepte la mise à niveau , alors vous devez répondre comme ceci ▽

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

Comme vous pouvez le voir, le code d'état de la réponse HTTP Upgrade est 101, et le corps de la réponse peut être défini à l’aide du nouveau format de données du protocole.

La poignée de main WebSocket profite de ce mécanisme de mise à niveau HTTP. Une fois la négociation terminée, le transfert de données ultérieur s'effectue directement via TCP.

API JavaScript WebSocket

Actuellement, les navigateurs grand public fournissent une interface API WebSocket, qui peut envoyer des messages (texte ou binaire) au serveur et recevoir des données de réponse basées sur des événements.

Étape 1. Vérifiez si le navigateur prend en charge WebSocket

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

Établissez une connexion

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

Étape 3. Enregistrez les fonctions de rappel et envoyez et recevez des données

Enregistrez respectivement les fonctions de rappel onopen, onclose, onerror et onmessage de l'objet WebSocket.

Envoyer des données via ws.send(). Non seulement des chaînes peuvent être envoyées ici, mais également des données de type Blob ou ArrayBuffer.

Si des données binaires sont reçues, le format de l'objet de connexion doit être défini sur blob ou arraybuffer.

ws.binaryType = 'arraybuffer';

API WebSocket Golang

Pour la bibliothèque WebSocket côté serveur, je recommande d'utiliser le de Google, qui est très pratique Utilisé avec net/http. Vous pouvez également convertir la fonction de gestionnaire de WebSocket en http.Handler via websocket.Handler, afin qu'elle puisse être utilisée avec la bibliothèque net/http.

Ensuite, recevez des données via websocket.Message.Receive et envoyez des données via websocket.Message.Send.

Le code spécifique peut être trouvé dans la section Démo ci-dessous.

MSE

Avant de présenter MSE, examinons d'abord les limites de HTML5b97864c2e0ef2353a16c4d64c7734e92 et 39000f942b2545a5315c57fa3276f220.

Limitations des balises HTML5b97864c2e0ef2353a16c4d64c7734e92 et 39000f942b2545a5315c57fa3276f220

  • Le streaming n'est pas pris en charge

  • Le DRM et le cryptage sont non pris en charge

  • Difficile de personnaliser les contrôles et de maintenir la cohérence entre les navigateurs

  • La prise en charge du codage et de l'encapsulation est différente selon les navigateurs

MSE résout le problème de streaming du HTML5.

Media Source Extensions (MSE) est une nouvelle API Web prise en charge par les navigateurs grand public tels que Chrome, Safari et Edge. MSE est une norme du W3C qui permet à JavaScript de construire dynamiquement des flux multimédias pour les formats 36a905548c8276df5a0a9467f3407669. Il définit des objets qui permettent à JavaScript de transférer des fragments de flux multimédia vers un HTMLMediaElement.

En utilisant MSE, vous pouvez modifier dynamiquement les flux multimédias sans avoir besoin de plugins. Cela permet à JavaScript frontal de faire plus : reconditionnement, traitement et même transcodage en JavaScript.

Bien que MSE ne puisse pas transmettre de flux directement aux balises multimédias, MSE fournit la technologie de base pour créer des lecteurs multi-navigateurs, permettant aux navigateurs de transmettre l'audio et la vidéo aux balises multimédias via des API JavaScript.

Prise en charge du navigateur

Utilisez caniuse pour vérifier si la prise en charge du navigateur est disponible.

Vous pouvez également vérifier si le type de codec MIME est pris en charge via MediaSource.isTypeSupported().

fMP4

Les formats d'encapsulation vidéo les plus couramment utilisés sont WebM et fMP4.

WebM et WebP sont deux projets frères, tous deux sponsorisés par Google. Puisque WebM est un format de conteneur basé sur Matroska, il est intrinsèquement en streaming et est très approprié pour une utilisation dans le domaine du streaming multimédia.

Ce qui suit se concentre sur le format fMP4.

Nous savons tous que MP4 est composé d'une série de Box. Le MP4 ordinaire a une structure imbriquée. Le client doit charger un fichier MP4 depuis le début avant de pouvoir le lire complètement, et il ne peut pas commencer la lecture à partir de la section centrale.

Et fMP4 se compose d'une série de fragments. Si le serveur prend en charge les requêtes de plage d'octets, ces fragments peuvent être demandés indépendamment au client pour la lecture sans charger l'intégralité du fichier.

Pour illustrer ce point de manière plus vivante, je présente ci-dessous plusieurs outils couramment utilisés pour analyser les fichiers MP4.

gpac, anciennement connu sous le nom de mp4box, est un framework de développement multimédia. Il existe un grand nombre d'outils d'analyse multimédia sous son code source, qui peuvent être utilisés dans les applications de test ; 🎜>mp4box.js, est la version Javascript de mp4box

  • bento4, un outil d'analyse spécifiquement pour MP4

  • mp4parser, un fichier MP4 en ligne ; outil d’analyse.

  • fragment mp4 VS non-fragment mp4

  • Ce qui suit est une capture d'écran d'un fragment de fichier mp4 analysé par mp4parser (Online MPEG4 Parser)▽

Ce qui suit est une capture d'écran d'un fichier mp4 non fragmenté analysé par mp4parser ▽

Nous pouvons voir la case supérieure du non-fragment fragment mp4 Il existe très peu de types, et le fragment mp4 est composé de segments moof+mdat. Ils contiennent déjà suffisamment d'informations et de données de métadonnées, et vous pouvez directement rechercher cette position et commencer à jouer. En d’autres termes, fMP4 est un format d’encapsulation de streaming, plus adapté au streaming sur le réseau sans dépendre des métadonnées dans l’en-tête du fichier.

Apple a annoncé lors de la conférence WWDC 2016 qu'il prendrait en charge fMP4 dans HLS sous iOS 10, tvOS et macOS. On voit que les perspectives de fMP4 sont très bonnes.

Il convient de mentionner que fMP4, CMAF et ISOBMFF sont en fait des choses similaires.

API JavaScript MSE

À un niveau élevé, MSE fournit

un ensemble d'API JavaScript pour créer des flux multimédias

  • Un modèle d'assemblage et de mise en cache

  • Identifie certains types de flux d'octets

  • WebM

  • Format de fichier multimédia de base ISO

  • Flux de transport MPEG-2

  • Structure interne 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 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接口

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn