30-16之 HTTP-FLV 傳輸協議

正文開始

接下來咱們要來介紹 HTTP-FLV 協議。

HTTP-FLV 協議

本篇文章將會分成幾個章節來理解 HTTP-FLV 協議:

  • HTTP-FLV 協議是要用來完成什麼事情呢 ?
  • HTTP-FLV 協議如何完成它想做的事情呢 ?
  • 建立 HTTP-FLV 的串流傳輸流程。
  • HTTP-FLV 的特點總結。

HTTP-FLV 協議是要用來完成什麼事情呢 ?

可以使用 HTTP 來完成低延遲的串流媒體傳輸。

那為啥他想使用 HTTP 呢 ?

先來說說 RTMP,它不是基於 Http 來進行傳輸,所以他個缺點,那就是有一定的機率被封,而且還有另外一點,通常使用 Http 的來進行傳輸的 html5 會支援的不錯,像在 chrome 比較新的幾個版本就有開始支援 HLS,而當然 RTMP 不支援。

那為啥不用 HLS 呢 ?

使用 HLS 的極大缺點就是它的延遲問題,可能直播主說個話後,大約要 10 秒左右聽眾才可以聽到,而 HTTP-FLV 就是想要解決這件事情。

HTTP-FLV 協議如何完成它想做的事情呢 ?

將聲音與影像封裝成 FLV 流容器,然後在使用 Http 進行流式傳輸。

以直播情況來看,直播主會將聲音用任何方式 ( RTMP 或啥的 ) 傳送到 Server,然後 Server 會將它轉換成 FLV 檔,然後 Client 會使用 Http 來請求這個畫面,請求如下,然後 Server 就會用 Http 流的方式就影像一段一段的傳輸過去。

這裡問個問題。

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 就有包含最後一段的資料。

建立 HTTP-FLV 的串流傳輸流程

事實上概念還蠻簡單的請看下圖,基本上直播主丟過去的聲音或影像的方法,可以選擇使用 RTMP (比較多人選),然後聽眾就會發個 http 請求給 server,然後 server 就會開始進行 http 串流傳輸,基本上就是這樣。

HTTP-FLV 的特點總結

  • HTTP-FLV 目前在 HTML5 支援比較好,其它平台要找找看有沒有 player 可以播放它。
  • HTTP-FLV 延遲性優於 HLS,並且大約和 RTMP 差不多。
  • HTTP-FLV 支援影像編碼為 H.264 (VP8 好像某)。
  • HTTP-FLV 支援聲音編碼為 AAC、MP3。
  • 使用 .flv 流容器。
  • 使用 http 串流傳輸 (chunked)。

目前大部份如果要做互動類型的直播,比較會選擇 HTTP-FLV,因為它們延遲低,而 RTMP 延遲雖然也低,但是因為不是用 http 而且要用 flash 播放器,所以優先度比較低點兒。

參考資料

comments powered by Disqus