Web直播技术 (2023.04)

直播流程

录制->编码->网络传输(推流->服务器处理->CDN分发)->解码->播放

  • 通过 HTTP、WebSocket 等方式获取数据;
  • 处理数据,解协议、组帧等得到媒体信息及数据;
  • 封装成媒体片段,或解码成一帧画面;
  • 通过 video 或 canvas(WebGL)等进行播放。

主要指标和问题

质量好坏的主要指标

  • 内容延时(评论、打赏等互动反馈)
  • 卡顿(流畅度)
  • 首帧时长(用户体验)

需要克服的主要问题

  • 网络环境
  • 多人连麦
  • 主辅路
  • 浏览器兼容性、跨平台
  • CDN 支持等

流媒体

概念

流媒体(streaming media)是指将一连串的媒体数据压缩后,经过网上分段发送数据,在网上即时传输影音以供观赏的一种技术与过程,此技术使得数据包得以像流水一样发送;如果不使用此技术,就必须在使用前下载整个媒体文件。流式传输可传送现场影音或预存于服务器上的影片,当观看者在收看这些影音文件时,影音数据在送达观看者的计算机后立即由特定播放软件播放。

流媒体实际指的是一种新的媒体传送方式,有声音流、视频流、文本流、图像流、动画流等,而非一种新的媒体。

流媒体文件格式是支持采用流式传输及播放的媒体格式。

特征

  1. 内容主要是时间上连续的媒体数据(音频、视频、动画、多媒体等)。
  2. 内容可以不经过转换就采用流式传输技术传输。
  3. 具有较强的实时性,交互性。
  4. 启动延时大幅度缩短,缩短了用户的等待时间;用户不用等到所有内容都下载到硬盘上才能开始浏览,在经过一段启动延时后就能开始观看。
  5. 对系统缓存容量的要求大大降低。

Internet是以包传输为基础进行的异步传输,数据被分解成许多包进行传输,由于每个包可能选择不同的路由,所以到达用户计算机的时间延迟就会不同,而在客户端就需要缓存系统来弥补延迟和抖动的影响以及保证数据包传输的顺序在流媒体文件的播放过程中,由于不再需要把所有的文件都下载到缓存,因此对缓存的要求很低。

系统组成

流媒体系统包括以下5个方面的内容:

  1. 服务器:存放和控制流媒体的数据。
  2. 编码工具:用于创建、捕捉和编辑多媒体数据,形成流媒体格式。
  3. 流媒体数据。
  4. 网络:适合多媒体传输协议甚至是实时传输协议的网络
  5. 播放器:供客户端浏览流媒体文件(解码、播放)。

这5个部分有些是服务器端需要的,有些是客户端需要的,而且不同的流媒体标准和不同公司的解决方案会在某些方面有所不同。

流式传输方式

流式传输是指通过网络传送媒体(音频、视频等)技术的总称。实现流式传输主要有两种方式:顺序流式传输(progressive streaming)和实时流式传输(real timestreaming)。采用哪种方式依赖于具体需求,下面就对这两种方式进行简要的介绍。

顺序流式传输

顺序流式传输是顺序下载,用户在观看在线媒体的同时下载文件,在这一过程中,用户只能观看下载完的部分,而不能直接观看未下载部分。也就是说,用户总是在一段延时后才能看到服务器传送过来的信息。由于标准的HTTP服务器就可以发送这种形式的文件,它经常被称为HTTP流式传输。

由于顺序流式传输能够较好地保证节目播放的质量,因此比较适合在网站上发布的、可供用户点播的、高质量的视频。

顺序流式文件是放在标准 HTTP 或 FTP 服务器上,易于管理,基本上与防火墙无关。顺序流式传输不适合长片段和有随机访问要求的视频,如:讲座、演说与演示。它也不支持现场广播。

实时流式传输

实时流式传输必须保证匹配连接带宽,使媒体可以被实时观看到。

在观看过程中用户可以任意观看媒体前面或后面的内容,但在这种传输方式中,如果网络传输状况不理想,则收到的图像质量就会比较差,实时流式传输需要特定服务器,如 Quick Time Streaming Server、 Realserver或 Windows Media server。这些服务器允许对媒体发送进行更多级别的控制,因而系统设置、管理比标准HTTP服务器更复杂。实时流式传输还需要特殊网络协议,如: RTSP(realtime streaming protocol) 或 MMS(microsoft media server)。在有防火墙时,有时会对这些协议进行屏闭,导致用户不能看到一些地点的实时内容,实时流式传输总是实时传送,因此特别适合现场事件。

流媒体传输的网络协议

RTMP 协议

RTMP (Real Time Messaging Protocol) 实时消息传送协议是 Adobe Systems 公司为 Flash 播放器和服务器之间⾳频、视频和数据传输开发的开放协议。

  • 浏览器端依赖Flash进行播放
  • 低延迟(~3s)
  • 需要架设媒体服务器,造价高
  • 非常稳定。与市场上的其他替代品相比,在使用支持RTMP的服务时,非常不可能遇到任何中断或停机。RTMP要求在客户端和服务器之间有一个持久的连接,如果网络中断,这可能是个问题
  • HTML5 不支持 (转流:ffmpeg 转 flv、hls)
变种
  • ⼯作在 TCP 之上的明⽂协议,使⽤端⼜1935;
  • RTMPT 封装在 HTTP 请求之中,可穿越防⽕墙;
  • RTMPS 类似 RTMPT,但使⽤的是 HTTPS 连接;

RTSP 实时流协议

RTSP (Real Time Streaming Protocol) 是 TCP/IP 协议体系中的一个应用层协议,该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。HTTP与RTSP相比,HTTP请求由客户机发出,服务器作出响应;使用RTSP时,客户机和服务器都可以发出请求,即RTSP可以是双向的。RTSP是用来控制声音或影像的多媒体串流协议,并允许同时多个串流需求控制,传输时所用的网络通讯协定并不在其定义的范围内,服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。

  • 自己不传输数据,由 RTP/UDP/TCP 完成
  • 更低的延迟(1-5s)
  • 分段流式传输
  • 实时性强
  • 用于视频监控、视频会议、IP电话、IP 摄像机、物联网设备
  • CDN厂商、浏览器不支持

Java流媒体平台项目 web流媒体_Java流媒体平台项目

RTP 实时传输协议

实时传输协议 RTP(Real-time Transport Protocol) 被定义为在一对一或一对多的传输情况下工作。

其目的是提供时间信息和实现流同步。

RTP通常使用UDP来传送数据;

当应用程序开始一个RTP会话时将使用两个端口: 一个给 RTP,一个给 RTCP。RTP本身并不能为按顺序传送数据包提供可靠的传送制,也不提供流量控制或拥塞控制,它依靠RTCP提供这些服务;

通常 RTP 算法并不作为一个独立的网络层来实现,而是作为应用程序代码的一部分。

RTCP 实时传输控制协议

RTCP 和 RTP 一起提供流量控制和拥塞控制服务;在 RTP 会话期间各参与者周期性地传送 RTCP包;RTCP 包中含有已发送的数据包的数量、丢失的数据包数量等统计资料,因此,服务器可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP 和 RTCP 配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特适合传送网上的实时数据。

HLS(拉流)

Http Live Streaming,苹果提出的基于 HTTP 协议的流媒体网络传输协议。

传输内容包括两部分:一是 M3U8 列表文件,二是 TS 媒体文件。

原理

将一个大的媒体文件进行分片,将该分片文件资源路径记录于 M3U (m3u8) 文件(即 playlist)内,其中附带一些额外描述(比如该资源的多带宽信息等)用于提供给客户端。客户端依据该 m3u8 文件即可获取对应的媒体资源进行播放。

当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源片段,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的 playlist 文件,用于寻找可用的媒体流。

  1. HTML5直接支持(video),适合APP直播,PC断只有Safari、Edge支持
  2. 必须是H264+AAC编码
  3. 动态码率自适应
  4. 因为传输的是切割后的音视频片段,导致内容延时较大

Java流媒体平台项目 web流媒体_实时音视频_02

图源:

Java流媒体平台项目 web流媒体_Java流媒体平台项目_03

图源:https://caniuse.com/?search=HLS%20

优点
  1. 跨平台性:支持iOS/Android/PC,通用性强。插件支持:hls.js、videojs-contrib-hls等。在IOS上得天独厚的稳定播放。
  2. 穿墙能力强:由于HLS是基于HTTP协议的,因此HTTP数据能够穿透的防火墙或者代理服务器HLS都可以做到,基本不会遇到被防火墙屏蔽的情况。
  3. 切换码率快(清晰度):自带多码率自适应,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。客户端可以很快的选择和切换码率,以适应不同带宽条件下的播放。
  4. 负载均衡:HLS基于无状态协议(HTTP),客户端只是按照顺序使用下载存储在服务器的普通TS文件,做负责均衡如同普通的HTTP文件服务器的负载均衡一样简单。
缺点
  1. 实时性差:苹果官方建议是请求到3个片之后才开始播放。所以一般很少用HLS做为互联网直播的传输协议。假设列表里面的包含5个 ts 文件,每个 TS 文件包含5秒的视频内容,那么整体的延迟就是25秒。苹果官方推荐的ts时长时10s,所以这样就会大约有30s(n x 10)的延迟。相比 RTMP 这类长连接协议, 延时较高, 难以用到互动直播场景。
  2. 文件碎片化严重:对于点播服务来说,由于 TS 切片通常较小,海量碎片在文件分发,一致性缓存, 存储等方面都有较大挑战。
改进

由于客户端每次请求 TS 或 M3U8 都有可能是一个新的连接请求, 无法有效的标识客户端,一旦出现问题, 基本无法有效的定位问题。一般工业级的服务器都会对传统的 HLS 做一些改进,常见优化是对每个 M3U8 文件增加 Session 来标识一条 HLS 连接。不管通过哪种方式,最终我们都能通过一个唯一的 id 来标识一条流,这样在排查问题时就可以根据这个 id 来定位播放过程中的问题。

DASH

基于HTTP的动态自适应流(英语:Dynamic Adaptive Streaming over HTTP,缩写DASH,也称MPEG-DASH)是一种自适应比特率流技术,使高质量流媒体可以通过传统的 HTTP 网络服务器以互联网传递。

类似苹果公司的HTTP Live Streaming(HLS)方案,MPEG-DASH 会将内容分解成一系列小型的基于HTTP的文件片段,每个片段包含很短长度的可播放内容,而内容总长度可能长达数小时(例如电影或体育赛事直播)。内容将被制成多种比特率的备选片段,以提供多种比特率的版本供选用。当内容被 MPEG-DASH 客户端回放时,客户端将根据当前网络条件自动选择下载和播放哪一个备选方案。客户端将选择可及时下载的最高比特率片段进行播放,从而避免播放卡顿或重新缓冲事件。也因如此,MPEG-DASH 客户端可以无缝适应不断变化的网络条件并提供高质量的播放体验,拥有更少的卡顿与重新缓冲发生率。

MPEG-DASH 是首个基于 HTTP 的自适应比特率流解决方案,它也是一项国际标准。MPEG-DASH 不应该与传输协议混淆——MPEG-DASH 使用TCP传输协议。

dash.js 是一个使用 javascript 便编写的开源实现DASH协议的视频客户端。

系统架构

Java流媒体平台项目 web流媒体_Java流媒体平台项目_04

流程

Java流媒体平台项目 web流媒体_流媒体_05

  1. 主播直播流上传
  2. 服务器的编解码封装
  3. 流媒体分发器
  1. mpd文件
  2. 切割后的媒体文件
  1. 客户端
  1. 客户端加载mpd文件
  2. 解析MPD文件, 组成文件下载链接
  3. 当前的网速和支持的编码加载相应的视频片段进行播放

DASH 协议调研总结

小结

Java流媒体平台项目 web流媒体_webrtc_06

  • RTMP 主要优势在于延时相对较低 (1-3s),支持完善,稳定性强,CDN 分发。直播常用 RTMP,但现在已经不能用任何浏览器播放。现直播常见格式是 HLS 或 DASH。
  • RTSP 实时性最好(传输层可以使用 UDP/RTP,延迟可控制到1s内),但是实现复杂,适合视频聊天和视频监控。
  • HLS 延迟大,动态切换码率,适合视频点播。或对实时性要求不高的直播拉流。
  • HLS 是目前在 iOS(iPad,iPhone)上唯一支持的视频流标准,与 HLS 一样,DASH 支持自适应流传输。DASH 是国际标准。也是第一个基于 HTTP 的自适应流视频格式的国际标准。HLS 由苹果开发拥有,不是国际标准,但是目前在业界占主流。(https://zhuanlan.zhihu.com/p/24292096 2016-12-10)
  • 流媒体传输协议浅析

Media Source Extensions API

MSE 是 W3C 标准 API,提供了实现无插件且基于 Web 的流媒体的功能。解决 HTML5 的流问题(HTML5 原生仅支持播放 mp4/webm 非流格式,不支持 FLV),使用 MSE,媒体串流能够通过 JavaScript 创建,并且能通过使用 和 元素进行播放。

Why MSE

有了 标签,支持 HTML5 的 Web 浏览器就能够实现无需插件播放媒体内容了,但是 HTML5 的 标签对媒体的格式有所限制(在 Windows 电脑上只支持 mp4、webm、ogg 等格式)。这里简单介绍一下媒体格式,媒体的格式分为“编码格式”和“封装格式”,原视频数据通过编码来压缩视频数据大小,这里用到的格式为编码格式(如目前常见的 H.264 编码),再通过封装将压缩后的音视频、字幕组合到一个容器中,这里用到的格式为封装格式(如常见的 mp4 格式)。

我们可以把 标签看做是浏览器自带的、具有解封和解码功能的视频播放器。但是,随着视频点播、直播等视频业务的兴起,视频数据会通过流媒体传输协议(目前常用的 MPEG-DASH 和 Apple 的 HLS)从服务端分发给客户端,在这种情况下,媒体内容就被包含在传输协议中了,此时 HTML5 的 标签就无法识别并播放媒体内容了。以 HLS 协议为例。HLS 将视频源文件的内容分散地封装到一个个TS文件中,此时仅靠 标签是无法识别这些 TS 文件的,所以,我们就需要引入了 MSE 来帮助 Web 浏览器识别并处理 TS 文件,将其变回 Web 浏览器可识别的媒体容器格式(mp4 格式),经过 MSE 的处理, 标签就可以识别并播放视频源文件了。

例如,hls.js 中就利用 MSE 将视频分片内容进行合流,并组成 HTML5 的 标签可播放的媒体资源文件。再比如,flv.js 通过 MSE 播放 HTTP-FLV 协议的视频直播流。简单总结一下,引入 MSE 之后,支持 HTML5 的 Web 浏览器就变成了能够解析流协议的播放器了。

从另外一个角度来说,通过引入 MSE,HTML5 的 标签不仅可以直接播放其默认支持的 mp4、m3u8、webm、ogg 等格式,还可以支持能够被 (具备 MSE 功能的)JS 处理的视频流格式。如此一来,我们就可以通过 (具备 MSE 功能的)JS,把一些 标签原本不支持的视频流格式,转化为其支持的格式(如 H.264 编码的 mp4)。

MSE 支持性

可以用 MediaSource.isTypeSupported() 判断是否支持某种 MINE 类型。在 ios Safari 中不支持。https://caniuse.com/?search=MSE

  • 前端流媒体:MSE入门
  • MIME 类型
  • 可以被使用的解码器或视频文件格式
  • 为什么视频网站的视频链接地址是blob?

JS 库

flv.js

一个用纯 JavaScript 编写的 HTML5 Flash 视频 (FLV) 播放器,没有 Flash。

对于 FLV 直播流播放,请考虑正在积极开发中的mpegts.js 。这个项目将变得很少维护。

  1. Bilibli 开源,解析flv数据,通过 MSE 封装成 fMP4 喂给 video 标签
  2. 编码为 H264+AAC/MP3
  3. 使用 HTTP 的流式 IO(fetch或stream) 或 WebSocket 协议流式的传输媒体内容
  4. 2~5 秒的延迟,首帧比 RTMP 更快

Adobe 宣布 2020 年彻底停止 flash 更新,H5 中播放视频用的是 video 标签,仅支持 Ogg、MPEG4、WebM 三种格式。可是 B 站早期的视频都是 flv 格式,B 站想出了一个过渡的办法:由于 HTML5 的 video 标签只支持 mp4,要想支持 flv ,我们就要拆解 flv 了。由于 flv 容器封装的是 H264 + AAC,所以我们可以在网页端收到 flv 后,使用 js 代码解析 flv,取出 H264 以及 AAC,然后封装成 mp4 文件,再喂给 video 标签就可以了。这样我们就可以无插件播放 flv 了,由于 mp4 封装比 flv 复杂多了,所以这样可以减轻服务器压力,服务器不用再专门封装 mp4 文件。使哔哩哔哩网页端平滑过度到 HTML5 播放器,历史遗留不再是障碍。

优酷用的 hls.js,跟 flv 类似,也需要一个 js 插件把 hls 转成 mp4。

mpegts.js

mpegts.js 是在 HTML5 上直接播放 MPEG2-TS 流的播放器,针对低延迟直播优化,可用于 DVB/ISDB 数字电视流或监控摄像头等的低延迟回放。

基于 flv.js 改造而来

mpegts.js 通过在 JavaScript 中渐进化解析 MPEG2-TS 流并实时转封装为 ISO BMFF (Fragmented MP4),然后通过 Media Source Extensions 把音视频数据喂入 HTML5 元素。

  • H.265/HEVC 播放支持(FLV 或 MPEG-TS 均已支持)
  • 超低延迟,最佳状态延迟可低达 1 秒以内
  • 支持 Chrome, FireFox, Safari, Edge (Old or Chromium) 或任何基于 Chromium 的浏览器
  • 极低的 CPU 使用率和内存使用量(单个实例约使用 JS 堆 10MiB)

hls.js

HLS.js 是一个实现 HTTP Live Streaming 客户端的 JavaScript 库。它依赖于 HTML5 视频和 MediaSource Extensions 进行播放。

它通过将 MPEG-2 传输流和 AAC/MP3 流转换为 ISO BMFF (MP4) 片段来工作。

video.js

video.js 是一款基于 HTML5 的网络视频播放器。它支持 HTML5 和 MSE,以及 YouTube 和 Vimeo(通过插件)。支持在台式和移动设备上播放视频。现已用于 700,000 个网站。

  • 有良好的跨浏览器的样式,更美观 (官方/自定义皮肤: 列表)
  • 支持流媒体格式,例如 HLS、MPEG DASH
  • 没有浏览器兼容问题
  • 支持社交媒体平台,例如 Youtube,Vimeo 等
  • 有丰富的插件(官方/第三方/自定义)
  • 播放技术 Playback Technology (“Tech”) 播放技术是指用于播放视频或音频的特定浏览器或插件技术
  • FAQ
  • Web 前端如何播放 HLS(.m3u8) 视频

工具

OBS 推流

VLC 拉流解码播放,静态视频文件转流,例如 MP4 -> RTSP

FFmpeg 编码解码,转流:flv、websocket、http-flv、m3u8、hls 等

参考

  • 直播点播流媒体技术方案书
  • 流媒体之HLS与DASH

WebRTC

  • WebRTC (Web Real-Time Communication) 是为浏览器之间提供实时数据传输的 javascript API
  • 支持 peer-to-peer 音频、视频、数据流传输能力
  • WebRTC 实时通信
  • Google Developers - 利用 WebRTC 实现实时通信
  • adapter.js 抹平各浏览器之间的前缀差异和行为差异
  • WebRTC 示例

主要的API

  • getUserMedia : 获取音视频
  • MediaRecorder: 录制音视频
  • RTCPeerConnection: 浏览器之间音视频流连接对象(连接管理)
  • RTCDataChannel: 浏览器数据流连接对象(管理任意数据)

结构图

Java流媒体平台项目 web流媒体_HTTP_07

优点

  • Google 力推,已成为 W3C 标准
  • 现代浏览器支持趋势,X5 也支持(微信、QQ)

Java流媒体平台项目 web流媒体_HTTP_08

图源:https://caniuse.com/?search=webRTC

  • 基于 UDP,低延迟,弱网抗性强,比 flv.js 更有优势

方案

CPU占用

帧率

码率

延时

首帧

flv.js

0.4

30

700kbit/s

1.5s

2s

WebRTC

1.9

30

700kbit/s

0.7s

1.5s

  • 支持 Web 上行能力
  • 提供 NAT 穿透技术(ICE)

缺点

  • 缺乏服务器方案的设计和部署。
  • 传输质量难以保证。WebRTC 的传输设计基于 P2P,难以保障传输质量,优化手段也有限,只能做一些端到端的优化,难以应对复杂的互联网环境。比如对跨地区、跨运营商、低带宽、高丢包等场景下的传输质量基本是靠天吃饭,而这恰恰是国内互联网应用的典型场景。
  • 比较适合一对一的单聊,虽然功能上可以扩展实现群聊,但是没有针对群聊,特别是超大群聊进行任何优化。
  • 设备端适配,如回声、录音失败等问题层出不穷。这一点在安卓设备上尤为突出。由于安卓设备厂商众多,每个厂商都会在标准的安卓框架上进行定制化,导致很多可用性问题(访问麦克风失败)和质量问题(如回声、啸叫)。
  • 以上缺点信息来源:WebRTC的优缺点,文章发表时间 2016.06,目前应该有所改善。

参考

  • Web 直播,你需要先知道这些
  • 基于 webRTC+Electron 实现远程控制
  • The Complete Guide to Live Streaming (直播流媒体完整指南.pdf 2021)
  • wowza - Reports & Guides

Java流媒体平台项目 web流媒体_HTTP_09

Java流媒体平台项目 web流媒体_实时音视频_10

图源:Wowza - 2021 年视频流延迟报告

Java流媒体平台项目 web流媒体_webrtc_11

图源:Wowza - 2021 年视频流延迟报告

总结

  • 根本不同的业务,选用不同的直播技术
  • RTMP 和 HLS 保持其优势,但下一代格式正在兴起。其中包括 WebRTC, SRT, Low-Latency HLS 和用于 DASH 的 low-latency CMAF。
  • 不断的去关注新技术