流媒体服务
完整的流媒体一般包含推流端,服务器端,拉流端,其中推流和拉流可以使用不同的通讯协议,一般使用的也是不同的。
总体
推流端
- 设备采集数据
- 将采集的数据进行处理,比如水印,美颜,特效等
- 对数据进行编码压缩
- 分发数据
拉流端,功能比较简单,分成核心需求和应对特定业务的业务需求
- 核心需求,通常使用几个关键性的指标评价,比如延时,是否卡顿,是否清晰等
- 业务需求,点赞,送礼,聊天等
服务器端
服务器端最核心的功能就是接收推流端的数据再转发给观众,除此之外,还有诸如视频连线,实时转码,自动鉴黄等特定的业务需求
关键问题
- 怎么录制直播视频
- 怎么实时上传直播视频
- 怎么播放直播视频
- 主播和观众之间的交互
- 怎么兼容各种终端
完整直播系统搭建的主要知识点如下(以 IOS 为例)
实践问题
对于一款商业级的直播产品,需要考虑很多方面,不单单是技术,比如运营,安全性和隐私政策
1. 技术
对完整直播流程的技术实现已经很成熟,各种 SDK,云服务应有尽有,对于小型初创公司,选择第三方的服务是明智的选择,无论是在效率上还是经济上,但对于注重于直播领域的大公司来说,选择自研未尝不是个好方案,因为对于选择第三方的 SDK 而言,自研拥有更多的灵活性和可控性。
2. 运营
因为直播本身带有很强的同步属性,对带宽的要求是非常大的,同时 CDN 分布对用户端拉流的流畅性也是至关重要的,这就导致必须在这两方面有大量的资金投入,以带宽为例, 2 万人同时在线, 手机码率在 600KB, 每个月的带宽费用至少在 30 万左右. 根据欢聚时代(YY)15 年四季度财务报, 他们的带宽成本为人民币 1.611 亿元, 折合每月 5000 万+. 人力成本+渠道支出和其他支出就不详谈了,据网上的数据,斗鱼 TV 运营成本为 3 亿人民币,战旗 TV 为 1.5 亿人民币,龙珠为 1.2 亿人民币,虎牙为 3000 万 + 人民币
流媒体协议
1. webRTC (web real-time communication)
webRTC 作为一项 web 标准在 2011 年被纳入 W3C 推荐标准,他将和设备交互得接口,例如摄像头,麦克风,封装在 BOM 中,具体是 navigator.mediaDevices 对象,让脚本语言可以访问到硬件设备,同时还发布了一系列得 API,让开发人员可以基于其上进行直播流得实现
使用
async function playVideoFromCamera() {
try {
//声明配置对象
const constraints = { video: true, audio: true };
//打开设备并获取连接流
const stream = await navigator.mediaDevices.getUserMedia(constraints);
//获取显示video标签
const videoElement = document.querySelector("video#localVideo");
//设置标签数据来源
videoElement.srcObject = stream;
} catch (error) {
console.error("Error opening video camera.", error);
}
}
<html>
<head><title>Local video playback</video></head>
<body>
<video id="localVideo" autoplay playsinline controls="false"/>
</body>
</html>
在实际场景中,设备不总是来源于电脑,还可能通过诸如 USB 等外接,当设备得来源变化时,就会触发相应的事件,开发者可以监听相应的事件来对情况进行控制。
另外,webRTC 还拥有配置功能,可以根据 MediaTrackConstraint 对象配置响应得限制,主要是对 audio 和 video 得限制,例如
{
"video": {
"width": 640,
"height": 480
}
}
以上仅仅是数据采集,对于直播,还需要数据分发,webRTC 提供了 RTCPeerConnection 对象,该对象可以确认连接得双方,并发送数据
async function makeCall() {
const configuration = {
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
};
const peerConnection = new RTCPeerConnection(configuration);
signalingChannel.addEventListener("message", async (message) => {
if (message.answer) {
const remoteDesc = new RTCSessionDescription(message.answer);
await peerConnection.setRemoteDescription(remoteDesc);
}
});
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
signalingChannel.send({ offer: offer });
}
const remoteStream = MediaStream();
const remoteVideo = document.querySelector("#remoteVideo");
remoteVideo.srcObject = remoteStream;
peerConnection.addEventListener("track", async (event) => {
remoteStream.addTrack(event.track, remoteStream);
});
协议
WebRTC 使用 UDP 作为传输层协议,在 WebRTC 中,RTCPeerConnetcion API 负责把获取到的媒体流传输到另外一台视频播放设备,其中涉及到了多种协议。WebRTC 采用SRTP和SRTCP作为其流媒体协议,用于传输音视频,但 SRTP 和 SRTCP 与另外两个协议——RTP 和 RTCP 关系比较密切
RTP
实时传输协议 (Real-time Transport Protocol)是用于 Internet 上针对多媒体数据流的一种传输层协议。RTP 协议详细说明了在互联网上传递音频和视频的标准数据包格式,RTP 协议是建立在 UDP 协议上的。 RTP 由两个紧密链接部分组成: RTP ― 传送具有实时属性的数据;RTP 控制协议(RTCP) ― 监控服务质量并传送正在进行的会话参与者的相关信息。
RTCP
实时传输控制协议(Real-time Transport Control Protocol 或 RTP Control Protocol 或 RTCP)是 RTP 的一个姐妹协议。RTCP 为 RTP 媒体流提供信道外控制。RTCP 本身并不传输数据,但和 RTP 一起协作将多媒体数据打包和发送。RTCP 定期在会话参加者之间传输控制数据。RTCP 的主要功能是为 RTP 所提供的服务质量提供反馈。 RTCP 收集相关媒体连接的统计信息,例如:传输字节数,传输分组数,丢失分组数,单向和双向网络延迟等等。网络应用程序可以利用 RTCP 所提供的信息试图提高服务质量,比如限制信息流量或改用压缩比较小的编解码器。RTCP 本身不提供数据加密或身份认证。SRTCP 可以用于此类用途。
SRTP
安全实时传输协议(Secure Real-time Transport Protocol) ,是在实时传输协议(Real-time Transport Protocol 或 RTP)基础上所定义的一个协议,旨在为单播和多播应用程序中的实时传输协议的数据提供加密、消息认证、完整性保证和重放保护。
SRTCP
安全实时传输控制协议(Secure RTCP 或 SRTCP),类似于 RTP 和 RTCP 之间的关系,SRTP 同样也有一个伴生协议,即为 SRTCP 协议。
HLS
前面说过,适应多终端是直播技术实现得一个难点,不同的系统本身就不一定支持某些协议,比如 webRTC 比较适合 PC 终端,但也要看实现的浏览器本身是否支持,而在移动端,HLS 协议就成为了首选,移动端 iOS 和 Android 都天然支持 HLS 协议,做好视频采集端、视频流推流服务之后,便可以直接在 H5 页面配置 video 标签播放直播视频, HLS 在 PC 端仅支持 safari 浏览器,类似 chrome 浏览器使用 HTML5 video 标签无法播放 m3u8 格式,可直接采用网上一些比较成熟的方案
前导知识
- m3u8 简介
m3u8 是一种基于 HTTP Live Streaming 文件视频格式,它主要是存放整个视频的基本信息和分片(Segment)组成。 M3U8 实际上是一个播放列表,也是以 UTF-8 字符编码的 M3U 文件之一。M3U8 最初是为音频开发的,但后来一些媒体播放器和程序,如 Winamp,KMPlayer,iTunes,VLC 媒体播放器等也可以支持打开 M3U8 文件。
- m3u 文件格式
M3U 文件是一种纯文本文件,可以指定一个或多个多媒体文件的位置,其文件扩展名是“M3U”或者“m3u”。M3U 文件具有多个条目,每个条目的格式可以是以下几种格式之一:
M3U 文件的作用通常是创建指向在线流媒体的播放列表,创建的文件可以轻松访问流媒体。M3U 文件通常作为网站的下载资源、通过 email 收发,并可以收听网络电台。
HLS 协议主要原理
它的工作原理是把整个流分成一个个小的基于 HTTP 的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的 extended M3U (m3u8)playlist文件,用于寻找可用的媒体流。
这种将推流端和拉流端解耦的通信协议非常适合业务场景复杂的直播需求,因为其还需要在服务端进行压缩和解码,此过程中完全可以按照业务需求进行譬如鉴黄,鉴权等功能的添加,更为关键的是,可以根据不同用户的带宽问题进行分发不同码率的视频流,大大提高了灵活性和智能性。
但因为其使用的是短链接 https,缺点也是明显的,就是延时太高,完整的拉流过程包括么 u3u8 的文件下载,以及里面的 ts 文件下载,不包括 dns,tcp 解析的情况下,如果每个 m3u8 的 ts 文件数为 3 ~ 8,ts 播放为 5s,那么延迟为 40,平均 10s 以上延迟。
RTMP
RTMP,实时消息传输协议,Real Time Messaging Protocol,是 Adobe Systems 公司为 Flash 播放器和服务器之间音频、视频和数据传输开发的开放协议。协议基于 TCP,是一个协议族,包括 RTMP 基本协议及 RTMPT/RTMPS/RTMPE 等多种变种。RTMP 是一种设计用来进行实时数据通信的网络协议,主要用来在 Flash/AIR 平台和支持 RTMP 协议的流媒体/交互服务器之间进行音视频和数据通信。
相对于 HLS 来说,具有延时较少的优点,一般为 1-3 秒,因为 RTMP 使用的是 TCP 长连接,一次握手耗时少,但 IOS 平台没有提供原生支持 RTMP 或 HTTP-FLV 的播放器,需要自己开发。
协议 | 原理 | 延时 | 优点 | 使用场景 | |
---|---|---|---|---|---|
HLS | 短链接 Http | 集合一段时间数据生成 ts 切片文件更新 m3u8 文件 | 10s - 30s | 跨平台 | 移动端为主 |
RTMP | 长链接 Tcp | 每个时刻的数据收到后立即发送 | 2s | 延时低、实时性好 | PC+直播+实时性要求高+互动性强 |