我好奇的是m3u8這種影音串流的檔案,按理說要用network去監控,
或是VLC那種軟體去對接串流。
因為是分割的ts檔案,要像mp4那樣直接下載似乎很難。
1.
依照前端來說,是能用javascript直接去載下來的嗎?
我能從原始碼找到m3u8的地址,但就算我載了一堆ts我還要合併耶~
2.
那下載m3u8的extension是否:
是有一個後端處理,
幫忙下載所有檔案、合併、上傳到伺服器,才給使用者下載?
如果是這樣也太耗費成本跟心力了,免費提供豈不佛心?
3.
若extension能做到下載m3u8(把他變成mp4下載)
那等於我用F12打一串code也能完成這個任務嗎?
不用dev tool network的前提下 就算找到的也僅僅是ts分割檔吧?
總結來說,前端是否能完成這樣的任務?能完成多少的比例呢?
個人有視訊串流全端經驗,HLS原理是這樣:
Camera攝影機擷取畫面到記憶體之後經過軟體編碼or硬體編碼h264或是訊號線傳到編碼盒(Encoder硬體)之後壓成串流(這裡絕大部分都還是RTMP格式,不是HLS)
上傳到影音伺服器,這一段壓縮是為了省頻寬,RTMP在業界太成熟,一堆硬體設備不可能為了Apple一家HLS規格就全部更換。
影音伺服器例如是YouTube,Adobe Stream Server,Wowza,Live555收到RTMP串流之後通常會有一個plugin,也就是你詢問的server端程式,不算太複雜.
RTMP只是一種封裝IFrame,PFrame收到之後切成MPEG-2-TS格式也只是另一種封裝.
Server端plugin會根據適合秒數,通常是10秒~20秒切割成一個.ts檔案。
所謂的m3u8 extension就是這個小plugin,說他小是因為相對於整個Server來說是很小一塊功能。Server還有互相串流,分散Loading,Transcoding等工作要做,例如你打2k串流上來,他要
幫你同時轉成1080p,720p,480p備用。此時距離從Camera擷取的實際畫面大約已經過3秒鐘,同時開始產生一堆.ts檔案分別放在不同目錄備用,每款Server作法不同。
Client端也就是.js或是hls player發出http請求,
這個請求的URL一定是https://server/xxxx/yyyy.m3u8 帶時間戳記表示要從哪裡開始看,如果不帶時間戳記表示從當下開始看,也就是直播
HTTP Request抵達Server端這個plugin之後,plugin小程式根據當前時間找到對應的.ts檔案然後往後數若干個,通常是湊1~2分鐘給你也就是6個.ts湊成一個HTTP Response給Client端.
Client端工作這時候就進入根據此清單抓取部分,根據每款player或是你的js要自己實作,有不同的演算法。你可以很積極開parallel thread狂抓,或是固定只抓3個.ts. 由於播放端可能是手機或是平板或是電腦,網路頻寬不同,一款優秀的player要能根據各種情形調整積極度。但根據我個人實作經驗,一定要用雙重緩衝,第一層緩衝是死命的跟Server抓檔,有多少抓多少。第二層緩衝是與畫面播放速度溝通,如果畫面只剩10秒左右就跟第一層緩衝拿一下。為什麼是10秒?這跟IFrame當初壓縮時的長度有關係。播放畫面如果跳躍太多IFrame就會出現破裂或綠畫面。由於雙重緩衝,此時距離從Camera擷取的實際畫面大約已經過10秒鐘。業界經驗幾乎無法再縮短,最積極的演算法只用一層緩衝有多少抓多少也只能拉近到3秒鐘,但播放體驗會很差一直卡頓,Server也沒有更新的m3u8 playlist可以組合給你,只能吐給你未來還不存在的.ts url。這時候你的js怎麼抓都是404也沒用。
串流跟MP4檔案的差異只在於,MP4檔案的開頭描述了整個檔案的長度,後面mdat內容一直串到結尾中間都不再放長度描述。MP4播放器是根據header顯示影片總長度多少然後開始播放,QuickTime player對於長度很敏感,你不告訴它檔案就打不開。但VLC player可以硬開無正常結尾的mp4檔案。.TS的格式是每一小段都自己有個header,才能做到從任何時間點都能直接開始播放,不需要得知整個完整檔案。
所以抓.ts湊成mp4是完全可行的。你先宣告一個.mp4檔案,header先騙他影片長度有30秒,然後每抓到一段.ts就解開取得mdat部分append到檔案。這種.mp4檔案可以先用VLC Player播放然後設定成錯誤就從先前位置繼續播放,這樣是可以work的。等到你不想抓了要完檔,必須2nd pase把檔案查一遍加總真實影片長度然後寫到header。這種從Server砍站下來湊成的mp4畫質只能說堪用,因為你抓取過程可能會有漏。
但回到上面Server端的設計,它知道每個client都會瘋狂要檔案,所以它會盡量每次只給一點點清單,每個清單的位址又可能變動,一方面也是避免有人來砍站造成盜版。
了解上述機制之後你在看YouTube直播緩衝條在那邊增增補補就更有感覺了。不建議自己寫一個hls player因為你得把第4點完整實作出來,你寫出來跟開一家聘請3個RD的公司差不多。
看你的需求是要用.js去抓playlist當中的.ts 然後轉mp4存起來,沒錯就是要自己去合併。
先認識一下什麼是 HTTP Live Streaming,縮寫為HLS。
簡單說它是基於 http 的串流。把影片分割為數個 .ts 檔,再用一個列表檔,也就是 .m3u8 來讓播放端知道,要逐個下載 .ts 檔來播放,就是完整影片檔。
@wiseguy
您好,您可能誤會我問題意思,所以您都沒回答到。
我有重新修改問題內容。
怕您或其他人也不太理解,以下對您給的意見做補充:
1.我指的是用javascript,而不是手動操作。
2.我並沒有操心,我問的是server這邊是怎麼操作的,其中必定是人寫出程式執行而不會是「自然」而然。
3.我文內所指的是「把m3u8的影片"內容"抓下來」,並不是純粹下載一個不能撥放的文件檔。
也就是「下載所有ts且合併成影片」的這個過程。
以上交流,希望讓各位更理解我的問題。
謝謝你的意見喔!
哈哈 ... 可能你沒看懂我回答的。
你的問題,簡單說就是「參考 HLS 協定,實做這個程式」就是了啊,所以你想得到什麼答案?