YouTube採用DASH!其網頁端及移動端APP都使用了DASH。DASH的其餘採用者包括:Netflix, Hulu, …html
一種服務端、客戶端的流媒體解決方案:
服務端:
將視頻內容分割爲一個個分片,每一個分片能夠存在不一樣的編碼形式(不一樣的codec、profile、分辨率、碼率等);
播放器端:
就能夠根據自由選擇須要播放的媒體分片;能夠實現adaptive bitrate streaming技術。不一樣畫質內容無縫切換,提供更好的播放體驗。python
MPD
媒體文件的描述文件(manifest),做用相似HLS的m3u8文件。MPD文件以XML格式組織,其層次結構參圖1。ide
Representation
對應一個可選擇的輸出(alternative)。如,480p video,720p video, 44100採樣 audio,22050採樣audio,都使用Representation描述。編碼
Segment(分片)
每一個Representation會劃分爲多個Segment。Segment分爲4類,其中,最重要的是:Initialization Segment(每一個Representation都包含1個Init Seg),Media Segment(每一個Representation的媒體內容包含若干Media Seg)!spa
圖1. MPD的層次示意圖 (每一個Rrepresentation使用fMP4文件格式)3d
fMP4(fragmented MP4),能夠簡單理解爲分片化的MP4,是DASH採用的媒體文件格式,文件擴展名一般爲(.m4s或直接用.mp4)。code
圖2. 普通MP4與fMP4組織結構對比,fMP4與DASH 分片概念對照視頻
圖2說明:htm
普通MP4 由索引文件頭文件moov box和媒體數據mdat box組成。blog
fMP4 由分片組成,能夠按整個文件存儲,也能夠按分片存儲:
若是按照單個文件存儲,每一個輸出是一個m4s文件。 完整的fMP4視頻能夠描述爲以下形式:
moov + (moof + mdat) * N
其中moof box是分片(fragment)的標識, mdat box存放的是當前分片的媒體數據;
若是按照分片存儲,每一個分片是一個m4s文件,輸出對應了多個m4s。
fMP4中的第一個分片,對應了DASH協議中Initialization Segment;其後的分片,則對應Media Segment。
一段15’ 720分辨率視頻,YouTube有以下Representation:
1. audio1 id:139 codec:HE-AAC 採樣率22050 分片:5
2. audio2 id:140 codec:AAC-LC 採樣率44100 分片:5
3. video1 id:133 codec:264 main profile level1.2 240p 分片:4
4. video2 id:134 codec:264 main profile level2.0 360p 分片:4
5. video3 id:135 codec:264 main profile level2.0 480p 分片:4
6. video4 id:160 codec:264 main profile level1.1 144p 分片:4
7. video5 id:136 codec:264 main profile level3.0 720p 分片:4
關注視頻部分,4個分片包含:1個Init Seg,3個Media Seg,視頻內容部分分別爲5.12s 5.12s 4.76s。
正常順序播放
圖3. 正常順序播放的時序圖
切換行爲
圖4. 發生switch的時序圖
切換前,Representation 0的全部分片已經下載完成,交互流程同上,
第8s進行畫質切換:
1. 下載Representation 1的Init Seg # 每次切換都會先下載Init Seg
2. 下載Representation 1 當前所在分片!Seg2
3. 下載後續分片。
說明:YouTube在播放Rep0 Seg2期間發生切換,會下載Repr1的Seg2,這屬於YouTube的播放策略。不少DASH播放器,此時會直接請求Repr1的Seg3。
FFmpeg支持DASH封裝,仿YouTube格式的命令:
ffmpeg -hide_banner -y -threads 0 -i INPUT_VIDEO -filter_complex 'split=2[s0][s1];[s0]scale=480:-2[480s];[s1]scale=360:-2[360s]' -map '[480s]' -c:v:0 libx264 -crf 25 -preset veryslow -map '[360s]' -c:v:1 libx264 -crf 27 -preset veryslow -map a -c:a:0 libfdk_aac -ar:a:0 22050 -map a -c:a:1 libfdk_aac -ar:a:1 44100 -g 150 -sc_threshold 0 -b_strategy 0 -min_seg_duration 5000 -use_timeline 0 -use_template 1 -single_file 1 -window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a" -f dash OUTPUT.mpd
輸出:
若存在兼容普通mp4轉碼的需求,能夠直接對已編碼視頻轉封裝獲得DASH文件,避免重複編碼。
要點在於保證編碼命令中的GOP length與DASH要求匹配,不然會發生卡頓問題,須要在播放器端作額外處理。
mp4box -dash 5000 -frag 5000 -rap -frag-rap -profile dashavc264:onDemand ld.mp4 hd.mp4 audio.m4a -out OUTPUT.mpd
使用開源的網頁端DASH player dash.js能夠播放,以下圖。
圖5. 後臺轉碼的實際播放效果