背景:此前一直接觸的是RTMP流媒體,前一段時間幫助一個朋友研究了下HLS流媒體,感受挺好玩的。如今把淺薄的嘗試和總結分享給你們。html
一.HLS流媒體點播系統概述
html5
HTTP Live Streaming最初是蘋果公司針對其iPhone、iPod、iTouch和iPad等移動設備而開發的流媒體協議,後來在桌面QuickTime播放器中也獲得了應用。HTTP Live Streaming容許內容提供者經過普通Web服務器向上述客戶端提供接近實時的音視頻流媒體服務,包括直播和點播。HTTP Live Streaming支持將同一節目編碼爲不一樣碼率的多個替換流,客戶端軟件能夠根據網絡帶寬的變化在這些不一樣碼率的替換流之間進行智能切換。此外,HTTP Live Streaming還支持經過媒體加密和用戶認證等方式來達到媒體版權保護。目前HTTP Live Streaming已被提交成爲IETF的Internet-Draft。android
一個典型的HTTP Live Streaming流媒體系統由內容準備(流媒體服務)、內容分發(分發服務器)和客戶端軟件三部分組成,如圖所示ios
1.1 內容準備服務nginx
內容準備服務(流媒體服務器)負責將輸入的音視頻媒體內容轉換成爲適合於內容分發服務進行傳輸的格式。對於視頻源獲取的或者上傳的視利用視頻編碼器轉化爲MPEG-2系統層標準的傳輸流(TS)格式進行輸出。流分割器負責將編碼器輸出的MPEG-2 TS流分割爲一系列連續的、長度均等的小TS文件(後綴名爲.ts),並依次發送至內容分發組件中的Web服務器進行存儲。與此同時,流分割器還需建立一個含有指向這些小TS文件指針的索引文件(後綴爲m3u8),一樣放置於Web服務器之中進行存儲。流分割器還能夠對其生成的每一個小TS文件進行加密,並生成相應的密鑰文件。git
之因此採用MPEG-2 TS格式來對編碼後的媒體流進行統一封裝,是由於它可以將音視頻媒體流嚴格按時序進行交織複用,任意截取和分段後,每個分段均可能不依賴於以前的分段而獨立進行解碼和播放github
1.2內容分發服務web
內容分發服務(分發服務器)用於經過HTTP協議將分割後的小媒體文件及其索引文件遞送至客戶端播放器,能夠採用一個普通的Web服務器(nginx,Apache)來實現。瀏覽器
1.3 客戶端緩存
一般狀況下,客戶端軟件經過訪問Web網頁中的URL連接來獲取和下載一個流媒體會話的索引文件。這個索引文件進一步指定了服務器上當前可用的TS格式媒體文件、解密密鑰和其餘替換流的位置。對於選定的媒體流,客戶端依次下載索引文件中列出的每個可用媒體文件。當這些媒體文件緩衝夠必定數量後,客戶端將它們按順序從新拼裝成一個連貫的TS流,而後發送至播放器進行解碼和呈現。對於加密的媒體文件,客戶端還負責根據索引文件的指引來獲取解密密鑰,提供用戶認證接口,並按需進行解密。
1.4 HTTP Live Streaming協議介紹
索引文件採用擴展的M3U播放列表格式,後綴名爲.m3u8。M3U播放列表是一個由若干文本行組成的文本文件,其中每一行要麼是一個URI,一個空行,或者是一個以註釋符「#」起始的行。每一個URI行指向一個分段的媒體文件,或者一個衍生的索引(播放列表)文件。除了以「#EXT」起始的行是標籤行外,其餘以「#」起始的行是註釋,應予忽略。下面是一個簡單的.m3u8索引文件例子,其所表示的媒體流由3個未加密的長度爲10秒的TS文件組成
#EXT-X-MEDIA-SEQUENCE:0 #EXT-X-TARGETDURATION:10 #EXTINF:10, http://media.example.com/segment1.ts #EXTINF:10, http://media.example.com/segment2.ts #EXTINF:10, http://media.example.com/segment3.ts #EXT-X-ENDLIST
對於視頻點播,直到客戶端碰到索引文件中的#EXT-X-ENDLIST標籤便會中止播放。
二.HLS流媒體系統的優點
部署方便,便於分發:一旦切分完成,以後的分發過程徹底不須要額外使用任何專門軟件,普通的網絡服務器便可,大大下降了 CDN 邊緣服務器的配置要求,可使用任何現成的 CDN。分發使用的協議是最多見 HTTP,代理服務器對這個協議的緩存優化至關成熟。
時移特性好:若是你要在一段長達一小時的視頻中跳轉,若是使用單個 MP4 格式的視頻文件,而且也是用 HTTP 協議,那麼須要代理服務器支持 HTTP range request 以獲取大文件中的一部分。不是全部的代理服務器都對此有良好的支持。而 HTTP Live Streaming 則只須要根據列表文件中的時間軸找出對應的 TS 片斷下載便可,不須要 range request,對代理服務器的要求小不少。全部代理服務器都支持小文件的高效緩存。
自適應碼率流播:效果就是客戶端會根據網絡情況自動選擇不一樣碼率的視頻流,條件容許的狀況下使用高碼率,網絡繁忙的時候使用低碼率,而且自動在兩者間隨意切換。這對移動設備網絡情況不穩定的狀況下保障流暢播放很是有幫助。實現方法是服務器端提供多碼率視頻流,而且在列表文件中註明,播放器根據播放進度和下載速度自動調整。
對網絡環境支持好:HLS能夠穿過任何容許HTTP數據經過的防火牆或者代理服務器。
二.HLS流媒體系統的缺點
具備時延性:HTTP Live Streaming並非一個真正實時的流媒體系統,這是由於對應於媒體分段的大小和持續時間有必定潛在的時間延遲。在客戶端中,至少在一個分段媒體文件被徹底下載以後纔可以開始播放,而一般要求下載完成兩個分段媒體文件以後纔開始播放以保證不一樣分段音視頻之間的無縫鏈接。
媒體數據碼率相對較大:MPEG-TS流有比一般文件更多的頭信息,會致使文件總體碼率明顯上升。
三.技術選型
內容準備服務中的編碼器採用ffmpeg,流切片採用Segmenter,web服務器採用Nginx,客戶端:對flash支持客戶端的選用StrobeMedia Playback,ios利用Safari瀏覽便可,Android正在研究中,對於支持html5的瀏覽器可採用html5技術進行播放。
四.流媒體服務器的安裝配置
系統環境:
發行版本:CentOS release 6.3
內核版本:2.6.32-279.el6.x86_64
4.1 ffmpeg的安裝
4.1.1安裝Yasm
Yasm是一個徹底重寫的NASM彙編。目前,它支持x86和AMD64指令集,接受NASM和睦體彙編語法,產出二進制, ELF32 , ELF64 ,COFF , Mach - O的( 32和64 ) , RDOFF2 ,的Win32和Win64對象的格式,並生成STABS 調試信息的來源,DWARF 2 ,CodeView 8格式。
wget http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz tar zxvf yasm-1.2.0.tar.gz cd yasm-1.2.0 ./configure –prefix=/usr/local Make make install 查看yasm是否能夠執行,不能執行就將/usr/local/bin加入可執行路徑
4.1.2 安裝ffmpeg
FFmpeg是一套能夠用來記錄、轉換數字音頻、視頻,並能將其轉化爲流的開源計算機程序。它包括了目前領先的音/視頻編碼庫libavcodec。能夠輕易地實現多種視頻格式之間的相互轉換,例如在本例中能夠把MP4,MOV等文件轉成咱們用來切片的MPEG-TS文件。
wget http://ffmpeg.org/releases/ffmpeg-2.2.tar.gz tar zxvf ffmpeg-2.2.tar.gz cd ffmpeg-2.2 ./configure –prefix=/usr/local Make make install
4.2 切片工具segmenter的安裝
咱們使用segmenter工具得到m3u8的索引文件以及視頻流切片文件。
從http://httpsegmenter.googlecode.com/svn/ 找到segmenter.c文件,採用以下編譯方式
gcc -Wall-g segmenter.c -o segmenter -lavformat -lavcodec -lavutil -lm -lz-lpthread -std=c99
建議以後把生成的二進制segmenter拷貝入/usr/local/bin方便使用。
警告:針對網絡上不少https://github.com/johnf/m3u8-segmenter這個解決方案,在我和王海濤的測試中發現切片不許確的狀況,須要注意。
4.3 web服務器nginx的安裝
4.3.1 能夠直接安裝官網提供的較新的穩定版本便可,也能夠安裝github上的加入nginx-rtmp-module模塊的版本,https://github.com/arut/nginx-rtmp-module。
4.3.2因爲咱們須要播放m3u8,ts類型的文件,因此要在nginx的conf/mime.types文件中加入
application/x-mpegURL m3u8; video/MP2T ts;
4.3.3另外對於nginx的http配置塊中server配置塊進行下簡要說明
http { server { listen 80; server_name localhost; location / { root /usr/local/html; index index.html index.htm; } } }
listen 表示nginx的監聽端口,建議配置爲80,由於「容許HTTP數據經過的防火牆或者代理服務器」這個緣故。
對Location進行講解主要是爲了指出從此咱們的視頻存儲URL對應在web
以root方式設置資源路徑 語法:rootpath; 默認:roothtml; 配置塊:http、server、location、if 例如,定義資源文件相對於HTTP請求的根目錄。 location /download/ { . root /opt/web/html/; } 在上面的配置中,若是有一個請求的URI是/download/index/test.html,那麼Web服務器將會返回服務器上/opt/web/html/download/index/test.html文件的內容。
以root方式設置資源路徑
語法:rootpath;
默認:roothtml;
配置塊:http、server、location、if
例如,定義資源文件相對於HTTP請求的根目錄。
location /download/ {
. root /opt/web/html/;
}
在上面的配置中,若是有一個請求的URI是/download/index/test.html,那麼Web服務器將會返回服務器上/opt/web/html/download/index/test.html文件的內容。
五.如何採用HLS協議播放視頻
5.1 利用ffmpeg對視頻文件進行轉碼 **文件 -- >ts文件。
ffmpeg -y -i <infile> -vcodec copy -acodec copy -vbsf h264_mp4toannexb <output file> -y 覆蓋輸出文件,即若是nba.xxx文件已經存在的話,直接覆蓋 -i 「filename」 指定須要轉換的文件 -vcodec的意思是指定一個視頻編碼器,copy的意思就是不編碼,直接複製到新文件。 -acodec的意思是指定一個音頻編碼器,copy的意思就是不編碼,直接複製到新文件。 vbsf爲過濾方法,即將mp4規定的H264組織方式轉換回H264協議書規定的字節流格式。 h264_mp4toannexb 過濾器,不少×××只支持annexb這種模式,所以須要將mp4作轉換 其中in file爲待轉換的視頻文件,好比input.mov,outputfile爲轉換後的文件,要命名爲output.ts
5.2 利用segmenter將轉換好的ts文件切割成多個ts片,並生成.m3u8的索引文件。
5.3 分完片後就會生成視頻的m3u8索引文件和視頻分片文件,將這些文件拷貝至相應的web目錄便可。
六.測試及結論
6.1 播放模式
對於蘋果的設備可直接使用safari播放m3u8文件。
對於支持flash的設備咱們採用StrobeMediaPlayback實現播放音視頻文件。
對於支持hls的平臺,在對html5支持的瀏覽器下,可直接使用瀏覽器進行視頻播放。
6.2 演示資源
略
6.3 測試結果
對於蘋果設備均支持m3u8文件的播放(iphone,ipad, mac os)。
對於支持flash的設備均支持StrobeMediaPlayback播放(pc)。
對於瀏覽器支持html5的瀏覽器均支持html5方式的播放(蘋果設備,pc, android)。
附錄:
1. 關於StrobeMediaPlayback的配置方式:
說明:StrobeMediaPlayback自身不支持hls視頻的播放,可是利用第三方插件能夠完成對hls視頻播放的支持。
配置方式:
第三方插件地址https://github.com/denivip/osmf-hls-plugin,咱們進行配置只須要將
StrobeMediaPlayback文件夾下的文件拷貝至nginx的web目錄下,而後對StrobeMediaPlayback/ StrobeMediaPlayback.html文件內容進行更改
將src改成hls索引文件的url,接着經過訪問url就能夠完成對hls視頻的播放。