前言:
現在安防設備普遍使用rtsp拉取視頻流,要在網頁播放rtsp視頻流不可以直接實現,html不支持rtsp視頻流, 所以需要進行轉換成html5可以解析的幀數據然后在瀏覽器進行播放。傳輸數據流的長連接,網上很多都是node.js開發的http轉websocket,借鑒采用java + netty 進行了這一步的轉換。這個地方一定要搞清楚http和WS的區別,為啥要轉WS。本文的核心就是http轉ws+ js頁面幀展示.
原理:
ffmpeg可以將rtsp視頻流轉換成很多格式的幀數據。將這些數據以http長連接的方式推送給后台,后台轉換為瀏覽器可以播放的WS數據流,瀏覽器通過js解析ws協議提取出每一幀后展示。網上的思路也大多是如此,此處以h264_wfs_websocket為例進行分析。
操作步驟
1.安裝ffmpeg,可以用java驅動ffmpeg進行調用,網上有很多案例,封裝的庫也很方便,在此就不列舉。
ffmpeg -rtsp_transport tcp -i "rtsp://admin:guide123@192.168.1.190:554/" -q 0 -buffer_size 1024000 -max_delay 500 -f rawvideo -codec:v libx264 -preset ultrafast http://127.0.0.1:8081/supersecret/live3
這里主要說明優化的幾點:
a. ffmpeg轉tcp協議不會丟幀,但是不可避免的存在延時大,udp在網絡不好的情況下出現很多馬賽克。
b. -preset ultrafast這個指令可以讓延遲縮小很多 ,畫質有一定影響。
2. java后台服務 ,搭建netty平台,將ffmpeg推送的http連接升級為Websocket(WS)長連接,將收到的WS消息廣播給指定用戶(通過瀏覽器連接參數或路徑進行廣播) ,參考rtsp+ffmpeg+ netty +jsmpeg。
3. 引入wfs.js,按自己需求進行微調,前期由於里面參數調整不到位,讀幀的速度沒調整好(_this.H264_TIMEBASE = 3000),導致幀跳躍。參考github進行微調,從大往小了調整,找到最合適的值。
4. 編寫頁面進行播放:
<!DOCTYPE html> <html> <head> <title>h.264 To fmp4</title> </head> <body> <h2>h.264 To fmp4</h2> <script type="text/javascript" src="../wfs/wfs.js" ></script> <div class="wfsjs"> <video id="video1" width="640" height="480" controls></video> <div class="ratio"></div> </div> <script> window.onload = function () { if (Wfs.isSupported()) { var video1 = document.getElementById("video1"), wfs = new Wfs(); wfs.attachMedia(video1,'ch1'); } }; </script> </body> </html>
總結了幾個地方需注意和優化:
1.播放延遲越來越高,可以通過調整播放速率來調整。解決不了的話定時修改player.currentTime = 當前視頻加載進度 來解決,相當於播放器下的快進鍵和進度條控制拉動。
2.瀏覽器縮小后視頻可能暫停了, 需要在重新打開的時候按上面1的方法處理。.
3.瀏覽器緩存越來越大,監控視頻是一天24小時不間斷的播放,所以瀏覽器在經過一段時間后絕對會崩潰。解決辦法是定時(采用了30分鍾)重新打開新的視頻連接,替換老的視頻連接,相當於偷偷的給用戶換了個頁面播放連接,新老視頻播放中間有時間差注意好,預計新的視頻流加載的可以平穩播放了再替換並關閉老的視頻流,保證平穩過度。