JavaScript实现⽹页端播放摄像头实时画⾯
⽬录
初衷
应对的场景
涉及到的范围
解决问题的思路
摄像头的Rtsp地址
ffmpeg下载,安装,配置环境变量
nodejs和Express
JSMpeg播放和请求打开关闭
初衷
写这篇博客已经是项⽬过去很久了,之所以写是因为当时被这个问题为难了很久。我原本是做后端的,涉及到前端的东西,当时是两眼⼀⿊。好在最后还是解决了。当相信这个内容还是有价值的,所以今天整理出来,帮助未来可能需求的⼈。
应对的场景
希望在⾃⼰的Web应⽤中播放局域⽹(不能上云),或是⼴域⽹的摄像头实时画⾯。
涉及到的范围
Nodejs 以及 Express
WebSocket html页⾯拉流
ffmpeg 推流⽤
node-rtsp-stream 主要依赖这个东西,将 rtsp 流推送到 Ws
JSMpeg 主要⽤来播放 ws 流画⾯
这个解决⽅案是全前端⽅案,所以后端的流处理都是⽤Node处理的。
解决问题的思路
⾸先要拿到摄像头的播放Rtsp通道。(有些是带密码的,有些不带密码)。
使⽤ffmpeg将rtsp流转成ws流。
当客户端请求播放摄像头画⾯的时候,Node接受请求,并将流地址返回给前端。
前端使⽤ JSMpeg 去播放ws流,画⾯呈现。
闭关的时候,仍然请求后端,⽤Node处理。闭关推流进程。
摄像头的Rtsp地址
因为这⾥没有摄像头,所以我在⽹上搜索了⼀个流地址:
rtsp://wowzaec2demo.streamlock/vod/mp4:v'
如果电脑中装了 VCL,则可以使⽤VCL的流地址播放功能去播放,这⾥我就不做演⽰了。
ffmpeg 下载,安装,配置环境变量
这⾥我在gitHub上到了⼀个 ,这个版本是windows版本的。
安装就不⽤说了,下⼀步,下⼀步即可,最后就说配置环境变量。其作⽤就是在命令⾏状态下可以直接通过 ffmpeg 访问到⽂件。nodejs 和 Express
nodejs 我就不详细介绍了,express也⼀样,这两个东西要是不会,这篇⽂章也就不⽤看了。
然后就是写代码接受前端到http请求了。可以参考博客园⾥⾯的express介绍。稍后我会贴出代码,建议看看⽂档。
接受请求的代码
var express = require('express');
const requestmanager = require('../lib/RequestManager')
var router = express.Router();
<('/', function (req, res) {
res.send('Carmeras Server ');
});
/* GET users listing. */
router.post('/', function (req, res) {
var cfg = req.body
let result = new requestmanager().Open(cfg)
res.json(result)
});
router.post('/close', function (req, res) {
var cfg = req.body
new requestmanager().Close(cfg)
res.json({ state: 'close the rtsp stream success.' })
})
这⾥⽤到了 node-rtsp-stream 、express 、express.Router 还引⽤了⼀个 RequestManager,这是我⾃⼰写的⼀个管理请求的包,代码如下:
const Stream = require('node-rtsp-stream')
const os = require('os');
///获取本机ip///
function getIPAdress() {
var interfaces = osworkInterfaces();
for (var devName in interfaces) {
var iface = interfaces[devName];
for (var i = 0; i < iface.length; i++) {
var alias = iface[i];
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
return alias.address;
}
}
}
}
const args = []
const requestManager = function () { }
//这⾥是在原型上加上打开和关闭两个⽅法
requestManager.prototype = {
Open: function (arg) {
let result = {}
if (args.length == 0) {
result = this._create(arg)
result = this._openVideo(result)
} else {
args.forEach(a => {
if (a.rtspUrl == spUrl) {
result = a
}
})
if (result.port === undefined || spUrl === undefined) {
result = this._create(arg)
result = this._openVideo(result)
}
}
result = Object.assign(result,{url:`ws:\\${getIPAdress()}:${result.port}`})
return result;
},
Close: function (arg) {
let result = {}
let idx = -1
idx = args.findIndex(a => a.rtspUrl == spUrl)
if (idx !== -1) {
args[idx].stream.stop()
result = args.splice(idx, 1)
} else {
}
console.log(args)
return result
},
//这⾥是产⽣⼀个随机端⼝号,⽤来推流使⽤。
_randomPort: function () {
let port = Math.floor(Math.random() * (4001 - 3001) + 3001)
return port
},
//这⾥是核⼼推流代码,其实很简单。
_openVideo: function (arg) {
arg.stream = new Stream({
name: 'name',
//streamUrl: 'rtsp://wowzaec2demo.streamlock/vod/mp4:v',
streamUrl: spUrl,
wsPort: arg.port,
ffmpegOptions: { // options ffmpeg flags
'-stats': '', // an option with no neccessary value uses a blank string
'-r': 30, // options with required values specify the value after the key
'-s': arg.size,
'-codec:a': 'mp2',
'-ar': 44100,
'-ac': 1,
'-b:a': '128k'
}
})
return arg
},
//这⾥创建参数。
_create: function (arg) {
let target = {
rtspUrl: 'rtsp://wowzaec2demo.streamlock/vod/mp4:v',
port: this._randomPort(),
size: '1024*768',
stream: null
}
let source = {
rtspUrl: spUrl,
port: this._randomPort(),
size: arg.size,
stream: null
}
Object.assign(target, source)
args.push(target)
return target
}
}
当 Open⽅法被调⽤的时候,node-rtsp-stream会调⽤ ffmepg 程序开始推流。其参数如下:
ffmpegOptions: { // options ffmpeg flags
'-stats': '', // an option with no neccessary value uses a blank string
'-r': 30, // options with required values specify the value after the key
'-s': arg.size,
'-codec:a': 'mp2',
'-ar': 44100,
'-ac': 1,
'-b:a': '128k'
}
这⾥关注 -s 它是设置画幅⼤⼩的。所以我这⾥⽤到了参数 arg.size。带_(下划线)的⽅法内部使⽤。关键位置都给了注视了,⼀般应该是看的懂了。
JSMpeg 播放和请求打开关闭
这是个第三⽅库,在gitee和gitHub上都有,这⾥列出Gitee上的地址我⽤到的关键代码就⼏句
/*初始化并播放*/
let player = new JSMpeg.Player(url, opt);
/*销毁关闭*/
player.destroy()
⾄于请求,可以⽤axios 或是 jquery库,我这⾥⽤的是 jquery
var player
//关闭
function closeStream() {
$.post("127.0.0.1:3000/cameras/close/", { rtspUrl: $('#rtsp').val() }, function (result) {
player.destroy()
js assign})
}
/
/打开
function start() {
var rstp = $('#rtsp').val()
var size = $('#size').val()
$.post("127.0.0.1:3000/cameras/", { rtspUrl:rstp, size: size }, function (result) {
var url = "ws://127.0.0.1:" + result.port;
var canvas = ElementById('video-canvas');
let opt = {
canvas: canvas,
poster: "0.jpg",
}
player = new JSMpeg.Player(url, opt);
})
}
完整的Html如下:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>DEMO node-rtsp-stream-jsmpeg</title>
<script src="jsmpeg/jsmpeg.min.js"></script>
<script src="libs.baidu/jquery/2.0.0/jquery.min.js"></script>
<style type="text/css">
html,
body {
text-align: center;
}
input[type='text'] {
width: 450px;
}
</style>
</head>
<body>
<div>
<!-- <span>rtsp : <input type="text" name="rtsp" id="rtsp" value="rtsp://admin:xcs123456@192.168.3.11:554/h264/ch1/main/av_stream"></span><br /> --> <span>rtsp : <input type="text" name="rtsp" id="rtsp" value="rtsp://wowzaec2demo.streamlock/vod/mp4:v"></span><br />
<span>rtsp : <input type="text" name="size" id="size" value="1024*768"></span><br />
<canvas id="video-canvas">
</canvas><br />
<input type="button" value="Start Stream" onclick="start()">
<input type="button" value="Close Stream" onclick="closeStream()">
</div>
<script type="text/javascript">
var player
function closeStream() {
$.post("127.0.0.1:3000/cameras/close/", { rtspUrl: $('#rtsp').val() }, function (result) {
player.destroy()
})
}
function start() {
var rstp = $('#rtsp').val()
var size = $('#size').val()
$.post("127.0.0.1:3000/cameras/", { rtspUrl:rstp, size: size }, function (result) {
var url = "ws://127.0.0.1:" + result.port;
var canvas = ElementById('video-canvas');
let opt = {
canvas: canvas,
poster: "0.jpg",
}
player = new JSMpeg.Player(url, opt);
})
}
</script>
</body>
以上就是全部的内容,完整代码可以到gitee上。
以上就是JavaScript实现⽹页端播放摄像头实时画⾯的详细内容,更多关于JavaScript摄像头实时画⾯的资料请关注其它相关⽂章!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论