iT邦幫忙

0

前端-下載m3u8變成影片的extension是什麼原理???

  • 分享至 

  • xImage

我好奇的是m3u8這種影音串流的檔案,按理說要用network去監控,
或是VLC那種軟體去對接串流。
因為是分割的ts檔案,要像mp4那樣直接下載似乎很難。

1.
依照前端來說,是能用javascript直接去載下來的嗎?
我能從原始碼找到m3u8的地址,但就算我載了一堆ts我還要合併耶~

2.
那下載m3u8的extension是否:
是有一個後端處理,
幫忙下載所有檔案、合併、上傳到伺服器,才給使用者下載?
如果是這樣也太耗費成本跟心力了,免費提供豈不佛心?

3.
若extension能做到下載m3u8(把他變成mp4下載)
那等於我用F12打一串code也能完成這個任務嗎?
不用dev tool network的前提下 就算找到的也僅僅是ts分割檔吧?

總結來說,前端是否能完成這樣的任務?能完成多少的比例呢?

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

2
shooding
iT邦新手 5 級 ‧ 2023-01-08 10:42:04
最佳解答

個人有視訊串流全端經驗,HLS原理是這樣:

  1. Camera攝影機擷取畫面到記憶體之後經過軟體編碼or硬體編碼h264或是訊號線傳到編碼盒(Encoder硬體)之後壓成串流(這裡絕大部分都還是RTMP格式,不是HLS)
    上傳到影音伺服器,這一段壓縮是為了省頻寬,RTMP在業界太成熟,一堆硬體設備不可能為了Apple一家HLS規格就全部更換。

  2. 影音伺服器例如是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作法不同。

  3. Client端也就是.js或是hls player發出http請求,
    這個請求的URL一定是https://server/xxxx/yyyy.m3u8 帶時間戳記表示要從哪裡開始看,如果不帶時間戳記表示從當下開始看,也就是直播
    HTTP Request抵達Server端這個plugin之後,plugin小程式根據當前時間找到對應的.ts檔案然後往後數若干個,通常是湊1~2分鐘給你也就是6個.ts湊成一個HTTP Response給Client端.

  4. Client端工作這時候就進入根據此清單抓取部分,根據每款player或是你的js要自己實作,有不同的演算法。你可以很積極開parallel thread狂抓,或是固定只抓3個.ts. 由於播放端可能是手機或是平板或是電腦,網路頻寬不同,一款優秀的player要能根據各種情形調整積極度。但根據我個人實作經驗,一定要用雙重緩衝,第一層緩衝是死命的跟Server抓檔,有多少抓多少。第二層緩衝是與畫面播放速度溝通,如果畫面只剩10秒左右就跟第一層緩衝拿一下。為什麼是10秒?這跟IFrame當初壓縮時的長度有關係。播放畫面如果跳躍太多IFrame就會出現破裂或綠畫面。由於雙重緩衝,此時距離從Camera擷取的實際畫面大約已經過10秒鐘。業界經驗幾乎無法再縮短,最積極的演算法只用一層緩衝有多少抓多少也只能拉近到3秒鐘,但播放體驗會很差一直卡頓,Server也沒有更新的m3u8 playlist可以組合給你,只能吐給你未來還不存在的.ts url。這時候你的js怎麼抓都是404也沒用。

  5. 串流跟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都會瘋狂要檔案,所以它會盡量每次只給一點點清單,每個清單的位址又可能變動,一方面也是避免有人來砍站造成盜版。

  6. 了解上述機制之後你在看YouTube直播緩衝條在那邊增增補補就更有感覺了。不建議自己寫一個hls player因為你得把第4點完整實作出來,你寫出來跟開一家聘請3個RD的公司差不多。

  7. 看你的需求是要用.js去抓playlist當中的.ts 然後轉mp4存起來,沒錯就是要自己去合併。

akajoke iT邦新手 5 級 ‧ 2023-01-25 00:28:58 檢舉

謝謝你的專業說明,我覺得很屌。給您最佳解答了

0
wiseguy
iT邦超人 1 級 ‧ 2023-01-07 11:59:01

先認識一下什麼是 HTTP Live Streaming,縮寫為HLS
簡單說它是基於 http 的串流。把影片分割為數個 .ts 檔,再用一個列表檔,也就是 .m3u8 來讓播放端知道,要逐個下載 .ts 檔來播放,就是完整影片檔。

  1. 能執行 http 的,就能下載。不過"你"不是 HLS 播放器,所以你得下載一堆 .ts 自己一個一個看。支援 HLS 的播放器或下載器,自然知道把 .ts 組合在一起。如 VLS。
  2. 支援 HLS 的影音 server 自然會做影片分割及產生 m3u8 的動作,這個你不用操心。
  3. 能下載 m3u8 沒什麼技巧啊,就是找到網址在哪,然後下載它。你當然能用手動指令下載。
akajoke iT邦新手 5 級 ‧ 2023-01-07 19:57:09 檢舉

@wiseguy
您好,您可能誤會我問題意思,所以您都沒回答到。

我有重新修改問題內容。
怕您或其他人也不太理解,以下對您給的意見做補充:

1.我指的是用javascript,而不是手動操作。
2.我並沒有操心,我問的是server這邊是怎麼操作的,其中必定是人寫出程式執行而不會是「自然」而然。
3.我文內所指的是「把m3u8的影片"內容"抓下來」,並不是純粹下載一個不能撥放的文件檔。
也就是「下載所有ts且合併成影片」的這個過程。

以上交流,希望讓各位更理解我的問題。
謝謝你的意見喔!

wiseguy iT邦超人 1 級 ‧ 2023-01-07 22:50:32 檢舉

哈哈 ... 可能你沒看懂我回答的。

  1. 我第一句就寫了。能執行 http 就能下載。下載當然是 js 程式下載,但 js 程式不就是你要寫的嗎!所以簡單講就是「你會寫的話,就能下載」,或者不會寫那就找開源軟體參考。
  2. server 是怎麼操作?當然是有人寫 server 的程式去操作,你怎麼問這麼鮮的問題?想知道怎麼寫,就參考 HLS 流程,或是找開源 HLS server 來看不就知道了。
  3. 「下載所有ts且合併成影片」的這個過程,這答案不就跟 2 一樣。

你的問題,簡單說就是「參考 HLS 協定,實做這個程式」就是了啊,所以你想得到什麼答案?

我要發表回答

立即登入回答