來自:https://github.com/gwuhaolin/blog/issues/3#issue-229271574
爲何要在這個時候探索flv.js作直播呢?緣由在於各大瀏覽器廠商已經默認禁用Flash,以前常見的Flash直播方案須要用戶贊成使用Flash後才能夠正常使用直播功能,這樣的用戶體驗很致命。html
在介紹flv.js以前先介紹下常見的直播協議以及給出我對它們的延遲與性能所作的測試得出的數據。
若是你看的很吃力能夠先了解下音視頻技術的一些基礎概念。react
TCP
,在瀏覽器端依賴Flash。HTTP
流式IO傳輸FLV,依賴瀏覽器支持播放FLV。WebSocket
傳輸FLV,依賴瀏覽器支持播放FLV。WebSocket
創建在HTTP
之上,創建WebSocket
鏈接前還要先創建HTTP
鏈接。HTTP
的流媒體傳輸協議。HTML5
能夠直接打開播放。UDP
,延遲1秒,瀏覽器不支持。傳輸協議 | 播放器 | 延遲 | 內存 | CPU |
---|---|---|---|---|
RTMP | Flash | 1s | 430M | 11% |
HTTP-FLV | Video | 1s | 310M | 4.4% |
HLS | Video | 20s | 205M | 3% |
在支持瀏覽器的協議裏,延遲排序是:
RTMP = HTTP-FLV = WebSocket-FLV < HLS
而性能排序剛好相反:
RTMP > HTTP-FLV = WebSocket-FLV > HLS
也就是說延遲小的性能很差。git
能夠看出在瀏覽器裏作直播,使用HTTP-FLV協議是不錯的,性能優於RTMP+Flash,延遲能夠作到和RTMP+Flash同樣甚至更好。github
flv.js是來自Bilibli的開源項目。它解析FLV文件餵給原生HTML5 Video標籤播放音視頻數據,使瀏覽器在不借助Flash的狀況下播放FLV成爲可能。web
H.264
,音頻編碼必須是AAC
或MP3
, IE11和Edge瀏覽器不支持MP3音頻編碼,因此FLV裏採用的編碼最好是H.264+AAC,這個讓音視頻服務兼容不是問題。原生HTML5 Video標籤
和 Media Source Extensions APIHTTP FLV
或者 WebSocket
中的一種協議來傳輸FLV。其中HTTP FLV
需經過流式IO去拉取數據,支持流式IO的有fetch或者streamflv.min.js
文件大小 164Kb,gzip後 35.5Kb,flash播放器gzip後差很少也是這麼大。Media Source Extensions
,目前全部iOS和Android4.4.4如下里的瀏覽器都不支持,也就是說目前對於移動端flv.js基本是不能用的。flv.js只作了一件事,在獲取到FLV格式的音視頻數據後經過原生的JS去解碼FLV數據,再經過Media Source Extensions API 餵給原生HTML5 Video標籤。(HTML5 原生僅支持播放 mp4/webm 格式,不支持 FLV)npm
flv.js 爲何要繞一圈,從服務器獲取FLV再解碼轉換後再餵給Video標籤呢?緣由以下:瀏覽器
因爲目前flv.js兼容性還不是很好,要用在產品中必要要兼顧到不支持flv.js的瀏覽器。兼容方案以下:緩存
說了這麼多介紹與原理,接下來教你們如何用flv.js搭建一個完整的直播系統。
我已經搭建好了一個demo能夠供你們體驗。服務器
主播推流到音視頻服務,音視頻服務再轉發給全部鏈接的客戶端。爲了讓你快速搭建服務推薦我用go語言實現的livego,由於它能夠運行在任何操做系統上,對Golang感興趣?請看Golang 中文學習資料彙總。websocket
livego
,服務就啓動好了。它會啓動RTMP(1935端口)服務用於主播推流,以及HTTP-FLV(7001端口)服務用於播放。在react體系裏使用react flv.js 組件reflv 快速實現。
先安裝npm i reflv
,再寫代碼:
import React, { PureComponent } from 'react'; import Reflv from 'reflv'; export class HttpFlv extends PureComponent { render() { return ( <Reflv url={`http://localhost:7001/live/test.flv`} type="flv" isLive cors /> ) } }
讓以上代碼在瀏覽器裏運行。這是你還看不到直播,是由於尚未主播推流。
ffmpeg -f avfoundation -i "0" -vcodec h264 -acodec aac -f flv rtmp://localhost/live/test
按照上面的教程運行起來的直播延遲大概有3秒,通過優化能夠到1秒。在教你怎麼優化前先要介紹下直播運行流程:
主播端在採集到一段時間的音視頻原數據後,由於音視頻原數據龐大須要先壓縮數據:
壓縮完後再經過FLV容器格式封裝壓縮後的數據,封裝成一個FLV TAG
再把FLV TAG經過RTMP協議推流到音視頻服務器,音視頻服務器再從RTMP協議裏解析出FLV TAG。
音視頻服務器再經過HTTP協議經過和瀏覽器創建的長連接流式把FLV TAG傳給瀏覽器。
flv.js 獲取FLV TAG後解析出壓縮後的音視頻數據餵給Video播放。
知道流程後咱們就知道從哪入手優化了:
{
enableWorker: true, enableStashBuffer: false, stashInitialSize: 128,// 減小首楨顯示等待時長 }
這裏是優化後的完整代碼