!!!
http://www.cnblogs.com/mobiledever/archive/2012/03/26/2552119.html
1。官方文檔:http://developer.apple.com/resources/http-streaming/
2。蘋果http視頻點播技術http://rainbird.blog.51cto.com/211214/507958
如何做內容加密
HTTPLiveStreaming支持在m3u8中指定一個key文件(目前支持16-octet的AES-128加密),然後每個視頻切段都使用這個key來加密。
可以所有切段共用一個key,也可以幾個切段使用一個key,最細可以一個切段使用一個key。
然後把這些key文件加上驗證功能,比如登陸才能讀取到,這樣就可以達到內容加密的效果了。
建議使用HTTPS來傳輸key文件。
注意:每個新key文件都會發起一個新的HTTP請求,因此每個切段一個key會大大加大服務器的連接數。
cache時的2個注意事項
1、最好不要用HTTPS來傳送視頻文件和m3u8文件,因爲這樣很容易穿透cache服務器。
2、另外,cache服務器必須知道m3u8文件緩存的時間不能大於一個視頻切段的長度。
如何做冗餘
可以在m3u8中指定2個BANDWIDTH相同的外部地址,這樣客戶端會自己在其中一路不可達時切換到另一路。
1、更長的分段導致更長的延遲和更長的初始化時間,切換碼率(只能在切換分段的時候切)也更慢;
2、更短的分段導致對m3u8文件更密集的請求,從而導致更多網絡流量;
3、Apple推薦的分段時長爲10秒;
4、MPEG-TS流有比通常文件更多的頭信息,會導致文件整體碼率明顯上升。可以使用Apple家的分段軟件來減少和壓縮其中不必要的頭;
5、Apple家文檔說10s分段的話會有約30s時延;
6、m3u8中可阻止客戶端緩存文件,否則客戶端會爲了提高seek效率而緩存文件。
在寫一個基於iphone的應用,主要是用來播放視頻的.但是提交給蘋果審覈的時候卻遭到百般刁難.尤其是關於在3G網絡上播放視頻流的限制:
9.4Videostreamingcontentoveracellularnetworklongerthan10minutesmustuseHTTPLiveandincludeabaseline64kbpsaudio-onlyHTTPLivestream
也罷,想想也是,在移動互聯網直接播放一個幾十M上百M的文件也確實是太浪費有限的流量了.難道說在互聯網上直接下載整個文件,而不管會不會看完就不浪費流量了嗎?覺得確實有必要研究一下這項技術了.
applehttplivestreaming.基於http的視頻流播放,筆者稱它爲視頻切片技術,先是將視頻文件通過mpegts編碼,然後通過apple提供的小工具segmenter將視頻文件切割成很多小文件並維護一個時間列表.這些文件可以直接放在網站目錄下面通過http協議被下載播放.不幸的是蘋果提供的segmenter只能工作在mac下,我們需要一個基於linux的開源解決方案.
幾經搜索和嘗試最後找到CarsonMcDonald的<<iPhoneHTTPStreamingwithFFMpegandanOpenSourceSegmenter>>雖然文中給出了幾乎"完美"的解決方案,但是由於時代的發展和實際環境的不同,筆者着實將這篇文章細細研究了N久,於是也便有了這篇文章的出現.接下筆者會給出在ubuntu10.04服務器編譯安裝ffmpeg和segmenter技術細節,並彙報一些心得.ok,goon.
1.編譯安裝ffmpeg
刪除不用的已安裝文件,升級apt-get緩存,安裝必要的開發工具及庫文件
apt-getremoveffmpegx264libx264-devlibmp3lame-dev
apt-getupdate
apt-getinstallbuild-essentialsubversiongit-corecheckinstallyasmtexi2html\
libopencore-amrnb-devlibopencore-amrwb-devlibsdl1.2-devlibtheora-devlibvorbis-dev\
libx11-devlibxfixes-devlibxvidcore-devzlib1g-devnasmyasmlibbz2-dev
需要用到的庫及下載地址
1).faad2的安裝最簡單,直接解壓然後
./configure&&make&&makeinstall就ok了.
2).faac需要修改一個文件
vi+123./common/mp4v2/mpeg4ip.h
從123行開始修改此文件mpeg4ip.h,到129行結束。
修改前:
#ifdef__cplusplus
extern"C"{
#endif
char*strcasestr(constchar*haystack,constchar*needle);
#ifdef__cplusplus
}
#endif
修改後:
#ifdef__cplusplus
extern"C++"{
#endif
constchar*strcasestr(constchar*haystack,constchar*needle);
#ifdef__cplusplus
}
#endif
然後默認安裝:
./configure&&make&&makeinstall
3).lame這樣編譯:
./configure--enable-nasm--disable-shared&&make&&makeinstall
4).x264則是取的最新的代碼,然後默認安裝
gitclonegit://git.videolan.org/x264.git
./configure&&make&&makeinstall&&cd..
5).ffmpeg的編譯參數
./configure--enable-gpl--enable-nonfree--enable-pthreads\
--enable-libfaac--enable-libfaad--enable-libmp3lame--enable-libx264
爲什麼要選擇ffmpeg-0.6.1呢?因爲較早的版本編譯完以後不能正常使用而從svn取的最新的代碼則會好端端的出現Unknownoption"--enable-libfaad"錯誤.
2.安裝segmenter
如果您有一定的linux使用經驗,ffmpeg編譯自然不在話下,也比較簡單的,最難的就是這部分的segmenter的編譯安裝了.
先取出源代碼:
svncheckouthttp://svn.assembla.com/svn/legend/segmenter/segmenter
修改一個小地方:
vi+242segmenter.c
把guess_format修改成av_guess_format
不然segmenter會在編譯的時候提示:
segmenter.c:242:warning:‘guess_format’isdeprecated(declaredat/usr/local/include/libavformat/avformat.h:764)
接下來選擇一種編譯方式:
gcc-Wall-gsegmenter.c-osegmenter-L/usr/include/ffmpeg/libavformat-lavformat-L/usr/include/ffmpeg/libavcodec-lavcodec-L/usr/include/ffmpeg/libavutil-lavutil-I/usr/include/ffmpeg/-lbz2-lm-lmp3lame-lxvidcore-lx264-lfaad-lfaac-lpthread-lz
或者
gcc-Wall-gsegmenter.c-osegmenter-L/usr/local/src/ffmpeg/ffmpeg-0.6.1/libavformat-lavformat-L/usr/local/src/ffmpeg/ffmpeg-0.6.1/libavcodec-lavcodec-L/usr/local/src/ffmpeg/ffmpeg-0.6.1/libavutil-lavutil-I/usr/local/src/ffmpeg/ffmpeg-0.6.1/-lbz2-lm-lmp3lame-lxvidcore-lx264-lfaad-lfaac-lpthread-lz
其實無論哪種編譯方式都是手動指定了庫文件的位置,不然的話編譯不過,這個地方最坑人,費了很多很多時間!
3.編碼視頻文件並切割
這之前的地方如果你遵循筆者的安裝文檔和提示應該很容易就通過了(雖然筆者花費了大量的時間摸索).但是正確編譯以後,你並不知道正確切割文件以後的效果是什麼樣的,所以筆者在這裏花費了超級大量的時間,這也是筆者爲什麼堅持要寫出這篇文章的原因.
先列出筆者犯的幾個致命錯誤吧:
1).不按apple文檔格式轉碼
因爲筆者使用的輸入文件在編碼的時候是針對apple的設備優化過的,可以直接在apple設備上播放並獲得良好的觀看效果.而在使用原作者的編碼參數:
ffmpeg-i-fmpegts-acodeclibmp3lame-ar48000-ab64k-s320×240-vcodeclibx264-b96k-flags+loop-cmp+chroma-partitions+parti4x4+partp8x8+partb8x8-subq5-trellis1-refs1-coder0-me_range16-keyint_min25-sc_threshold40-i_qfactor0.71-bt200k-maxrate96k-bufsize96k-rc_eq'blurCplx^(1-qComp)'-qcomp0.6-qmin10-qmax51-qdiff4-level30-aspect320:240-g30-async2
時報錯,在這種情況下,考慮到前一個原因,筆者自己摸索了一個編碼代碼:
ffmpeg-y-i-vcodeccopy-acodeccopy-vbsfh264_mp4toannexb
是可以正常編碼和分割視頻文件的.但是將應用提交給蘋果審覈後,蘋果依舊給出了9.2的提示並拒絕了應用.這纔想起來源視頻在進行編碼的過程中音頻並沒有使用64k的編碼也沒有單獨增加一路音頻流.
2).浪費時間解決可以忽略的錯誤提示
無論直接正常編譯成功還是編譯失敗從別的機器上拷貝segmenter過來,在分割視頻的時候都出現了:
[mpegts@0x2942160]max_analyze_durationreached
Output#0,mpegts,to'a/index':
Stream#0.0:Video:libx264,yuv420p,536x402,q=2-31,90ktbn,25tbc
Stream#0.1:Audio:libmp3lame,48000Hz,2channels,64kb/s
[mpegts@0x2a08430]muxrate1bps,pcrevery5pkts,sdtevery200,pat/pmtevery40pkts
[NULL@0x2956900]missingpictureinaccessunit
"max_analyze_durationreached"和"missingpictureinaccessunit"的提示.最初這兩個提示困擾了筆者很久,不斷的在網上搜索尋找解決辦法;不斷的重新編譯ffmpeg和segmenter;不斷的更換視頻輸入源,重新編碼;直到最後發現即便有這兩個提示存在並不影響視頻的正常播放的時候,筆者決定接受現實:這兩個提示可以存在.
3).解決視頻長度問題
即使上面走過了那麼多的艱難,但是你還是會發現這個世界是不完美的.畢竟segmenter是蘋果開發了以後用在mac上的.不知道是移值到linux還是什麼原因,這個工具的表現有點讓人理解不了.它的參數是這樣的:
segmenter
第二個參數,你指定視頻分割間隔的時候,比如說指定了15秒.如果你的視頻時長是32秒的話,你的視頻文件會被分割成3段(每15秒一段,最後的2秒一段),而最後一段的播放時長,它竟然會寫成15秒!明明就2秒幹嘛要寫成15秒!!!用quicktime還好說,它似乎會自動檢查視頻的時長糾正時間和進度條,而在iphone上,顯示時長是取的視頻文件裏的時長(15x3=45s),而下載進度條顯示的是實際文件的視頻時長(32s),這樣的話,你會發現,當一個視頻被播放完的時候,時間還差13秒!怎麼辦呢?沒辦法了,我是看不懂c程序,但是哥會php啊,不就是時間不對嘛,哥給你重新計算一下時間重寫一下文件,搞定!
4).測試時的網速問題
爲了"大規模"的隨機測試視頻,筆者是在服務器上直接編碼測試的.無論在quicktime還是iphone上,正常的表現應該是視頻會被提前下載兩到三個小段.結果筆者測試的時候,發現視頻總是播一條下一段,筆者鬱悶了很久發現:原來是公司網速太慢了.直接在iphone上用3G測試,很給力!
5).轉碼耗用cpu問題
視頻轉碼是最費cpu的東東,如果想提高轉碼速度還是買兩顆8核的cpu一塊幹活吧,速度哇哇的,你懂的.
ok,廢話半天說一下筆者用的轉碼指令.
ffmpeg-y-ia.mp4-fmpegts-acodeclibmp3lame-ar48000-ab64k-vcodeclibx264-b250k\
-flags+loop-cmp+chroma-partitions+parti4x4+partp8x8+partb8x8-subq5-trellis1-refs1\
-coder0-me_range16-keyint_min25-sc_threshold40-i_qfactor0.71\
-bt250k-maxrate250k-bufsize250k-rc_eq'blurCplx^(1-qComp)'\
-qcomp0.6-qmin10-qmax51-qdiff4-level30-aspect320:240-g30-async2a.ts
segmentera.ts15aa/index.m3u8http://vod.rainbird.cc/
rm-rfa.ts
這個時候測試時訪問的url爲:http://vod.rainbird.cc/a/index.m3u8(隨便寫的,請勿對號入座)
4.nginx配置
vimime.types
添加以下兩條兒,重啓nginx
application/x-mpegURLm3u8;
video/MP2Tts;
一切順利的話,這時候可以通過測試url觀看視頻了.
參考文檔: