目前大多數網路攝影機都是透過RTSP 協定傳輸視訊串流的,但是HTML 並不標準支援RTSP 串流。除了Firefox 瀏覽器可以直接播放RTSP 串流之外,幾乎沒有其他瀏覽器可以直接播放RTSP 串流。 Electron 應用程式是基於Chromium 核心的,因此也不能直接播放RTSP 串流。
在使用某一工具的情況下,可以實現在Web 頁面上播放RTSP 串流。本文介紹的方法可以應用於傳統Web 應用程式和Electron 應用程式中,唯一的差異是將Electron 應用程式的主流程當作傳統Web 應用的伺服器。
目前已有RTSP 播放方案的對比既然是做直播,就需要延遲較低。當攝影機斷線時,也應有一定的事件提示。處於這兩點,對目前已有的已經實現、無需購買許可證的RTSP 播放方案進行比較(處於原理階段的暫時不分析)。
我對這四種方式都進行了實現,整體效果最好的還是第4種方案,佔用端口少,延遲低,渲染速度快,而且離線事件易於處理。
基於flv.js 的RTSP 播放方案flv.js 是Bilibili 開源的HTML5 瀏覽器。依賴Media Source Extension 進行視訊播放,視訊透過HTTP-FLV 或WebSocket-FLV 協定傳輸,視訊格式需要為FLV 格式。
伺服器端(主進程)伺服器端採用express + express-ws 框架進行編寫,當有HTTP 請求發送到指定的地址時,啟動ffmpeg 流媒體程序,直接將RTSP 流封裝成FLV 格式的視頻流,推送到指定的WebSocket 響應流中。
import * as express from express;import * as expressWebSocket from express-ws;import ffmpeg from fluent-ffmpeg;import webSocketStream from websocket-stream/stream;import WebSocket from websocket-stream;import * as http { let app = express(); app.use(express.static(__dirname)); expressWebSocket(app, null, { perMessageDeflate: true }); app.ws(/rtsp/:id/, rtspRequestHandle) app.listen(8888); console.log(express listened)}function rtspRequestHandle(ws, req) { console.log(rtsp request handle); const stream = webSocketStream(ws, { binary: true, browserBufferTimeout: 1000000 }, { browserBufferTimeout: 100000 }); let url = req.query.url; console.log(url url:, . log(rtsp params:, req.params); try { ffmpeg(url) .addInputOption(-rtsp_transport, tcp, -buffer_size, 102400) // 這裡可以加入一些RTSP 最佳化的參數.on(start, function () { console.log(url, Stream started.); }) .on(codecData, function () { console.log(url, Stream codecData.) // 攝影機線上處理}) .on(error, function (err) { console.log(url, An error occured: , err.message); }) .on(end, function () { console.log(url, Stream end!); //攝影機斷線的處理}) .outputFormat(flv).videoCodec(copy).noAudio().pipe(stream); } catch (error) { console.log(error); }}
為了實現較低的載入時間,可以為ffmpeg 新增以下參數:
當然這個實作還比較粗糙。當有多個相同位址的請求時,應增加ffmpeg 的輸出,而不是啟動一個新的ffmpeg 進程流。
瀏覽器端(渲染流程)範例使用Vue 框架進行頁面設計。
<template> <div> <video class=demo-video ref=player></video> </div></template><script>import flvjs from flv.js;export default { props: { rtsp: String, id : String }, /** * @returns {{player: flvjs.Player}} */ data () { return { player: null } }, mounted () { if (flvjs.isSupported()) { let video = this.$refs.player; if (video) { this.player = flvjs.createPlayer({ type: flv, isLive: true, url: `ws:/ /localhost:8888/rtsp/${this.id}/?url=${this.rtsp}` }); this.player.attachMediaElement(video); try { this.player.load(); this.player.play(); } catch (error) { console.log(error); }; } } }, beforeDestroy () { this.player.destory(); }}</script><style> .demo-video { max-width: 480px; max-height: 360px; }</style>效果展示
用Electron 頁面展示了7 個Hikvison NVR 的攝像頭,可以實現低延遲,低CPU 佔用,無花螢幕現象。由於涉及保密,這裡就不放截圖了。
同樣的方法我播放了9 個本地1080p 的影片《白鹿原》,可以看一下這個效果。
播放效果非常好,完全沒有卡頓和花屏,CPU 佔用率也不高。
範例程式碼倉庫:WhuRS-FGis/html5-rtsp範例程式碼倉庫:
總結以上所述是小編給大家介紹的HTML5 播放RTSP 影片的實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對VeVb武林網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請註明出處,謝謝!