由於 HTML5 針對 MPEG Streaming 越來越細緻,也需要做得好,所以紀錄一下研究的結果!
MPEG-DASH (Dynamic Adaptive Streaming over HTTP) 是一個可調整 bitrate 的 streaming 技術。透過這樣的技術,可以在收看 streaming 時,針對網路的流量來調整最適合的品質播放。最常見的就是 youtube,如果仔細觀察就會發現,品質是可以根據用戶的網路速度來調整的。如果想要觀察這樣的行為,可以直接用這個網址測試!
這樣就可以直接切換不同的頻寬的影片了。
使用 DASH 的好處是,不僅可以切換不同品質的影片,也能夠把聲音跟影像分開!這樣才能夠保證在切換的時候不會造成聲音停頓的問題!
以下為 MPD 的描述 (這是從 youtube 抓出來的範例)
<?xml version="1.0" encoding="UTF-8"?> <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:yt="http://youtube.com/yt/2012/10/10" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT1.500S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" mediaPresentationDuration="PT20.247S"> <Period> <AdaptationSet mimeType="audio/mp4" subsegmentAlignment="true"> <Representation id="139" codecs="mp4a.40.5" audioSamplingRate="22050" startWithSAP="1" bandwidth="48543"> <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" /> <BaseURL yt:contentLength="121199">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=139&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=121199&lmt=1394420759457149&dur=20.247&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=04E654301557E32F0AED2F7C88D8EC1AA0D58C2B.259AA39F1C2CA6FAC412874E5602A0228F46D59E&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=audio/mp4&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="593-660" indexRangeExact="true"> <Initialization range="0-592" /> </SegmentBase> </Representation> <Representation id="140" codecs="mp4a.40.2" audioSamplingRate="44100" startWithSAP="1" bandwidth="127984"> <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" /> <BaseURL yt:contentLength="321203">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=140&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=321203&lmt=1394420756531007&dur=20.178&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=0642D22D6615387A3CEE03DA2833747FD8B53F3E.2AA665821C0091ED9C2BF8661819B78518A82C01&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=audio/mp4&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="592-659" indexRangeExact="true"> <Initialization range="0-591" /> </SegmentBase> </Representation> <Representation id="141" codecs="mp4a.40.2" audioSamplingRate="44100" startWithSAP="1" bandwidth="257226"> <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" /> <BaseURL yt:contentLength="644053">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=141&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=644053&lmt=1394420761566193&dur=20.178&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=0BFF77525D8353C7735BC967284BF2AFEA16BDF7.46CA0B5D897178172D8D604EE08C10D61C136B39&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=audio/mp4&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="592-659" indexRangeExact="true"> <Initialization range="0-591" /> </SegmentBase> </Representation> </AdaptationSet> <AdaptationSet mimeType="audio/webm" subsegmentAlignment="true"> <Representation id="171" codecs="vorbis" audioSamplingRate="44100" startWithSAP="1" bandwidth="116267"> <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" /> <BaseURL yt:contentLength="290465">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=171&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=290465&lmt=1394606562936146&dur=20.119&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=4F8183B2B00302AB2F35B1F44783B819BB3DC7A1.44E7B754448FC98706E2562ED5C7B3BB7335FA0F&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=audio/webm&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="4452-4502" indexRangeExact="true"> <Initialization range="0-4451" /> </SegmentBase> </Representation> <Representation id="172" codecs="vorbis" audioSamplingRate="44100" startWithSAP="1" bandwidth="166147"> <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" /> <BaseURL yt:contentLength="401392">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=172&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=401392&lmt=1394606560692748&dur=20.119&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=8D23DF20959C7A4D34CDA2A2FC1AF8291A64F039.2FA6A24FEDA8CEB8A75675AD2BDF88F68EE6FBA0&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=audio/webm&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="3995-4045" indexRangeExact="true"> <Initialization range="0-3994" /> </SegmentBase> </Representation> </AdaptationSet> <AdaptationSet mimeType="video/mp4" subsegmentAlignment="true"> <Representation id="133" codecs="avc1.4d4015" width="426" height="240" startWithSAP="1" bandwidth="247149"> <BaseURL yt:contentLength="614054">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=133&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=614054&lmt=1394420761538993&dur=20.086&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=4E357B9A55A04C460F3AEBDD1B6327DA0DA082CD.8CABCF9A9A6417D0D6D3F62F53C4E7ADD7F7267D&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=video/mp4&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="677-756" indexRangeExact="true"> <Initialization range="0-676" /> </SegmentBase> </Representation> <Representation id="134" codecs="avc1.4d401e" width="640" height="360" startWithSAP="1" bandwidth="423848"> <BaseURL yt:contentLength="899260">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=134&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=899260&lmt=1394420760590263&dur=20.086&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=084DF8E6E22F75E443389CF79AE1936648FF2F02.1BFD4C1C27275FF36626A653C09054E9B82B0758&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=video/mp4&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="709-788" indexRangeExact="true"> <Initialization range="0-708" /> </SegmentBase> </Representation> <Representation id="135" codecs="avc1.4d401f" width="854" height="480" startWithSAP="1" bandwidth="803225"> <BaseURL yt:contentLength="1760282">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=135&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=1760282&lmt=1394420767493544&dur=20.086&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=45A2F7C4D3BCE064778FDC34FDDB9162B780936C.57660A6974A7DCA5BF67439F83DF0375BA5BE355&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=video/mp4&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="713-792" indexRangeExact="true"> <Initialization range="0-712" /> </SegmentBase> </Representation> <Representation id="160" codecs="avc1.42c00c" width="256" height="144" startWithSAP="1" bandwidth="114177"> <BaseURL yt:contentLength="283175">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=160&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=283175&lmt=1394420763553808&dur=20.086&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=4E4BDAC3F2EBAD217601F24ABF185D160F861B67.20AF456A1C5E0474BA04A57817C1707E0764479F&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=video/mp4&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="672-751" indexRangeExact="true"> <Initialization range="0-671" /> </SegmentBase> </Representation> <Representation id="136" codecs="avc1.4d401f" width="1280" height="720" startWithSAP="1" bandwidth="1539482"> <BaseURL yt:contentLength="3508736">http://r2---sn-ipoxu-u2xl.googlevideo.com/videoplayback?id=d07c4c2c028c9038&itag=136&source=youtube&playback_host=r2---sn-ipoxu-u2xl.googlevideo.com&cmbypass=yes&ratebypass=yes&gir=yes&clen=3508736&lmt=1394420776544869&dur=20.086&key=dg_yt0&sver=3&fexp=900225,906335,932261,916807,934913,916611,937417,913434,936910,936913,934022,3300009,3300100,3300134,3300137,3300161,3310366,3310628,3310649&signature=2394AF11A0C86E9D359D654162ADB4569F551060.6BE517FB3326C126D40FB565D0794A7F49C2A7FB&ms=au&upn=uM4FwNm82uQ&mt=1394888580&mv=u&mime=video/mp4&ip=59.120.37.117&ipbits=0&expire=1394913830&sparams=ip,ipbits,expire,id,itag,source,playback_host,cmbypass,ratebypass,gir,clen,lmt,dur</BaseURL> <SegmentBase indexRange="709-788" indexRangeExact="true"> <Initialization range="0-708" /> </SegmentBase> </Representation> </AdaptationSet> </Period> </MPD>