Vue 之 视频流 - Streamedian.js
Vue 之 使用streamedian播放rtsp格式的视频流
·
目录
一、前情提要
1. 作用
作用 : 使用 streamedian 播放 rtsp 格式的视频流
2. 准备一
需要后端的支持
3. 准备二
rtsp流需要有对应的websock地址
拥有了rtsp流地址和websock地址这两样,才能播放
4. 准备三
若是现场环境,需要连接VPN
二、开始使用
1. 安装依赖
npm install long --- npm install babel-polyfill
2. 下载streamedian.js文件
我的资料库中可以下载,实在太长,这里放不下
网址 : streamedian.min.js
3. 代码
HTML
<template>
<div class="about-layout">
<input type="button" value="play" @click="onPlay" id="play" />
<div id="container">
<div id="video_overlays"></div>
<canvas id="canvas" width="1280" height="720"></canvas>
<video id="test_video" autoplay muted></video>
</div>
<p id="error_msg"></p>
</div>
</template>
JS
import "./js/streamedian.min.js";
export default {
name: "playVideo",
data() {
return {
videoRtsp:
"rtsp://rtsp的地址",
videoWs: "ws://websock的地址",
ObjectType: {},
p: null,
player: null,
canvas: null,
heatmapRenderer: null,
scale: 0,
};
},
props: {
videoPath: { //传过来的rtsp的地址
type: String,
default: "",
},
},
methods: {
//关闭弹窗
closeVideo() {
this.$emit("closeVideo");
},
//初始化数据
init() {
this.player = document.getElementById("test_video");
this.canvas = document.getElementById("canvas");
var config = {
canvas: canvas,
canvasWidth: 1280,
canvasHeight: 720,
enableSmoothing: true,
pixelAlpha: 255,
colormap: null, //use default
};
this.heatmapRenderer = Streamedian.heatmapRenderer(config);
},
update(currentTime, previewInfo) {
if (previewInfo) {
previewInfo.objects.forEach(function (target) {
if (
target &&
target.objectType == 6 &&
target.crowd &&
target.crowd.densitySize.width
) {
var start = Date.now();
// console.log(bytesToHex(target.crowd.density));
this.heatmapRenderer.render(
target.crowd.density,
target.crowd.densitySize.width,
target.crowd.densitySize.height
);
var millis = Date.now() - start;
console.log("milli seconds elapsed = " + Math.floor(millis));
}
let items = [];
if (target.attributes && PreviewInfoMap[target.objectType]) {
for (let i in PreviewInfoMap[target.objectType].attrs) {
let title = PreviewInfoMap[target.objectType].attrs[i];
let value = target.attributes[i];
if (value && attributeEnabled(target.objectType, i)) {
items.push("" + title + ": " + value);
}
}
}
if (!target.bounding) {
return;
}
});
}
},
reconnectHandler(e) {
return new Promise((resolve, reject) => {
document.getElementById(
"error_msg"
).innerHTML = `连接错误${e.code}: ${e.msg}`;
document.getElementById("operators").style.display = "unset";
document.getElementById("reconnect").addEventListener("click", () => {
document.getElementById("error_msg").innerHTML = "";
document.getElementById("operators").style.display = "none";
resolve();
});
document.getElementById("cancel").addEventListener("click", () => {
document.getElementById("error_msg").innerHTML = "已断开连接";
document.getElementById("operators").style.display = "none";
reject();
});
});
},
onPlay() {
document.getElementById("error_msg").innerHTML = "";
let host = this.videoWs;
let source = this.videoRtsp;
console.log("PLAY: ", source);
if (this.p) {
this.p.destroy();
}
this.p = Streamedian.player("test_video", {
socket: host,
reconnectHandler: this.reconnectHandler,
});
this.p.setSource(source, "rtsp");
document
.getElementById("test_video")
.addEventListener("error", function (e) {
console.error(e);
});
this.animLoop();
return true;
},
animLoop() {
var running,
lastFrame = window.performance.now();
let player = this.player;
let p = this.p;
let that = this;
function loop(now) {
if (running !== false) {
requestAnimationFrame(loop);
let videoWidth = player.videoWidth;
let scale = 0;
if (videoWidth > 0) {
scale = 1280.0 / videoWidth;
that.scale = scale;
}
let ev = p.pullOOBData(player.currentTime + 0.01);
if (ev && ev.length > 0) {
ev.forEach(function (last) {
let seiID = last.payload.subarray(0, 16).toString();
if (scale > 0 && last.foundIDR && PreviewInfo) {
let pi = PreviewInfo.decode(last.payload.subarray(16));
console.log("decoded = ", JSON.stringify(pi));
overlay.update(now, pi);
}
});
} else {
that.update(now, null);
}
lastFrame = now;
}
}
loop(lastFrame);
},
},
mounted() {
this.init();
},
};
更多推荐
已为社区贡献3条内容
所有评论(0)