一,簡言
rtsp是一種RTSP(實時流協(xié)議)是一種網(wǎng)絡協(xié)議,專門用于控制基于IP的網(wǎng)絡上的多媒體流。RTSP主要用于設置和控制流媒體服務器上的媒體會話
一般電視直播或者攝像頭(使用RTSP流來傳輸實時視頻和音頻)
RTSP流的URL通常包含協(xié)議類型、服務器地址、端口號和媒體資源路徑,下面是一種格式
rtsp://username:password@hostname:port/path
首先將rtsp形式的視頻流在網(wǎng)頁上播放有很多種方法。
方法1 rtsp 轉 hls/m3u8
可以使用FFmpeg這個工具。FFmpeg可以讀取RTSP流并將其轉換為HLS流,然后生成m3u8文件但是轉hls流出來延遲很大。
方法2 使用rtsp2web
是一個提供在web頁面直接播放 rtsp 視頻流的包。使用起來簡單快捷高效
rtsp2web官網(wǎng)有具體
的使用方法。
方法3 Jsmpeg.JS + ffmpeg + websocket + node實現(xiàn)在網(wǎng)頁上播放。
我實現(xiàn)這種功能用的就是方法 下面會對方法進行詳細的說明,據(jù)網(wǎng)上搜索目前海k和大h也是使用的這種方法來實現(xiàn)的
二, ffmpeg + websocket + node+Jsmpeg.JS 的原理
首先這種方法的原理就是
1.RTSP流獲?。菏褂?strong>FFmpeg從RTSP源獲取視頻流。
2.轉碼與推流:FFmpeg將視頻流轉碼為MPEG-TS格式并通過WebSocket(全雙工通信)推送到Node.js服務器。
3.WebSocket轉發(fā):Node.js服務器通過WebSocket將接收到的MPEG-TS流轉發(fā)給網(wǎng)頁客戶端。
4.網(wǎng)頁播放:網(wǎng)頁客戶端使用jsmpeg.js庫從WebSocket接收MPEG-TS流并進行播放。
ffmpeg
簡單來說就是一種能獲取并且轉換RTSP的一種工具,并且還是跨平臺的
websocket
WebSocket 是一種全雙工通信協(xié)議,允許服務器和客戶端之間的實時數(shù)據(jù)傳輸
相比于傳統(tǒng)的HTTP請求-響應模型,WebSocket提供了更低的延遲。這對于實時視頻流傳輸非常重要,因為它能夠減少視頻播放的延遲
其在這里的作用是
**FFmpeg 通過 WebSocket 推送視頻流到 Node.js 服務器,然后WebSocket 服務器監(jiān)聽連接請求,并通過WebSocket 服務器轉發(fā)視頻流所有已連接的客戶端。
node
這里Node.js 服務器使用 ws 庫創(chuàng)建一個 WebSocket 服務器,處理客戶端的 WebSocket 連接請求,并且轉發(fā)給所以連接的客戶端,Node.js 服務器同時充當一個簡單的 HTTP 服務器,使頁面中的 JavaScript 代碼與服務器建立 WebSocket 連接。
jsmpeg.Js
jsmpeg.js 是一個用 JavaScript 編寫的輕量級視頻播放器庫,它能夠在網(wǎng)頁中通過 HTML5 <canvas> 元素播放視頻。jsmpeg.js 特別適用于播放通過 WebSocket 接收到的實時視頻流。它最常用于將視頻流從服務器傳輸?shù)綖g覽器客戶端并進行播放。
而且使用canvas進行渲染非常的高性能,也能支持大多數(shù)瀏覽器.
作用就是從服務器接收視頻流數(shù)據(jù),然后解析 MPEG-TS 流中的視頻幀,并進行視頻解碼,解碼后的視頻幀渲染到canvas中進行視頻播放
三,實現(xiàn)步驟
一,拿到rtsp流
首先拿到后端給你的一個rtsp流你要先去進行這個rtsp視頻流的*驗證,確保這個視頻流誰沒問題的然后再去進行以下的工作
使用一款叫VLC media player的軟件去進行測試
VLC media player下載地址
他是一個能播放所有類型的一個軟件
打開之后去將rtsp地址

在這個位置打開,能正常播放說明給你的流沒有問題.然后可以進行下一步的操作
第一步 布置環(huán)境變量
我用的是vue2版本進行開發(fā)的
vue2創(chuàng)建的命令是
安裝npm install -g @vue/cli
創(chuàng)建項目 vue create myproject
- 1.下載ffmpeg.并配置環(huán)境變量,保證在cmd命令窗口執(zhí)行
ffmpeg -h可以顯示對應信息
[ffmpeg下載網(wǎng)址](Download ffmpeg-latest-win32-static.zip free - FFmpeg
) - 2 jsmpeg的下載
jsmpeg下載網(wǎng)址
) - node.js的環(huán)境變量配置
第二步
- 1 在vue項目中安裝webSocet模塊
npm install ws
image.png - 2 將之前下載的jsmpeg文件放在跟src目錄下同級的位置,并新開一個終端去運行
node websocket-relay.js supersecret 8081 8082命令.這個命令是用來啟動一個 WebSocket 轉發(fā)服務的,也就是監(jiān)聽這個8081端口(8082可以多端),然后一旦啟動這個8081端口websocket就會監(jiān)聽到并將數(shù)據(jù)給到這個端口
8082端口是jsmpeg經(jīng)過處理過的可以讓網(wǎng)頁播放mpeg1的視頻,可以實現(xiàn)瀏覽器中播放MPEG1視頻和MP2音頻流
node websocket-relay.js supersecret 8081 8082 這條命令用于啟動一個 WebSocket 中繼服務器,具體來說:
node: 是運行 JavaScript 的 Node.js 環(huán)境的命令。
websocket-relay.js: 是一個 JavaScript 腳本文件的名稱,通常用于創(chuàng)建 WebSocket 服務器。
supersecret: 是一個參數(shù),可能是用于標識 WebSocket 服務器的一部分信息或密碼。
8081: 是 WebSocket 服務器的監(jiān)聽端口,即客戶端將連接到的端口。
8082: 是 WebSocket 服務器的中繼端口,即接收來自源服務器的流數(shù)據(jù)的端口。
這條命令的目的是啟動一個 WebSocket 服務器,用于接收來自某個源的視頻流數(shù)據(jù),并通過 WebSocket 中繼端口 (8082) 將該視頻流數(shù)據(jù)轉發(fā)到 WebSocket 客戶端。
- 3 然后再用cmd開一個服務(此操作在用戶下打開終端就可以)執(zhí)行
ffmpeg -i rtsp://192.168.2.0 -vf "delogo=x=10:y=10:w=400:h=80" -q 5 -f mpegts -codec:v mpeg1video -s 800x600 -timeout 5000000 http://127.0.0.1:8081/supersecret
此命令作用是用ffmpeg的轉碼操作將從 rtsp://192.168.2.0 這個 RTSP 源獲取的視頻流,視頻流轉碼為 MPEG-TS 格式,并通過 HTTP 協(xié)議推送到 http://127.0.0.1:8081/supersecret 這個地址
這條命令的目的是從一個 RTSP 源(rtsp://192.168.19.47/ch1)獲取視頻流,并通過 ffmpeg 進行處理和轉碼,然后將轉碼后的視頻流以 MPEG-TS 格式發(fā)送到指定的 HTTP 地址(http://127.0.0.1:8081/supersecret)。
-rtsp_transport tcp: 指定使用 TCP 作為 RTSP 傳輸協(xié)議,確保穩(wěn)定的數(shù)據(jù)傳輸。
-i rtsp://192.168.99.27/ch1: 指定輸入源為 RTSP 地址 rtsp://192.168.19.27/ch1,從這個地址獲取視頻流。
-vf "delogo=x=10:y=10:w=400:h=80": 使用視頻濾鏡,去除視頻中指定位置的水?。╠elogo)。
x=10: 水印左上角的 x 坐標。
y=10: 水印左上角的 y 坐標。
w=400: 水印的寬度。
h=80: 水印的高度。
-q:v 15: 視頻質量參數(shù),指定視頻編碼的質量,值越小質量越高。
-f mpegts: 指定輸出格式為 MPEG-TS(MPEG Transport Stream)。
-codec:v mpeg1video: 指定視頻編碼器為 MPEG-1 Video。
-s 800x600: 指定輸出視頻的分辨率為 800x600 像素。
-b:v 2000k: 指定視頻的目標比特率為 2000 kbps。
-maxrate 2000k: 指定視頻的最大比特率為 2000 kbps。
-bufsize 4000k: 指定視頻緩沖區(qū)的大小為 4000 kbps。
-timeout 10000000: 指定超時時間為 10000000 微秒(10 秒),在此時間內沒有數(shù)據(jù)傳輸將會中斷連接。
-trellis 2: 激活 trellis 量化算法,提高視頻編碼的效率。
-qmax 30: 視頻質量參數(shù),最大量化參數(shù),控制視頻編碼的最大量化值。
最后的 http://127.0.0.1:8081/supersecret 是輸出的目標地址,指定將轉碼后的視頻流以 MPEG-TS 格式發(fā)送到此 HTTP 地址。
第三步 在vue頁面展示
-
1 在vue項目的main.js文件中引入jsmpeg.min這個文件
image.png
將jsmpeg.min文件的第一行改成window.JSMpeg(作用是將 JSMpeg 庫暴露到全局作用域中,使得在其他代碼中可以直接訪問和使用 JSMpeg 對象)
展示的vue文件
<template>
<div class="right_one_box">
<div class="title"><span></span>視頻監(jiān)控</div>
<div class="box_con">
<div class="con">
<canvas id="video-canvas" style="height: 640px; width: 664px;"></canvas>
</div>
</div>
</div>
</template>
<script>
import '../../jsmpeg-master/jsmpeg.min';// 引入 JSMpeg
export default {
mounted() {
// 獲取 canvas 元素
const canvas = document.getElementById('video-canvas');
// 創(chuàng)建 JSMpeg Player 實例,并傳入 WebSocket 地址和 canvas
new JSMpeg.Player(this.path, {
canvas: canvas,
autoplay: true,
loop: true,
});
},
data() {
return {
path: 'ws://127.0.0.1:8082/brightness=1&saturation=0', // 視頻源地址(假設有一個 WebSocket 服務器運行在 127.0.0.1 的 8082 端口上,
//客戶端可以通過 ws://127.0.0.1:8082/brightness=1&saturation=0 這樣的地址來請求視頻流數(shù)據(jù)。在這個例子中,brightness=1&saturation=0
//就是傳遞給服務器的參數(shù))
//這里只是部署到我自己的服務器了
//1.WebSocket 地址ws://127.0.0.1:8082/brightness=1&saturation=0
//2.node websocket-relay.js supersecret 8081 8082
//8081 端口通常用于客戶端向服務器發(fā)送視頻流數(shù)據(jù),8082 端口用于從服務器向客戶端發(fā)送處理后的視頻流數(shù)據(jù)。
//前者定義了客戶端請求視頻流的地址和參數(shù),后者提供了一個服務器端程序,用于處理客戶端的請求并傳輸視頻流數(shù)據(jù)
};
},
};
</script>
<style scoped>
</style>
四,補充
視頻水印的去除
兩種思路
1.在 HTML頁面進行處理,就是在canvas上面進行每一幀對應位置的一個覆蓋,但是這樣對于一些復雜的水印可能處理不了,并且性能也不是很好
2 使用FFmpeg 提供了一個 delogo 濾鏡,可以用來移除特定位置的水印.在運行ffmpeg上添加參數(shù)"delogo=x=10:y=10:w=200:h=80"
對于canvas的一些設置
可以參考github中的這個網(wǎng)址進行一些canvas的操作https://github.com/Neveryu/rtsp2web/blob/master/example/index.html
比如說
<!-- JSMpeg -->
<!-- 方式一: 只給定寬度或者高度,另外一個值將會自適應;整體比例與原視頻一致 -->
<canvas id="canvas-1" style="width: 400px"></canvas>
<!-- 方式二: 可以自定義視頻播放窗口的寬度和高度,會鋪滿,比例可能與原視頻不一致了-->
<canvas id="canvas-2" style="width: 400px; height: 400px"></canvas>
<!-- 方式三:雖然設置了固定的寬高,但是視頻還是會選擇安寬度來自適應,比例與原視頻保持一致 -->
<!-- 使用div + class="jsmpeg" + data-url的方式 -->
在調用 new JSMpeg.Player() 時,第一個參數(shù)是接口地址拼接上 rtsp 地址,我們還可以使用 url 傳參的方式傳遞更多的高階參數(shù)。
這里可以利用jsmpeg去設置在頁面播放視頻的參數(shù).如亮度,對比度等等
相關的報錯
-
1
image.png
這里出現(xiàn)的問題意思我大概理解是處理視頻時有一些幀會丟失被剪切掉,到達了一個臨界的值
解決方法: 把-q這個參數(shù)的值調大一點就好了
搜索了一下 -q 是視頻質量(范圍0(質量最高)-24),我之前設置的是0,可能是這個原因出現(xiàn)了上面的提示。 -
2
image.png
這里的報錯是進行視頻處理時發(fā)生了網(wǎng)絡相關的問題,通常是網(wǎng)絡連接中斷或連接被強制關閉所致。
然后這里可以增加一個參數(shù),一個增加連接超時參數(shù):在 FFmpeg 命令中增加 -timeout 參數(shù),以延長連接超時時間,-timeout 5000000
然后看了10分鐘目前沒有出現(xiàn)斷掉的情況,還需要去找真正的原因,看看是網(wǎng)絡的問題導致的還是什么。
五,關于報錯 不能長時間進行播放的

這個我查詢了很多資料 其中影響的因素有很多
FFMPEG詳解(完整版)-音視頻開發(fā)中文網(wǎng)
這個網(wǎng)站有一些關于ffnpeg的一些說明
其中我分析影響掉線的幾個點
1.網(wǎng)絡問題
2.掉包問題導致不能轉碼
3.傳輸?shù)膮f(xié)議 TCP(穩(wěn)定但可能有延遲) UDP(忽略掉包 延遲小)
4.緩沖區(qū)和超時時間
5.視頻質量的設置
6.設置-flags +global_header: ,這里是為了在每個關鍵幀前添加全局頭信息,確保解碼器正確解碼。
7.編碼格式RTSP通常用于控制和傳輸實時流媒體,而H.265則可以作為一種編碼標準被用于壓縮這些實時流媒體的視頻數(shù)據(jù)
8.編解碼器的參數(shù)(如碼率、幀率、分辨率等)
所以我根據(jù)以上這些點進行綜合調節(jié).下面兩條命令是一個UDP,一個TCP不同協(xié)議的命令
tcp:ffmpeg -report -rtsp_transport tcp -i rtsp://192.168.1.2/ch -vf "delogo=x=10:y=10:w=400:h=80" -q:v 20 -f mpegts -vcodec mpeg1video -s 800x600 -b:v 2000k -maxrate 2000k -bufsize 4000k -timeout 30000000 -trellis 2 -qmax 30 -flags +global_header [http://127.0.0.1:8081/supersecret](http://127.0.0.1:8081/supersecret)
udp:'ffmpeg -i rtsp://192.168.19.27/c -vf "delogo=x=10:y=10:w=400:h=80" -q:v 15 -f mpegts -codec:v mpeg1video -s 800x600 -b:v 2000k -maxrate 2000k -bufsize 4000k -timeout 10000000 -trellis 2 -qmax 30 http://127.0.0.1:8081/supersecret
'
前端可以播放MPEG-TS流和h265的格式流,但需要借助第三方進行處理
Video.js: 一個強大的HTML5視頻播放器,可以通過插件支持MPEG-TS。
hls.js: 一個支持HTTP Live Streaming(HLS)的JavaScript庫,可以將MPEG-TS流轉換為HLS格式進行播放。
Fluent-ffmpeg: 用于在服務器端處理視頻流,然后通過上述播放器庫在前端播放。
轉碼的HLS流可以借助video標簽來進行播放
如果你的監(jiān)控系統(tǒng)使用的是 MPEG-TS(MPEG Transport Stream)格式,JSMpeg 是一個非常合適的選擇。它可以通過 WebSocket 來接收和播放實時視頻流。
假設你有一個 H.265 編碼的視頻源,想要通過 HLS 協(xié)議傳輸并播放它。以下是一個使用 FFmpeg 將 H.265 編碼的視頻轉換為 HLS 流的示例:
sh
復制代碼
ffmpeg -i input_video.mp4 -c:v libx265 -preset fast -crf 28 -c:a aac -b:a 128k -f hls -hls_time 10 -hls_playlist_type vod -hls_segment_filename "segment_%03d.ts" output.m3u8
-i input_video.mp4:輸入視頻文件。
-c:v libx265:使用 H.265 編碼器。
-preset fast:編碼速度設置。
-crf 28:質量控制參數(shù),值越小質量越好但文件越大。
-c:a aac -b:a 128k:音頻編碼設置。
-f hls:輸出格式為 HLS。
-hls_time 10:每個片段的持續(xù)時間為 10 秒。
-hls_playlist_type vod:HLS 播放列表類型為點播(VOD)。
-hls_segment_filename "segment_%03d.ts":設置輸出片段文件的名稱格式。
output.m3u8:輸出的 HLS 播放列表文件。
通過這種方式,你可以將 H.265 編碼的視頻轉換為 HLS 流,在前端播放器中實現(xiàn)播放



