LS (HTTP Live Streaming),Apple的動態碼率自適應技術。主要用于PC和Apple終端的音視頻服務。包括一個m3u(8)的索引文件,TS媒體分片文件和key加密串文件。
HLS (HTTP Live Streaming)
常用的流媒體協議主要有 HTTP 漸進下載和基于 RTSP/RTP 的實時流媒體協議,這二種基本是完全不同的東西,目前比較方便又好用的是用 HTTP 漸進下載方法。在這個中 apple 公司的 HTTP Live Streaming 是這個方面的代表。它最初是蘋果公司針對iPhone、iPod、iTouch和iPad等移動設備而開發的流.現在見到在桌面也有很多應用了,HTML5 是直接支持這個。
但是HLS協議的小切片方式會生成大量的文件,存儲或處理這些文件會造成大量資源浪費。如果要實現數天的時移,索引量將會是個巨額數字,并明顯影響請求速度。因此,HLS協議對存儲I/O要求相當苛刻。對此,也有公司提出了非常好的解決方案。
新型點播服務器系統,獨創了內存緩存數據實時切片技術,顛覆了這種傳統實現方法,從根本上解決了大量切片的碎片問題,使得單臺服務器的切片與打包能力不再是瓶頸。其基本原理如下:
不將TS切片文件存到磁盤,而是存在內存當中,這種技術使得服務器的磁盤上面不再會有“數以噸計”的文件碎片,極大減少了磁盤的I/O次數,延長了服務器磁盤的使用壽命,極大提高了服務器運行的穩定性。同時,由于使用這種技術,使得終端請求數據時直接從服務器的內存中獲取,極大提高了對終端數據請求的反應速度,優化了視頻觀看體驗。
使用下面兩個工具
1、ffmpeg(下載地址:http://ffmpeg.org/download.html)
ffmpeg用來負責把直播流(RTSP)切片成*.ts文件
主要參數:
-i 設定輸入流
-f 設定輸出格式
-ss 開始時間
視頻參數:
-b 設定視頻流量,默認為200Kbit/s
-r 設定幀速率,默認為25
-s 設定畫面的寬與高
-aspect 設定畫面的比例
-vn 不處理視頻
-vcodec 設定視頻編解碼器,未設定時則使用與輸入流相同的編解碼器
-keyint_min 60 最小關鍵幀間隔
-g 60 GOP 長度
-sc_threshold 0 根據視頻的運動場景,自動為你添加額外的I 幀,所以會導致你編出來的視頻關鍵幀間隔不是你設置的長度,
這是只要將它設為0
音頻參數:
-ar 設定采樣率
-ac 設定聲音的Channel 數
-acodec 設定聲音編解碼器,未設定時則使用與輸入流相同的編解碼器
-an 不處理音頻
----------------------------------------------------分隔線----------------------------------------------------
主要參數
-i 設定輸入檔名。
-f 設定輸出格式。
-y 若輸出檔案已存在時則覆蓋檔案。
-fs 超過指定的檔案大小時則結束轉換。
-ss 從指定時間開始轉換。
-title 設定標題。
-timestamp 設定時間戳。
-vsync 增減Frame 使影音同步。
影像參數
-b 設定影像流量,默認為200Kbit/秒。( 單位請參照下方注意事項)
-r 設定FrameRate 值,默認為25。
-s 設定畫面的寬與高。
-aspect 設定畫面的比例。
-vn 不處理影像,于僅針對聲音做處理時使用。
-vcodec 設定影像影像編解碼器,未設定時則使用與輸入檔案相同之編解碼器。
聲音參數
-ab 設定每Channel(最近的SVN 版為所有Channel 的總合)的流量。( 單位請參照下方注意事項)
-ar 設定采樣率。
-ac 設定聲音的Channel 數。
-acodec 設定聲音編解碼器,未設定時與影像相同,使用與輸入檔案相同之編解碼器。
-an 不處理聲音,于僅針對影像做處理時使用。
-vol 設定音量大小,256 為標準音量。(要設定成兩倍音量時則輸入512,依此類推。)
注意事項
以-b 及ab 參數設定流量時,根據使用的ffmpeg 版本,須注意單位會有kbits/sec 與bits/sec 的不同。(可用ffmpeg -h 顯
示說明來確認單位。)
例如,單位為bits/sec 的情況時,欲指定流量64kbps 時需輸入‘ -ab 64k ’;單位為kbits/sec 的情況時則需輸入‘ -ab 64 ’。
以-acodec 及-vcodec 所指定的編解碼器名稱,會根據使用的ffmpeg 版本而有所不同。例如使用AAC 編解碼器時,會有輸入aac
與libfaac 的情況。此外,編解碼器有分為僅供解碼時使用與僅供編碼時使用,因此一定要利用ffmpeg -formats 確認輸入的
編解碼器是否能運作。
2、WEB服務器(IIS,Apache,Nginx)分發切片
web服務器配置在這里就不多說了。
demo:http://live.16it.wang
如有需要源碼的可以聯系我:519468341
享 | 劉博(又拍云多媒體開發工程師)
又小拍:
如何實現HTML5直播技術是直播創業團隊一直想要攻克的難題。12月1日20:00,深度參與“又拍直播云”開發的工程師劉博就如何利用WebSocket+MSE實現HTML5直播在微信群里進行了分享。小拍馬不停蹄將劉博的分享內容整理成了文字,并插入一些PPT便于大家了解。全文整理如下:
下面就是分享內容啦~
當前為了滿足比較火熱的移動Web端直播需求,一系列的HTML5直播技術迅速的發展起來。
常見的可用于HTML5的直播技術有HLS、WebSocket與WebRTC。今天我向大家介紹WebSocket與MSE相關的技術要點,并在最后通過一個實例來展示具體用法。
分享大綱
⊙WebSocket協議介紹
⊙WebSocket Client/Server API介紹
⊙MSE介紹
⊙fMP4介紹
⊙Demo展示
WebSocket
通常的Web應用都是圍繞著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握手
為了更方便地部署新協議,HTTP/1.1引入了Upgrade機制,使得客戶端和服務端之間可以借助已有的HTTP語法升級到其它協議。這個機制在RFC7230的6.7 Upgrade一節中有詳細描述。
要發起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 Upgrade響應的狀態碼是101,并且響應正文可以使用新協議定義的數據格式。
WebSocket握手就利用了這種HTTP Upgrade機制。一旦握手完成,后續數據傳輸直接在TCP上完成。
WebSocket JavaScript API
目前主流的瀏覽器提供了WebSocket的API接口,可以發送消息(文本或者二進制)給服務器,并且接收事件驅動的響應數據。
Step1. 檢查瀏覽器是否支持WebSocket
if(window.WebSocket) {
// WebSocket代碼
}
Step2. 建立連接
var ws = new WebSocket('ws://localhost:8327');
Step3. 注冊回調函數以及收發數據
分別注冊WebSocket對象的onopen、onclose、onerror以及onmessage回調函數。
通過ws.send()來進行發送數據,這里不僅可以發送字符串,也可以發送Blob或ArrayBuffer類型的數據。
如果接收的是二進制數據,需要將連接對象的格式設為blob或arraybuffer。
ws.binaryType = 'arraybuffer';
WebSocket Golang API
服務器端WebSocket庫我推薦使用Google自己的golang.org/x/net/websocket,可以非常方便的與net/http一起使用。也可以將WebSocket的handler function通過websocket.Handler轉換成http.Handler,這樣就可以跟net/http庫一起使用了。
然后通過websocket.Message.Receive來接收數據,通過websocket.Message.Send來發送數據。
具體代碼可以看下面的Demo部分。
MSE
在介紹MSE之前,我們先看看HTML5<audio>和<video>有哪些限制。
HTML5<audio>和<video>標簽的限制
不支持流
不支持DRM和加密
很難自定義控制, 以及保持跨瀏覽器的一致性
編解碼和封裝在不同瀏覽器支持不同
MSE是解決HTML5的流問題。
Media Source Extensions(MSE)是Chrome、Safari、Edge等主流瀏覽器支持的一個新的Web API。MSE是一個W3C標準,允許JavaScript動態構建<video>和<audio>的媒體流。它定義了對象,允許JavaScript傳輸媒體流片段到一個 HTMLMediaElement。
通過使用MSE,你可以動態地修改媒體流而不需要任何插件。這讓前端JavaScript可以做更多的事情—— 在JavaScript進行轉封裝、處理,甚至轉碼。
雖然MSE不能讓流直接傳輸到media tags上,但是MSE提供了構建跨瀏覽器播放器的核心技術,讓瀏覽器通過JavaScript API來推音視頻到media tags上。
Browser Support
通過caniuse來檢查是否瀏覽器支持情況。
通過MediaSource.isTypeSupported()可以進一步地檢查codec MIME類型是否支持。
fMP4
比較常用的視頻封裝格式有WebM和fMP4。
WebM和WebP是兩個姊妹項目,都是由Google贊助的。由于WebM是基于Matroska的容器格式,天生是流式的,很適合用在流媒體領域里。
下面著重介紹一下fMP4格式。
我們都知道MP4是由一系列的Boxes組成的。普通的MP4的是嵌套結構的,客戶端必須要從頭加載一個MP4文件,才能夠完整播放,不能從中間一段開始播放。
而fMP4由一系列的片段組成,如果服務器支持byte-range請求,那么,這些片段可以獨立的進行請求到客戶端進行播放,而不需要加載整個文件。
為了更加形象的說明這一點,下面我介紹幾個常用的分析MP4文件的工具。
gpac,原名mp4box,是一個媒體開發框架,在其源碼下有大量的媒體分析工具,可以使用testapps;
mp4box.js,是mp4box的Javascript版本;
bento4,一個專門用于MP4的分析工具;
mp4parser,在線MP4文件分析工具。
fragment mp4 VS non-fragment mp4
下面是一個fragment mp4文件通過mp4parser(http://mp4parser.com)分析后的截圖 ▽
下面是一個non-fragment mp4文件通過mp4parser分析后的截圖 ▽
我們可以看到non-fragment mp4的最頂層box類型非常少,而fragment mp4是由一段一段的moof+mdat組成的,它們已經包含了足夠的metadata信息與數據, 可以直接seek到這個位置開始播放。也就是說fMP4是一個流式的封裝格式,這樣更適合在網絡中進行流式傳輸,而不需要依賴文件頭的metadata。
Apple在WWDC 2016大會上宣布會在iOS 10、tvOS、macOS的HLS中支持fMP4,可見fMP4的前景非常的好。
值得一提的是,fMP4、CMAF、ISOBMFF其實都是類似的東西。
MSE JavaScript API
從高層次上看,MSE提供了
一套 JavaScript API 來構建 media streams
一個拼接和緩存模型
識別一些 byte 流類型:
WebM
ISO Base Media File Format
MPEG-2 Transport Streams
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(http://nickdesaulniers.github.io/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 Live Demo
展示利用MSE和WebSocket實現一個直播服務
后端代理一條HTTP-FLV直播流,通過WebSocket發送給MSE,進行播放
前端MSE部分做了很多工作, 包括將flv實時轉封裝成了fMP4,這里引用了videojs-flow的實現
Q & A
Q1:對于沒有公網iIP的客戶如何通過RTMP協議推流?
A1:用戶客戶端進行RTMP推流,不需要公網IP,推到直播系統分配給你的地址就可以了。
Q2:MSE客戶端做很多東西,可以轉碼、解碼, 這個會有性能問題嗎? 還有這個技術,目前有公司在大批量用嗎?
A2:目前該技術在實驗階段,轉封裝的話,對性能要求不高,我們在各自型號的手機上測試都沒有問題。目前除了微信內置瀏覽器對MSE支持不好,大部分瀏覽器對MSE支持都比較好。
Q3:沒做過相關內容,能簡單介紹一下HTTP-FLV么?
A3:HTTP-FLV就是將FLV流以HTTP長連接的形式分發出去,目前在各大直播平臺都用的比較多。大家可以關注下又拍云微信公眾賬號,之前專門有一篇文章介紹HTTP-FLV。
Q4:不大了解HTTP-FLV,既然是長時間的狀態性連接,為什么不用tcp/socket呢?
A5: FLV不能在<video>標簽直接播放,所以需要通過MSE轉封裝成MP4,再吐到<video>標簽進行播放。
Q5:嗶哩嗶哩H5播放器是基于WebSocket與MSE技術實現的嘛?
A5:B站開源的flv.js是一個非常好的項目,是基于 MSE 實現的,實時性做的也比較好,B 站自己已經在網站播放器上使用了。
Q6:VLC器播放和網頁播放,哪個快啊?
A6:播放器端延時,一個重要指標是播放器的緩存區大小。VLC的默認緩存區比較大,所以,VLC通常延時會大一些。
Q7:可以介紹下秒開技術么,以及秒開的原理?
A7:秒開可以在服務器端多緩存一個GoP來實現,這樣播放器請求的第一幀能保證是I幀,可以立即播放,以此達到秒開的效果.
Refs
WebSocket
rfc6455
HTTP Upgrade
WebSocket API
MDN WebSocket
videojs-flow
MSE
W3C
MDN MSE
HTML5 Codec MIME
著直播行業大火,游戲、樂秀、教育、發布會等直播類產品層出不窮,能夠滿足各方人員的需求。在直播中,總能在其中找到適合自己的產品內容。喜歡玩游戲的可以看游戲直播,想學點工作技能的,也可以觀看大牛現場授課,甚至你能通過直播跟各大主播實時互動。看了這么多直播,你好像發現了一個小秘密,不同類型的直播延時有所不同,像與主播實時互動的一般延遲比較短,而相對的,在線教育這一類就比較長了。這就是我今天想給大家講解的一些東西,除了網絡環境以外,對延時影響較大的就是直播架構中選擇的直播協議。接下來,我就給大家簡單介紹下常見的直播協議吧。
國內常見的直播協議有幾個:RTMP、HLS、HTTP-FLV,下面我們來一一介紹。
RTMP,全稱 Real Time Messaging Protocol,即實時消息傳送協議。Adobe 公司為 Flash 播放器和服務器之間音視頻數據傳輸開發的私有協議。工作在 TCP 之上的明文協議,默認使用端口 1935。協議中的基本數據單元成為消息(Message),傳輸的過程中消息會被拆分為更小的消息塊(Chunk)單元。最后將分割后的消息塊通過 TCP 協議傳輸,接收端再反解接收的消息塊恢復成流媒體數據。
RTMP 主要有以下幾個優點:RTMP 是專為流媒體開發的協議,對底層的優化比其它協議更加優秀,同時它 Adobe Flash 支持好,基本上所有的編碼器(攝像頭之類)都支持 RTMP 輸出。現在 PC 市場巨大,PC 主要是 Windows,Windows 的瀏覽器基本上都支持 Flash。另外RTMP適合長時間播放,曾經有過測試,聯系 100 萬秒,即 10 天多連續播放沒有出現問題。最后 RTMP 的延遲相對較低,一般延時在 1-3s 之間,一般的視頻會議,互動式直播,完全是夠用的。
當然 RTMP 并沒有盡善盡美,它也有不足的地方。一方面是它是基于 TCP 傳輸,非公共端口,可能會被防火墻阻攔;另一方面,也是比較坑的一方面是 RTMP 為 Adobe 私有協議,很多設備無法播放,特別是在 iOS 端,需要使用第三方解碼器才能播放。
FLV (Flash Video) 是 Adobe 公司推出的另一種視頻格式,是一種在網絡上傳輸的流媒體數據存儲容器格式。其格式相對簡單輕量,不需要很大的媒體頭部信息。整個 FLV 由 The FLV Header, The FLV Body 以及其它 Tag 組成。因此加載速度極快。采用 FLV 格式封裝的文件后綴為 .flv。
而我們所說的 HTTP-FLV 即將流媒體數據封裝成 FLV 格式,然后通過 HTTP 協議傳輸給客戶端。
HTTP-FLV 依靠 MIME 的特性,根據協議中的 Content-Type 來選擇相應的程序去處理相應的內容,使得流媒體可以通過 HTTP 傳輸。相較于 RTMP 協議,HTTP-FLV 能夠好的穿透防火墻,它是基于 HTTP/80 傳輸,有效避免被防火墻攔截。除此之外,它可以通過 HTTP 302 跳轉靈活調度/負載均衡,支持使用 HTTPS 加密傳輸,也能夠兼容支持 Android,iOS 的移動端。
說了這么多優點,也來順便說下 HTTP-FLV 的缺點,由于它的傳輸特性,會讓流媒體資源緩存在本地客戶端,在保密性方面不夠好。因為網絡流量較大,它也不適合做拉流協議。
上述兩個協議都是有Adobe公司推出的,而下面要講的 HLS (HTTP Live Streaming) 則是蘋果公司基于 HTTP 的流媒體傳輸協議。主要應用于 iOS 設備,包含(iPhone, iPad, iPod touch) 以及 Mac OSX 提供音視頻直播服務和錄制內容(點播)等服務。
相對于常見的流媒體協議,HLS 最大的不同在于它并不是一下請求完整的數據流。它會在服務器端將流媒體數據切割成連續的時長較短的 ts 小文件,并通過 M3U8 索引文件按序訪問 ts 文件。客戶端只要不停的按序播放從服務器獲取到的文件,從而實現播放音視頻。
相較 RTMP 而言,使用 HLS 在 HTML5 頁面上實現播放非常簡單:
直接:
或者:
HLS 的優勢:
HLS 的劣勢:
RTMP 協議為流媒體而設計,在推流中用的比較多,同時大多 CDN 廠商支持RTMP 協議。
HTTP-FLV 使用類似 RTMP流式的 HTTP 長連接,需由特定流媒體服務器分發的,兼顧兩者的優點。以及可以復用現有 HTTP 分發資源的流式協議。它的實時性和 RTMP 相等,與 RTMP 相比又省去了部分協議交互時間,首屏時間更短,可拓展的功能也更多。
HLS 作為蘋果提出的直播協議,在 iOS 端占據了不可撼動的地位,Android 端也同時提供相應的支持。
又拍云一站式直播解決方案基于又拍云 CDN,支持 RTMP、HTTP-FLV 和 HLS 三大直播協議,并且通過智能調度、鏈路保障、追幀處理、丟幀處理以及業界首創的 HLS+ 技術,將 RTMP、HTTP-FLV 直播延遲控制在1秒內,將 HLS 直播延時控制在 4 秒左右。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。