音视频之webRTC和直播
webrtc
是什么
Web real-time communication,实时通讯解决方案,涵盖音视频采集、通讯建立、信息传输、音视频显示。
怎么做到的
-
音视频采集
通过webrtc 中 MediaStream API getUserMedia可以获取设备媒体流,包括麦克风、摄像头、屏幕画面等,需要注意兼容性问题。
-
端到端如何音视频共享?
传统方法:通过中转服务器交换,实时性差
P2P连接:对等网络,不经过第三方服务,可以参考p2p通信原理及实现
Webrtc 基于UDP实现端对端连接,通过RTCPeerConnection创建点对点连接,但在点对点信道建立之前(信令阶段)需要信令服务帮助建立连接。
RTCPeerConnection:代表一个由本地计算机到远端的WebRTC连接,该接口提供了创建、保持、监控、关闭连接的方法实现。
SDP:本地媒体元数据格式,用来交换本地和远程描述
ICE:Interactive Connectivity Establishment,交互式连接建立
ICE候选者:潜在的连接端点
-
端到端数据共享:如共享画板
依赖RTCDataChannel,RTCDataChannel就是在点对点连接中建立一个双向的数据通道,从而获得文本、文件等数据的点对点传输能力,依赖于流控制传输协议SCTP。RTCDataChannel通过RTCPeerConnection创建。
SCTP,传输层协议,在WebRTC情况下SCTP通过安全的DTLS隧道传输,该隧道本身在UDP上运行。
-
瓶颈限制
P2P连接去中心化,适用于小量的连接;大量连接还需要回归中心化思想,由中心服务实现去中心化能力。
-
多人通信架构模式
- Mesh架构:在端到端对等连接上进行扩充,每个客户端创建多个1v1的对等连接。不需要额外的服务器处理媒体数据(除信令服务器),基于WebRTC自身的点对点连接进行通信。缺点是如果连接的客户端过多会导致上行带宽压力较大。
- Mixer架构:利用MCU(Multipoint Conferencing Unit,多点控制单元)接收并混合每个客户端传入的媒体流,即将多个客户端的音视频画面合成单个流,再传输给每个参与的客户端,能保证客户端始终是1v1连接,缓解Mesh架构问题。缺点是依赖服务端,成本较大,且服务端处理过多更容易导致视频延迟
- Router/SFU(Multipoint Conferencing Unit)架构:单纯数据流转发,不进行合成、转码等动作。
直播
基本概念
-
涵盖的技术环节:采集端、流媒体服务器、播放端、拉流(播放端)、推流(采集端)
-
视频流传输:流媒体传输协议
- RTMP:Real Time Messaging Protocol,实时消息传输协议,属于Adobe,可用于推流端和拉流端,视频必须H264编码,音频必须AAC/MP3编码,多以FLV格式封包,传输的基本是FLV格式的流文件,必须使用Flash播放器才能播放,实时效果好
- RTSP:Real-Time Stream Protocol,用于推流端,实时效果很好
- HLS:Http Live Streaming,Apple定义,基于HTTP的流媒体实时传输协议,传输内容包括两部分:M3U8描述文件和TS媒体文件,TS媒体中视频必须以H264编码,音频必须是ACC/MP3编码,数据通过HTTP传输。用于拉流端,实时效果不好
- HTTP-FLV,HTTP + FLV,将音视频数据封装成FLV格式,然后利用HTTP传输到客户端,用于拉流,依赖浏览器支持播放FLV
- WebSocket-FLV:基于WebSocket传输FLV,依赖浏览器支持播放FLV
-
Ffmepg:可以用来记录、转换数字音视频,并将其转化为流的开源软件,可以进行视频的采集、封装成流,并推送到流媒体服务器上。
-
FLV:网络上传输的流媒体数据存储容器格式,相对简单轻量,不需要很大的媒体头部信息,由FLV Header、FLV Body以及其他Tag组成。
-
编解码
-
为什么需要:
- 视频采集设备采集的原始音视频体积非常大,如果不经过压缩网络很难传输
- 相邻视频帧之间有很多重复内容
目的:减少体积便于存储、传输,需要进行压缩(即“编码”),在观看时必须解压缩(“解码”)还原成原始信息
-
有哪些编码技术
- H.264:高级视频编码,AVC,提供复杂压缩级别,质量损失最小,不需要极高的计算能力
- H.265:高效视频编码,HEVC,H.264的继任者,支持比H.264进一步减小文件大小
-
解码技术:
- 软解和硬解:软件解码(CPU)和硬件解码(机器专门的解码芯片),软解CPU占用过多,可能导致卡顿。硬解码兼容性较差
-
MSE
Media Souce Extensions,MSE可以把单个文件的src值替换成引用MediaSource对象以及引用多个SourceBuffer对象的元素,用来解决h5播放器video一部分功能的支持问题。
SourceBuffer
接收两种类型的数据:
Initialization Segment
视频的初始片段,其中包含媒体片段序列进行解码所需的所有初始化信息。Media Segment
包含一部分媒体时间轴的打包和带时间戳的媒体数据。
RTMP
-
是什么:Adobe基于Flash播放器对应音视频Flv封装格式提出的一种基于TCP的数据传输协议,属于应用层协议。优点是稳定、兼容性强、高穿透,常用于推流方的稳定传输需求
-
如何做的:
为了维持稳定连续传递、避免单次传输数据量问题,采用传输层封包、数据流切片的实现方式
-
需要注意:
rtmp://
协议端口问题,可能会有防火墙拦截
HLS
-
为什么要有:主要为了解决RTMP协议存在的一些问题
- RTMP协议不使用标准的HTTP接口传输数据,在一些特殊的网络环境下可能被防火墙屏蔽
- RTMP是一种有状态的协议,需要为每个播放视频流的客户端维护状态,很难对视频服务器进行平滑扩展。
HLS使用HTTP传输数据,一般不会被防火墙拦截,同时也是无状态协议。
-
工作原理:把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些,当媒体流正在播放时,客户端可以选择许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。
-
缺点:采用HLS协议直播视频延迟时间无法达成10s以下,RTMP协议最低可达3~4s左右。
-
工作过程:
- 编码:以 H.264 格式对图像进行编码,以 MP3 或者 HE-AAC 对声音进行编码,最终打包到 MPEG-2 TS(Transport Stream)容器之中;
- 分割:把编码好的 TS 文件等长切分成后缀为 ts 的小文件,并生成一个 .m3u8 的纯文本索引文件(index file);浏览器使用的是 m3u8 文件。m3u8 跟音频列表格式 m3u 很像,可以简单的认为 m3u8 就是包含多个 ts 文件的播放列表。
- 播放器按顺序逐个播放,全部放完再请求一下 m3u8 文件,获得包含最新 ts 文件的播放列表继续播,周而复始。整个直播过程就是依靠一个不断更新的 m3u8 和一堆小的 ts 文件组成,m3u8 必须动态更新,ts 可以走 CDN。
左侧inputs视频源格式和视频传输到server方式任意
-
具体实现:
苹果的设备都支持hls,直接设置video src为m3u8文件,其他不支持hls协议的设备使用hls.js。
hls.js 将ts容器转换成fmp4(MSE需要的处理格式),video可以使用MediaSource对象播放。
DASH
- 是什么:Dynamic Adaptive Streaming over HTTP,基于HTTP的动态自适应流,一种自适应比特率流技术,使高质量流媒体可以通过传统的HTTP网络服务器以互联网传递
- 与HLS异同:
- 相同:都是使用manifest描述视频信息和播放列表,然后通过HTTP自适应请求合适片段
- 不同:DASH国际标准,支持任何编码,可以使用vp9编码的webm格式。HLS属于苹果公司
- 具体实现:浏览器中播放可以使用dash.js,也基于MSE。DASH索引文件是.mpd(Media Presentation Description)结尾的xml文件
FLV.js
- 是什么:纯js写的HTML5 FLV(FLash Video)播放器,不需要Flash播放器,依赖MSE。
- 做了什么:
- HTML5原生仅支持播放mp4/webm格式,flv.js实现了在html5上播放flv视频,具体是将flv封装成fmp4视频格式,交给MSE播放。
- 低延迟http flv播放,不依赖flash
- 为什么:
- flash不再支持
- 对比flv/mp4封装格式,可以发现flv十分简洁,mp4内部box结构复杂有太多冗余数据,flv天生具备流式特征适合网络流传输。
mpegts:flv已不再维护,使用mpegts,支持播放FLV、MPEG-TS、H265
整体流程以及前端实现
- H5视频录制和推流
- 调用window.navigator.webkitGetUserMedia(),获取用户的PC摄像头视频数据。
- 将获取到视频流数据转换成window.webkitRTCPeerConnection(一种视频流数据格式)。
- 利用 WebScoket将视频流数据传输到服务端。
- 直播流转换、编码推流:流处理
- H5直播视频播放:拉流
性能优化:
- HLS卡顿:server做好分片,ts文件存在cdn上
斗鱼直播技术
HTTP+P2P FLV拉流
-
是什么:斗鱼使用HTTP-FLV方式拉流实现直播,视频流格式为.xs,不是.flv的原因是不完全用HTTP拉流,使用CDN和P2P两种方式拉流,.xs是一个子flv流。
-
如何实现:
- 进入直播间首先请求完整Flv流,等P2P连接建立完成切换成子流(P2P连接比较慢)
- 将一个完整的直播流进行切片,分成一个个小视频分片,将分片分成多个子流,通过HTTP从CDN拉一路子流,通过P2P从其他用户拉其他子流。
-
为什么:省钱,流量费较贵。
-
缺点:复杂度升高,直播延迟较高(不适用于低延迟直播场景)
直播时移
- 是什么:点击进度条播放指定时间的视频
- 怎么实现:斗鱼直播时移基于HLS,点进度条将视频流从FLV切换成HLS,走切换后时间的HLS拉流即可。
参考: