>  기사  >  웹 프론트엔드  >  WebSocket+MSE——HTML5 라이브 방송 기술 분석

WebSocket+MSE——HTML5 라이브 방송 기술 분석

巴扎黑
巴扎黑원래의
2017-06-23 14:45:594304검색

저자 | Liu Bo (역시 Paiyun 멀티미디어 개발 엔지니어)

현재 모바일 웹 라이브 방송에 대한 상대적으로 뜨거운 수요를 충족시키기 위해 일련의 HTML5 라이브 방송 기술이 급속히 개발되었습니다.

HTML5에 사용할 수 있는 일반적인 라이브 스트리밍 기술에는 HLS, WebSocket 및 WebRTC가 있습니다. 오늘은 WebSocket과 MSE에 관련된 기술적 포인트를 소개하고 마지막으로 예제를 통해 구체적인 사용법을 보여드리겠습니다.

문서 개요

  • WebSocket 프로토콜 소개

  • WebSocket 클라이언트/서버 API 소개

  • MSE 소개

  • fMP4 소개

  • 데모 디스플레이

WebSocket

일반적인 웹 애플리케이션 모두 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 Handshake

새 프로토콜을 더 쉽게 배포하기 위해 HTTP/1.1에서는 클라이언트와 서버가 기존 HTTP 구문을 사용하여 다른 프로토콜로 업그레이드할 수 있도록 하는 업그레이드 메커니즘을 도입했습니다. 이 메커니즘은 RFC7230, 섹션 6.7 업그레이드에 자세히 설명되어 있습니다.

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 업그레이드 응답의 상태 코드는 101이고 응답 본문은 새 프로토콜에서 정의한 데이터 형식을 사용할 수 있습니다.

WebSocket 핸드셰이크는 이 HTTP 업그레이드 메커니즘을 활용합니다. 핸드셰이크가 완료되면 후속 데이터 전송은 TCP를 통해 직접 수행됩니다.

WebSocket JavaScript API

현재 주류 브라우저는 서버에 메시지(텍스트 또는 바이너리)를 보내고 이벤트 기반 응답 데이터를 받을 수 있는 WebSocket API 인터페이스를 제공합니다.

Step1. 브라우저가 WebSocket을 지원하는지 확인하세요

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

Step2. 연결을 설정하세요

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

Step3.onopen, onclose, onerror, onmes를 등록하세요. WebSocket 객체 세이지 콜백 함수.

ws.send()를 통해 데이터를 보냅니다. 여기서는 문자열뿐만 아니라 Blob 또는 ArrayBuffer 유형의 데이터도 보낼 수 있습니다.

바이너리 데이터를 수신하는 경우 연결 개체의 형식을 blob 또는 arraybuffer로 설정해야 합니다.

ws.binaryType = 'arraybuffer';

WebSocket Golang API

서버측 WebSocket 라이브러리로는 net/http와 함께 매우 편리하게 사용할 수 있는 Google 자체 을 사용하는 것이 좋습니다. websocket.Handler를 통해 WebSocket의 핸들러 함수를 http.Handler로 변환하여 net/http 라이브러리와 함께 사용할 수도 있습니다.

그런 다음 websocket.Message.Receive를 통해 데이터를 받고 websocket.Message.Send를 통해 데이터를 보냅니다.

특정 코드에 대해서는 아래 데모 섹션을 볼 수 있습니다.

MSE

MSE를 소개하기 전에 먼저 HTML5b97864c2e0ef2353a16c4d64c7734e92 및 39000f942b2545a5315c57fa3276f220의 한계를 살펴보겠습니다.

HTML5b97864c2e0ef2353a16c4d64c7734e92 및 39000f942b2545a5315c57fa3276f220 태그 제한

  • 스트리밍 지원 안 됨

  • DRM 및 암호화 지원 안 됨

  • 컨트롤을 맞춤 설정하고 브라우저 간 일관성을 유지하기 어려움

  • 인코딩 캡슐화는 브라우저마다 다르게 지원됩니다

MSE는 HTML5의 스트리밍 문제를 해결하기 위한 것입니다.

Media Source Extensions(MSE)는 Chrome, Safari, Edge와 같은 주요 브라우저에서 지원되는 새로운 웹 API입니다. MSE는 JavaScript가 39000f942b2545a5315c57fa3276f220 및 b97864c2e0ef2353a16c4d64c7734e92에 대한 미디어 스트림을 동적으로 구성할 수 있도록 하는 W3C 표준입니다. 이는 JavaScript가 미디어 스트림 조각을 HTMLMediaElement로 전송할 수 있도록 하는 개체를 정의합니다.

MSE를 사용하면 플러그인 없이도 미디어 스트림을 동적으로 수정할 수 있습니다. 이를 통해 프런트엔드 JavaScript는 JavaScript에서 재패키징, 처리, 트랜스코딩까지 더 많은 작업을 수행할 수 있습니다.

MSE는 스트림을 미디어 태그에 직접 전송할 수 없지만 MSE는 크로스 브라우저 플레이어를 구축하기 위한 핵심 기술을 제공하여 브라우저가 JavaScript API를 통해 오디오 및 비디오를 미디어 태그에 푸시할 수 있도록 합니다.

브라우저 지원

caniuse를 사용하여 브라우저가 지원하는지 확인하세요.

MediaSource.isTypeSupported()를 통해 코덱 MIME 유형이 지원되는지 추가로 확인할 수 있습니다.

fMP4

더 일반적으로 사용되는 비디오 패키징 형식은 WebM과 fMP4입니다.

WebM과 WebP는 두 자매 프로젝트로 둘 다 Google이 후원합니다. WebM은 Matroska를 기반으로 한 컨테이너 형식이므로 본질적으로 스트리밍이며 스트리밍 미디어 분야에서 사용하기에 매우 적합합니다.

다음은 fMP4 형식에 중점을 둡니다.

우리 모두는 MP4가 일련의 상자로 구성되어 있다는 것을 알고 있습니다. 일반적인 MP4는 중첩된 구조를 가지고 있습니다. 클라이언트는 MP4 파일을 처음부터 로드해야 완전히 재생될 수 있으며, 중간 부분부터 재생을 시작할 수 없습니다.

그리고 fMP4는 일련의 조각으로 구성됩니다. 서버가 바이트 범위 요청을 지원하는 경우 전체 파일을 로드하지 않고도 이러한 조각을 클라이언트에 독립적으로 요청할 수 있습니다.

이 점을 더 생생하게 설명하기 위해 아래에서는 MP4 파일 분석에 일반적으로 사용되는 몇 가지 도구를 소개합니다.

gpac(이전에는 mp4box로 알려짐)은 소스 코드 아래에 테스트 앱에서 사용할 수 있는 수많은 미디어 분석 도구가 있습니다.

  • mp4box.js는 mp4box의 Javascript 버전입니다. ;

  • bento4, MP4용 전문 분석 도구

  • mp4parser, 온라인 MP4 파일 분석 도구.

fragment mp4 VS non-fragment mp4

다음은 mp4parser(Online MPEG4 Parser)로 분석한 조각 mp4 파일의 스크린샷입니다. ▽

다음은 조각이 아닌 mp4 파일을 분석한 스크린샷입니다. by mp4parser ▽

조각이 아닌 mp4에는 최상위 상자 유형이 거의 없으며 조각 mp4는 moof+mdat 세그먼트로 구성되어 있으며 이미 충분한 메타데이터 정보와 데이터를 포함하고 있으며 직접 검색할 수 있음을 알 수 있습니다. 이 위치로 가서 연주를 시작하세요. 즉, fMP4는 스트리밍 캡슐화 형식으로, 파일 헤더의 메타데이터에 의존하지 않고 네트워크 스트리밍에 더 적합합니다.

Apple은 WWDC 2016 컨퍼런스에서 iOS 10, tvOS, macOS의 HLS에서 fMP4를 지원할 것이라고 발표했는데, 이는 fMP4의 전망이 매우 좋다는 것을 보여줍니다.

fMP4, CMAF 및 ISOBMFF는 실제로 유사한 것임을 언급할 가치가 있습니다.

MSE JavaScript API

높은 수준에서 MSE는

  • 미디어 스트림 구축을 위한 JavaScript API

  • 스플라이싱 및 캐싱 모델

  • 일부 바이트 스트림 유형을 식별

  • WebM

  • ISO 기본 미디어 파일 형식

  • MPEG-2 전송 스트림

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接口

위 내용은 WebSocket+MSE——HTML5 라이브 방송 기술 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.