有同學(xué)問(wèn)道:需要實(shí)時(shí)播放攝像頭rtsp視頻流,而瀏覽器不能直接播放,怎樣解決?
實(shí)現(xiàn)這個(gè)需求可以通過(guò)插件或者轉(zhuǎn)碼來(lái)實(shí)現(xiàn)。
要實(shí)現(xiàn)這個(gè)目的,可以采用的方案非常得多,有商業(yè)的也有開(kāi)源的,這里主要列舉一些開(kāi)源的方案。這里的方案都是我嘗試過(guò)了的,有些成功,有些沒(méi)成功。但是因?yàn)槊總€(gè)項(xiàng)目情況不同,這次沒(méi)成的方法,換個(gè)項(xiàng)目也許就能成。
方案一: html5 + websocket_rtsp_proxy 實(shí)現(xiàn)視頻流直播
實(shí)現(xiàn)原理
實(shí)現(xiàn)步驟
- 服務(wù)器安裝streamedian服務(wù)器
- 客戶端通過(guò)video標(biāo)簽播放
<video id="test_video" controls autoplay></video>
<script src="free.player.1.8.4.js"></script>
<script>
if (window.Streamedian) {
var errHandler = function(err){
console.log('err', err.message);
};
var infHandler = function(inf) {
console.log('info', inf)
};
var playerOptions = {
socket: "ws://localhost:8088/ws/",
redirectNativeMediaErrors : true,
bufferDuration: 30,
errorHandler: errHandler,
infoHandler: infHandler
};
var html5Player = document.getElementById("test_video");
html5Player.src = "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov";
var player = Streamedian.player('test_video', playerOptions);
window.onbeforeunload = function(){
player && player.destroy();
player = null;
Request = null;
}
}
</script>
注意:測(cè)試時(shí)先從官網(wǎng)申請(qǐng)license key,否則socket 只能識(shí)別localhost和127.0.0.1
優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn):實(shí)現(xiàn)比較簡(jiǎn)單
- 缺點(diǎn):收費(fèi)的,免費(fèi)版有很多限制
方案二:ffmpeg + Nginx + video,rtsp轉(zhuǎn)rtmp播放
rtmp是adobe開(kāi)發(fā)的協(xié)議,一般使用adobe media server 可以方便的搭建起來(lái);隨著開(kāi)源時(shí)代的到來(lái),有大神開(kāi)發(fā)了nginx的rtmp插件,也可以直接使用nginx實(shí)現(xiàn)rtmp
rtmp方式的最大的優(yōu)點(diǎn)在于低延時(shí),經(jīng)過(guò)測(cè)試延時(shí)普遍在1-3秒,可以說(shuō)很實(shí)時(shí)了;缺點(diǎn)在于它是adobe開(kāi)發(fā)的,rtmp的播放嚴(yán)重依賴flash,而由于flash本身的安全,現(xiàn)代瀏覽器大多禁用flash
實(shí)現(xiàn)步驟
- 安裝ffmpeg工具
- 安裝nginx 注意:linux系統(tǒng)需要安裝 nginx-rtmp-module 模塊,windows系統(tǒng)安裝包含rtmp的(如nginx 1.7.11.3 Gryphon)
- 更改nginx配置
rtmp{
server{
listen 1935;
Application live{
live on;
record off;
}
application hls{
live on;
hls on;
hls_path nginx-rtmp-module/hls;
hls_cleanup off;
}
}
}
4.ffmpeg轉(zhuǎn)碼
ffmpeg -i "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov" -f flv -r 25 -s 1080*720 -an "rtmp://127.0.0.1:1935/hls/mystream"
5.video 播放
<html>
<head>
<title>video</title>
<!-- 引入css -->
<link rel="stylesheet" type="text/css" href="./videojs/video-js.min.css" />
</head>
<body>
<video id="test_video" class="video-js vjs-default-skin vjs-big-play-centered" controls autoplay>
<source src='rtmp://127.0.0.1:1935/hls/mystream' type='rtmp/flv'/>
</video>
</body>
</html>
<!-- 引入js -->
<script type="text/JAVAscript" src="./videojs/video.min.js"></script>
<script type="text/JavaScript" src="./videojs/videojs-flash.js"></script>
<script>
videojs.options.flash.swf = "./videojs/video-js.swf"
var player = videojs('test_video', {"autoplay":true});
player.play();
</script>
注意:使用谷歌瀏覽器播放時(shí),需要開(kāi)啟flash允許
方案三:ffmpeg + video,rtsp轉(zhuǎn)hls播放
HLS (HTTP Live Streaming) 直播 是有蘋(píng)果提出的一個(gè)基于http的協(xié)議。其原理是把整個(gè)流切分成一個(gè)個(gè)的小視頻文件,然后通過(guò)一個(gè)m3u8的文件列表來(lái)管理這些視頻文件
HTTP Live Streaming 并不是一個(gè)真正實(shí)時(shí)的流媒體系統(tǒng),這是因?yàn)閷?duì)應(yīng)于媒體分段的大小和持續(xù)時(shí)間有一定潛在的時(shí)間延時(shí)。在客戶端,至少在一個(gè)分段媒體文件被完全下載后才能夠開(kāi)始播放,而通常要求下載完兩個(gè)媒體文件之后才開(kāi)始播放以保證不同分段音視頻之間的無(wú)縫連接。
此外,在客戶端開(kāi)始下載之前,必須等待服務(wù)器端的編碼器和流分割器至少生成一個(gè)TS文件,這也會(huì)帶來(lái)潛在的時(shí)延。
服務(wù)器軟件將接收到的流每緩存一定時(shí)間后包裝為一個(gè)新的TS文件,然后更新m3u8文件。m3u8文件中只保留最新的幾個(gè)片段的索引,以保證觀眾任何時(shí)候連接進(jìn)來(lái)都會(huì)看到較新的內(nèi)容,實(shí)現(xiàn)近似直播的效果。
這種方式的理論最小延時(shí)為一個(gè)ts文件的時(shí)長(zhǎng),一般為2-3個(gè)ts文件的時(shí)長(zhǎng)。
實(shí)現(xiàn)步驟
- 安裝ffmpeg工具
- ffmpeg轉(zhuǎn)碼
ffmpeg -i "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov" -c copy -f hls -hls_time 2.0 -hls_list_size 0 -hls_wrap 15 "D:/Program Files/html/hls/test.m3u8"
ffmpeg 關(guān)于hls方面的指令說(shuō)明
- -hls_time n: 設(shè)置每片的長(zhǎng)度,默認(rèn)值為2。單位為秒
- -hls_list_size n:設(shè)置播放列表保存的最多條目,設(shè)置為0會(huì)保存有所片信息,默認(rèn)值為5
- -hls_wrap n:設(shè)置多少片之后開(kāi)始覆蓋,如果設(shè)置為0則不會(huì)覆蓋,默認(rèn)值為0.這個(gè)選項(xiàng)能夠避免在磁盤(pán)上存儲(chǔ)過(guò)多的片,而且能夠限制寫(xiě)入磁盤(pán)的最多的片的數(shù)量
- -hls_start_number n:設(shè)置播放列表中sequence number的值為number,默認(rèn)值為0
3.video 播放
<html>
<head>
<title>video</title>
<!-- 引入css -->
<link rel="stylesheet" type="text/css" href="./videojs/video-js.min.css" />
</head>
<body>
<div class="videoBox">
<video id="my_video_1" class="video-js vjs-default-skin" controls>
<source src="http://localhost:8088/hls/test.m3u8" type="application/x-mpegURL">
</video>
</div>
</body>
</html>
<script type="text/javascript" src="./videojs/video.min.js"></script>
<script type="text/javascript" src="./videojs/videojs-contrib-hls.min.js"></script>
<script>
videojs.options.flash.swf = "./videojs/video-js.swf"
var player = videojs('my_video_1', {"autoplay":true});
player.play();
</script>
方案四:VLC插件播放
播放步驟
- 下載安裝vlc
- 瀏覽器播放
<object type='application/x-vlc-plugin' pluginspage="http://www.videolan.org/" id='vlc' events='false' width="720" height="410">
<param name='mrl' value='rtsp://admin:[email protected]:554/h264/ch1/main/av_stream' />
<param name='volume' value='50' />
<param name='autoplay' value='true' />
<param name='loop' value='false' />
<param name='fullscreen' value='false' />
<param name='controls' value='false' />
</object>
優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn): 可以直接播放RTSP,無(wú)需任何中介服務(wù)器的幫助
- 缺點(diǎn): 需要手動(dòng)安裝插件; 基于NPAPI,不被最新的 Chrome 和 Firefox 支持
- 如果你項(xiàng)目的其他功能都能兼容客戶電腦上的 IE 瀏覽器,這個(gè)方案就是首選。
其他方案
WebRTC
WebRTC 是支持網(wǎng)頁(yè)瀏覽器進(jìn)行實(shí)時(shí)音視頻的一套API,例如:HTML5 通過(guò) webRTC 直接調(diào)用攝像頭,但是如果要實(shí)現(xiàn)遠(yuǎn)程視頻流的顯示,則需要將 RTSP 轉(zhuǎn)換為 WebRTC 流,供 web 端顯示。
h5stream
GB28181
jsmpeg.js + ffmpeg + websocket + node
如果你對(duì)音視頻開(kāi)發(fā)感興趣,或者對(duì)本文的一些闡述有自己的看法,可以在下方的留言框,一起探討。






