HTML播放RTSP视频

目前公司在做摄像头项目,需要在web页面上播放rtsp视频流,以下为整理的资料

研究

经过一番搜索,发现html是不能直接播放rtsp流的,只有两种方案,一个是用插件,另一个就是是转码

插件方案

  1. VLC
    VLC可以直接播放RTSP,但是现代浏览器用不了,只能老IE才能用,所以直接放弃了。
  2. Flash
    Flash方案可以播放RTSP,我用locomote尝试了以下,需要把.js.swf文件放进目录里
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    <div id="player" style="width: 640px; height: 480px;"></div>
    <script src="locomote.min.js"></script>
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {
    /* Load SWF and instantiate Locomote */
    var locomote = new Locomote('player', 'Player.swf');

    /* Set up a listener for when the API is ready to be used */
    locomote.on('apiReady', function() {
    console.log('API is ready. `play` can now be called');

    /* Tell Locomote to play the specified media */
    locomote.play('rtsp://192.168.10.51:554');
    });

    /* Start listening for streamStarted event */
    locomote.on('streamStarted', function() {
    console.log('stream has started');
    });

    /* If any error occurs, we should take action */
    locomote.on('error', function(err) {
    console.log(err);
    });
    });
    </script>
    运行起来发现会报错,原因是从Flash 10开始,需要一个Socket Policy Server来“授权”。所以要在843端口上起一个服务来返回授权信息 SETTING UP A SOCKET POLICY FILE SERVER
    服务启动后就能在浏览器中看见视频了,不过我这边视频播放了一会儿被Flash主动断开了,也失败了。

转码方案

转码方案就比较灵活了,可以转成浏览器支持的格式进行播放。
参考了网上的方案用FFmpeg这个软件把rtsp转换成flv格式,使用WebSocket进行传输,浏览器上使用Bilibili开源的flv.js进行播放,实现了浏览器无插件播放

服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
var express = require('express');
var expressWebSocket = require("./node_modules/express-ws");
const ffmpegInstaller = require('@ffmpeg-installer/ffmpeg');
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
var webSocketStream = require("websocket-stream/stream");
var WebSocket = require("websocket-stream");
var http = require("http");

function localServer() {
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: 1000000
});
let url = req.query.url;
console.log("rtsp url:", url);
console.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);
}
}

localServer()
浏览器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<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>

参考链接

参考:HTML5 播放 RTSP 视频
参考:html5播放rtsp方案
参考:如何不花钱让html5播放rtsp视频流
参考:浏览器播放rtsp视频流解决方案
参考:html5-dash-hls-rtmp
参考:几种浏览器播放RTSP视频流的方案

如果摄像头可以输出H264裸流,可以尝试以下方案

参考:H5解码H264实时视频流
参考:用于原始h.264流的HTML5播放器
参考:wfs.js
参考:web无插件解码播放H264/H265(js解码HTML5播放)
参考:web无插件解码播放H264/H265(WebAssembly解码HTML5播放)
参考:JS如何调用WebAssembly的api

参考:html h264
参考:MarkRepo/wfs.js

参考:h264-live-player