流媒體傳輸是“直播”中至關(guān)重要的環(huán)節(jié),在網(wǎng)絡(luò)傳輸媒體流的時(shí)候有著不同的流媒體傳輸協(xié)議。
做了一些小調(diào)查,在整個(gè)“直播”產(chǎn)品構(gòu)建的過(guò)程中,應(yīng)用最廣的兩個(gè)流媒體傳輸協(xié)議就是 RTMP 和 HLS 兩個(gè)協(xié)議,其中 RTMP 在國(guó)內(nèi)直播發(fā)展的長(zhǎng)河中扮演著極其重要的角色,各個(gè)平臺(tái)與 RTMP 的“結(jié)合”已變得很成熟。
兩種不同的流媒體傳輸協(xié)議
RTMP
RTMP (Real Time Messaging Protocol) :實(shí)時(shí)消息傳輸協(xié)議,屬應(yīng)用層協(xié)議,基于傳輸層 TCP 協(xié)議長(zhǎng)鏈接來(lái)進(jìn)行傳輸,有 N 多變種,最早由 Macromedia 公司開發(fā),而后 Macromedia 被 Adobe 公司收購(gòu)。
RTMP 的主要特性
- 市場(chǎng)廣闊,基本所有的編碼器都支持 RTMP;
- 延遲低,RTMP 的實(shí)時(shí)性在 1~3 秒左右,即使經(jīng)過(guò) CDN (Content Delivery Network 內(nèi)容分發(fā)網(wǎng)絡(luò))多層分發(fā)也能保證實(shí)時(shí)性在 3 秒左右,此特性已經(jīng)完全滿足現(xiàn)在的直播產(chǎn)業(yè)需求;
- 穩(wěn)定性、可靠性高,基于 TCP 保證媒體流在傳輸?shù)倪^(guò)程中不會(huì)丟失,但這也是缺點(diǎn),在網(wǎng)絡(luò)狀態(tài)不好的時(shí)候,服務(wù)器會(huì)等待數(shù)據(jù),這個(gè)過(guò)程會(huì)出現(xiàn)延遲,等包接受完整再將完整的包推給 Client 端;
- HTML5 播放需要插件,并且跨平臺(tái)較差
RTMP 原理
RTMP 通過(guò)握手的方式建立 RTMP Connection,
若 Client 端要按序發(fā)送 C0、C1、C2,Server 端按序發(fā)送 S0、S1、S2,大致過(guò)程如下圖:

為保證數(shù)據(jù)的有效性,無(wú)論是 Client 端還是 Server 端都會(huì)等待一次 Chunk 接收完畢再進(jìn)行下一次通信。
- Chunk 是 RTMP 在進(jìn)行數(shù)據(jù)流傳輸過(guò)程中的最小單位,每個(gè) Chunk 由 Message 拆分,當(dāng)然也可能每個(gè)獨(dú)立的 Message 作為 Chunk 進(jìn)行傳輸;
- Message 是滿足 RTMP 并且經(jīng)過(guò)「格式化」的數(shù)據(jù),Message 有著自己的“數(shù)據(jù)結(jié)構(gòu)”,標(biāo)識(shí)每個(gè) Message 的字段為 Message ID,該字段是拆分成 Chunk 和還原 Chunk 的憑借。
HLS
HLS (HTTP Live Streaming):是 Apple 公司基于 HTTP 實(shí)現(xiàn)的流媒體傳輸協(xié)議。
HLS 的主要特性
- 對(duì)于 Apple 自家平臺(tái)的硬件設(shè)備上最大化支持,不用自行開發(fā)特有播放器,在 Android 的設(shè)備上支持表現(xiàn)略差;
- HLS 會(huì)將視頻源分成索引文件和視頻切片進(jìn)行傳輸,所以可以實(shí)現(xiàn)平滑的切換碼率,但這也是 HLS 一個(gè)致命的缺點(diǎn),這種機(jī)制會(huì)導(dǎo)致 HLS 的實(shí)時(shí)性很差,延遲可達(dá)到數(shù)十秒;
- 基于 HTTP ,不存在防火墻和代理的問(wèn)題,但需要和 Server 端不斷進(jìn)行連接通信;
- HTML5 可以直接播放直播鏈接,不需任何獨(dú)立的 Application 支持。
HLS 主要原理
HLS 傳輸內(nèi)容包括:m3u8 索引文件以及 ts 視頻切片。
無(wú)論是直播還是點(diǎn)播,HLS 協(xié)議都將視頻源按策略分割成一個(gè)索引文件和若干 ts 視頻切片,由索引文件管理視頻切片,Server 則不斷的將這些最視頻切片推給 Client 端,所以對(duì)于直播而言,Client 會(huì)不斷接受從 Server 端推過(guò)來(lái)的視頻切片,以“點(diǎn)播”的方式達(dá)到直播的效果,但由于切片的過(guò)程會(huì)造成高延遲,所以在國(guó)內(nèi)的直播產(chǎn)業(yè)中并不被看好,即使是將 ts 文件的切片設(shè)置最小,表現(xiàn)也仍舊不如 RTMP。
RTMP Vs. HLS
通過(guò)上面的介紹,對(duì)于視頻采集 -> 處理/編碼 -> 推流分發(fā) -> Client 端播放整個(gè)過(guò)程中 RTMP 和 HLS 的工作內(nèi)容大致如下:


與此同時(shí),RTMP 既能推流也能拉流,而 HLS 只能拉流。
所以根據(jù)各自的特點(diǎn),RTMP 更適用于實(shí)時(shí)性、互動(dòng)性較高的直播,HLS 更適合 HTTP 點(diǎn)播。
本地流媒體傳輸實(shí)踐
準(zhǔn)備
a. 安裝 HomeBrew,終端鍵入:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
升級(jí)
Homebrew:brew update
b. 推流搭建本地服務(wù)器需 nginx,終端鍵入:brew tap denji/nginx
使用
brew tap homebrew/nginx會(huì)報(bào) Error: homebrew/nginx was deprecated. This tap is now empty as all its formulae were migrated.
c. 安裝 rtmp 模塊,終端鍵入:
brew install nginx-full --with-rtmp-module
d. 此時(shí),nginx 和 rtmp 模塊都已安裝完成,終端鍵入:nginx (權(quán)限問(wèn)題鍵入 sudo nginx),啟動(dòng) nginx 服務(wù),瀏覽器鍵入 http://localhost:8080 出現(xiàn) Welcome to nginx! 歡迎語(yǔ)表示安裝成功。
重啟 nginx 服務(wù)命令:
nginx -s reload
停止 nginx 服務(wù)命令:nginx -s stop
有序退出 nginx 服務(wù)命令:nginx -s quit
e. 配置 nginx.conf (HLS + RTMP)
nginx.conf 路徑為:/usr/local/etc/nginx/nginx.conf
文本打開該文件在 http 作用域內(nèi)鍵入:
location /hls {
#Serve HLS config
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /usr/local/var/www;
add_header Cache-Control no-cache;
}
在最后鍵入:
rtmp {
server {
listen 1935;
application rtmplive {
live on;
max_connections 1024;
}
application hls{
live on;
hls on;
hls_path /usr/local/var/www/hls;
hls_fragment 1s;
}
}
}
RTMP 默認(rèn)端口 1935,rtmp 配置信息不屬于任何作用域,寫在任何作用域里都會(huì)報(bào)錯(cuò) nginx: [emerg] "rtmp" directive is not allowed here in /etc/nginx/nginx.conf:起始行數(shù)
配置完畢重啟 nginx 服務(wù)。
f. 安裝 ffmepg 工具,終端鍵入:
brew install ffmpeg
g. 安裝支持 HLS 和 RTMP 的播放器,VLC 和 mpv 都可,在此用的是 mpv。
實(shí)踐本地推流至 nginx
一切都準(zhǔn)備就緒后,即可實(shí)踐推流服務(wù),終端鍵入:
ffmpeg -re -i 目標(biāo)視頻.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 rtmp://localhost:1935/xx/xx
推流命令具體參數(shù):
| 參數(shù) | 說(shuō)明 |
|---|---|
| -vcodec libx264 | 視頻的編碼器為 H.264 |
| vprofile baseline | 設(shè)置音視頻編碼器的類 |
| -acodec aac | 指定聲音的編碼器為AAC |
| -ar 44100 | 音頻編解碼器的采樣率,單位為赫茲 |
| -ac 1 | 設(shè)置音頻編解碼器的聲道數(shù)目 |
| -f flv | 強(qiáng)制設(shè)定輸入和輸出文件格式為 flv 格式 |
| -s 1280x720 | 分辨率 |
推送過(guò)程會(huì)在終端顯示如下:

推送完畢如下:

RTMP 拉流
推流至 RTMP 服務(wù)器生成地址: rtmp://localhost:1935/xx/xx
此時(shí)在 mpv 工具欄 File - Open URL - 鍵入 rtmp://localhost:1935/rtmplive/xx
播放即可播放:

HLS 拉流
推流至 HLS 服務(wù)器生成地址:
http://localhost:8080/hls/xx.m3u8
在瀏覽器或者 mpv 中播放表現(xiàn)如下:


實(shí)踐遠(yuǎn)程推流
手頭剛好有個(gè)科學(xué)上網(wǎng)買的 VPS 正好可以當(dāng)作遠(yuǎn)程服務(wù)器使用,新加坡節(jié)點(diǎn),但應(yīng)該也是繞到美國(guó)的線路,所以可想而知,播放過(guò)程異常的艱辛,十幾秒播放一幀已經(jīng)算是給面子了,但好在已經(jīng)有成果。
我的服務(wù)器是 CentOS 系統(tǒng),可能安裝模塊的命令和 Ubuntu 系統(tǒng)有細(xì)小的差別。
在此連接 VPS 的工具選擇的是 ShellCraft,macOS 自帶的終端工具也可以連接,可視化 CentOS 服務(wù)器的客戶端為 FileZilla,添加 VPS 站點(diǎn)步驟在本文最后。
準(zhǔn)備
a. 安裝 git,CentOS 系統(tǒng)下安裝 Git 的命令為:
yum install git
b. clone srs,鍵入:
git clone srs
srs 的作者將它定義為直播服務(wù)器集群,更多的信息,請(qǐng)點(diǎn) srs Github 主頁(yè)。
若 clone 過(guò)程中出現(xiàn) Please make sure you have the correct access rights and the repository exists. 說(shuō)明,SSH Key 出現(xiàn)了問(wèn)題導(dǎo)致無(wú)法正常 git 操作,解決如下依次鍵入:
git config --global user.name "yourname"git config --global user.email "your@email.com"ssh-keygen -t rsa -C "your@email.com"vi /root/.ssh/id_rsa.pub- 將該文件的一大串信息復(fù)制并添加到 Github 個(gè)人設(shè)置里新建的 SSH Key 中。
c. cd 到 srs 目錄,依次鍵入:
git checkout 2.0release
git pull
cd trunk
d. 配置遠(yuǎn)程服務(wù)器,該過(guò)程極其漫長(zhǎng),鍵入:
./configure --disable-all --with-ssl --with-nginx --with-hls --with-http-callback --with-http-server --with-http-api --with-ffmpeg --with-transcode --with-librtmp --with-dvr && make
出現(xiàn)下圖所示表示配置環(huán)境完成:

e. 執(zhí)行配置,鍵入
./objs/srs -c conf/srs.conf

實(shí)踐遠(yuǎn)程推流與拉流
推流拉流過(guò)程和本地推流命令一樣,只不過(guò)服務(wù)器地址的 localhost:接口 要換成服務(wù)器地址,倘若出現(xiàn)如下錯(cuò)誤信息則說(shuō)明需要關(guān)閉 CentOS 的防火墻:

錯(cuò)誤信息:
[tcp @ 0x7fd255c02b80] Connection to tcp://207.148.66.232:1935 failed: Connection refused
[rtmp @ 0x7fd255d0b100] Cannot open connection tcp://207.148.66.232:1935
rtmp://207.148.66.232/live/demo: Connection refused
關(guān)閉防火墻的命令為:systemctl stop firewalld.service。
FileZilla 添加站點(diǎn)
File -> Site Manager 彈出如下界面:

New Site -> General -> Protocol 選擇如圖所示的 SFTP,Logon Type 為 Normal,Host、User 以及 Password 自行填寫,Connect。
界面如下:

??done!??