接下來咱們要來介紹 HTTP-FLV 協議。
HTTP-FLV 協議
本篇文章將會分成幾個章節來理解 HTTP-FLV 協議:
可以使用 HTTP 來完成低延遲的串流媒體傳輸。
那為啥他想使用 HTTP 呢 ?
先來說說 RTMP,它不是基於 Http 來進行傳輸,所以他個缺點,那就是有一定的機率被封,而且還有另外一點,通常使用 Http 的來進行傳輸的 html5 會支援的不錯,像在 chrome 比較新的幾個版本就有開始支援 HLS,而當然 RTMP 不支援。
那為啥不用 HLS 呢 ?
使用 HLS 的極大缺點就是它的延遲問題,可能直播主說個話後,大約要 10 秒左右聽眾才可以聽到,而 HTTP-FLV 就是想要解決這件事情。
將聲音與影像封裝成 FLV 流容器,然後在使用 Http 進行流式傳輸。
以直播情況來看,直播主會將聲音用任何方式 ( RTMP 或啥的 ) 傳送到 Server,然後 Server 會將它轉換成 FLV 檔,然後 Client 會使用 Http 來請求這個畫面,請求如下,然後 Server 就會用 Http 流的方式就影像一段一段的傳輸過去。
這裡問個問題。
一般的 http 請求都會對應一個 http 回應這點是沒錯,http 流傳輸就是一個請求,會回應一堆小封包,然後最後才是一個 http 回應。
而 http 流式傳輸需要使用chunk
這個東西,它的使用方法如下,就是在 http response header 加上下面的欄位,這樣 http 的回應就會變成一段一段的。
Transfer-Encoding: chunked
這裡簡單使用 nodejs 簡單寫個 http chunk 的使用,如下範例,不過下面的程式碼沒有在 http 加 header 欄位是因為 nodejs 的 http 本身如果不執行 res.end() 這一段,它就會自動的幫你加 chunked。
// test.js
'use strict';
const http = require('http');
const sleep = ms => new Promise(r => setTimeout(r, ms));
const app = http.createServer(async (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html', 'charset': 'utf-8' });
res.write('loading...
');
await sleep(2000);
res.write('wait: 2000ms
');
await sleep(5000);
res.write('wait: 5000ms
');
res.end();
});
app.listen(3000);
接下來咱們來執行它看看。
node test.js
執果如下圖,你可以看到這個 http response 的 header 的 Transfer-Encoding 為 chunked 。
簡單的畫張圖如下,它的基本概念就是會將資料分成一包一包的 tcp 傳回去,然後在判斷是最後一包時,就會回傳一個 http response 然後它裡面的 tcp 就有包含最後一段的資料。
事實上概念還蠻簡單的請看下圖,基本上直播主丟過去的聲音或影像的方法,可以選擇使用 RTMP (比較多人選),然後聽眾就會發個 http 請求給 server,然後 server 就會開始進行 http 串流傳輸,基本上就是這樣。
目前大部份如果要做互動類型的直播,比較會選擇 HTTP-FLV,因為它們延遲低,而 RTMP 延遲雖然也低,但是因為不是用 http 而且要用 flash 播放器,所以優先度比較低點兒。