视频墙

merge-requests/1/head
qiushui 4 years ago
parent 84dd6cbf88
commit 03beee4a1d

Binary file not shown.

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

5
package-lock.json generated

@ -3714,6 +3714,11 @@
"hoek": "2.x.x"
}
},
"bootstrap": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz",
"integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",

@ -12,6 +12,7 @@
"ant-design-vue": "^1.6.3",
"antd-theme-generator": "^1.2.8",
"axios": "^0.19.2",
"bootstrap": "^5.1.3",
"core-js": "^3.6.5",
"element-ui": "^2.15.6",
"path-to-regexp": "^6.2.0",

@ -7,10 +7,9 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 加快视频的响应速度-->
<link href="/video_play_plugins/video-js-cdn.min.css" rel="stylesheet">
<script src="/video_play_plugins/video.js"></script>
<script src="/video_play_plugins/videojs-contrib-hls.min.js"></script>
<script src="/video_play_plugins/videojs-contrib-hls.min.js"></script>
<!-- <script src="/video_play_plugins/video.js"></script> -->
<script src="/video_play_plugins/webrtcplayer.js"></script>
<title>垛机视觉系统</title>
</head>

@ -0,0 +1,123 @@
class WebRtcPlayer {
static server = '127.0.0.1:8083';
webrtc = null;
video = null;
server = null;
codecLink = null;
rsdpLink = null;
stream = new MediaStream();
uuid = null;
options={
onStatusChange:null
};
constructor(video1, uuid, options={}) {
console.log("new uuid:"+uuid)
this.server = WebRtcPlayer.server;
//this.video = document.getElementById(id);
this.video = video1
this.uuid = uuid;
Object.assign(this.options, options);
this.createLinks();
this.play();
}
createLinks() {
this.codecLink = "//" + this.server + "/stream/codec/" + this.uuid
this.rsdpLink = "//" + this.server + "/stream/receiver/" + this.uuid
}
play() {
this.webrtc = new RTCPeerConnection({
iceServers: [{
urls: ["stun:stun.l.google.com:19302"]
}]
});
if(this.webrtc){
}else{
console.log("no")
}
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded.bind(this);
this.webrtc.ontrack = this.onTrack.bind(this);
fetch(this.codecLink)
.then((response) => {
response.json().then((data) => {
data.forEach((item, i) => {
this.webrtc.addTransceiver(item.Type, {
'direction': 'sendrecv'
});
});
});
})
.catch((error) => {
console.log(error);
});
this.webrtc.onconnectionstatechange = () => {
if(this.webrtc.connectionState == 'connected' || this.webrtc.connectionState == 'connecting'){
console.log("uuid:"+this.uuid+" status:" + this.webrtc.connectionState)
}else{
console.log(this.webrtc.connectionState)
this.load(this.uuid);
}
}
}
async handleNegotiationNeeded() {
let offer = await this.webrtc.createOffer();
await this.webrtc.setLocalDescription(offer);
let formData = new FormData();
formData.append('suuid', this.uuid);
formData.append('data', btoa(this.webrtc.localDescription.sdp));
fetch(this.rsdpLink, {
method: 'POST',
body: formData
})
.then((response) => {
response.text().then((data) => {
this.webrtc.setRemoteDescription(new RTCSessionDescription({
type: 'answer',
sdp: atob(data)
}))
});
})
.catch((err) => {})
}
onTrack(event) {
this.stream.addTrack(event.track);
this.video.srcObject = this.stream;
this.video.play();
}
load(uuid) {
this.destroy();
this.uuid = uuid;
this.createLinks();
this.play();
}
destroy() {
console.log("destroy uuid:"+this.uuid)
this.webrtc.close();
this.webrtc = null;
this.video.srcObject = null;
this.stream = new MediaStream();
}
getImageUrl() {
let canvas = document.createElement("canvas");
canvas.width = this.video.videoWidth;
canvas.height = this.video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
let dataURL = canvas.toDataURL();
canvas.remove();
return dataURL;
}
static setServer(serv) {
this.server = serv;
}
}
export default WebRtcPlayer;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

@ -1,12 +0,0 @@
{
"program": {
"portable": {
"pnacl-translate": {
"url": "media_player.pexe"
},
"pnacl-debug": {
"url": "media_player_unstripped.bc"
}
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -50,6 +50,16 @@ export default {
url: "/realTime/videoServer",
name: "获取视频服务器"
},
getAllCameras:{
method: "GET",
url: "/realTime/allCameras",
name: "获取全部球机"
},
getWallStyle:{
method: "GET",
url: "/realTime/wallStyle",
name: "获取视频墙样式"
},
addCamera: {
method: "POST",
url: "/camera",

@ -1,9 +1,10 @@
<template>
<div class="wrap">
<!-- 面包屑下标题 -->
<keep-alive>
<router-view :exclude="['checkManage']" class="table"></router-view>
</keep-alive>
<router-view :exclude="['checkManage','realTimeMonitoring']" class="table"></router-view>
<!-- <keep-alive>
</keep-alive> -->
<!-- footer -->
<div class="wrap-footer bg-white">

@ -39,15 +39,7 @@ const routes = [{
component: () => import('@/views/realTimeMonitoring/index'),
},
{
path: 'realTimeMonitoring/model',
name: 'realTimeMonitoringModel',
meta: {
name: '实时视频流(全屏)'
},
component: () => import('@/views/realTimeMonitoring/model'),
},
{
path: 'historyMonitoring',
name: 'historyMonitoring',
@ -57,15 +49,6 @@ const routes = [{
},
component: () => import('@/views/historyMonitoring/index')
},
// {
// path: 'alarmVideos',
// name: 'alarmVideos',
// meta: {
// icon: 'alert',
// name: '告警视频'
// },
// component: () => import('@/views/alarmVideos/index')
// },
{
path: 'alarmLog',
name: 'alarmLog',
@ -136,6 +119,15 @@ const routes = [{
},
component: () => import('@/views/repertoryManage/index')
},
{
path: 'videoWall',
name: 'videoWall',
meta: {
icon: 'desktop',
name: '视频墙'
},
component: () => import('@/views/videoWall/index'),
},
{
path: 'cameraManage/ioTable',
name: 'ioTable',

@ -11,7 +11,7 @@ const store = {
"primary-color":"rgba(184, 68, 13, 1)"
},
"title":{
"text":"昆船垛机视觉系统",
"text":"垛机智能视觉系统",
"style":{
"color":"rgba(255, 255, 255, 1)",
"background-color":"rgba(163, 60, 12, 1)",

@ -197,7 +197,7 @@ const columns = [
scopedSlots: { customRender: 'position' }
}
];
import WebRtcPlayer from "./webrtcplayer"
import WebRtcPlayer from "../../../public/static/webrtcplayer"
export default {
props:[ 'visible', 'modelType', 'modelData'],
watch: {

@ -1,123 +0,0 @@
class WebRtcPlayer {
static server = '127.0.0.1:8083';
webrtc = null;
video = null;
server = null;
codecLink = null;
rsdpLink = null;
stream = new MediaStream();
uuid = null;
options={
onStatusChange:null
};
constructor(video1, uuid, options={}) {
console.log("new uuid:"+uuid)
this.server = WebRtcPlayer.server;
//this.video = document.getElementById(id);
this.video = video1
this.uuid = uuid;
Object.assign(this.options, options);
this.createLinks();
this.play();
}
createLinks() {
this.codecLink = "//" + this.server + "/stream/codec/" + this.uuid
this.rsdpLink = "//" + this.server + "/stream/receiver/" + this.uuid
}
play() {
this.webrtc = new RTCPeerConnection({
iceServers: [{
urls: ["stun:stun.l.google.com:19302"]
}]
});
if(this.webrtc){
}else{
console.log("no")
}
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded.bind(this);
this.webrtc.ontrack = this.onTrack.bind(this);
fetch(this.codecLink)
.then((response) => {
response.json().then((data) => {
data.forEach((item, i) => {
this.webrtc.addTransceiver(item.Type, {
'direction': 'sendrecv'
});
});
});
})
.catch((error) => {
console.log(error);
});
this.webrtc.onconnectionstatechange = () => {
if(this.webrtc.connectionState == 'connected' || this.webrtc.connectionState == 'connecting'){
console.log("uuid:"+this.uuid+" status:" + this.webrtc.connectionState)
}else{
console.log(this.webrtc.connectionState)
this.load(this.uuid);
}
}
}
async handleNegotiationNeeded() {
let offer = await this.webrtc.createOffer();
await this.webrtc.setLocalDescription(offer);
let formData = new FormData();
formData.append('suuid', this.uuid);
formData.append('data', btoa(this.webrtc.localDescription.sdp));
fetch(this.rsdpLink, {
method: 'POST',
body: formData
})
.then((response) => {
response.text().then((data) => {
this.webrtc.setRemoteDescription(new RTCSessionDescription({
type: 'answer',
sdp: atob(data)
}))
});
})
.catch((err) => {})
}
onTrack(event) {
this.stream.addTrack(event.track);
this.video.srcObject = this.stream;
this.video.play();
}
load(uuid) {
this.destroy();
this.uuid = uuid;
this.createLinks();
this.play();
}
destroy() {
console.log("destroy uuid:"+this.uuid)
this.webrtc.close();
this.webrtc = null;
this.video.srcObject = null;
this.stream = new MediaStream();
}
getImageUrl() {
let canvas = document.createElement("canvas");
canvas.width = this.video.videoWidth;
canvas.height = this.video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
let dataURL = canvas.toDataURL();
canvas.remove();
return dataURL;
}
static setServer(serv) {
this.server = serv;
}
}
export default WebRtcPlayer;

@ -29,9 +29,9 @@
<script>
import WebRtcPlayer from "./webrtcplayer"
import WebRtcPlayer from "../../../public/static/webrtcplayer"
export default {
name: "historyMonitoring",
name: "realTimeMonitoring",
components: {
//VideoPlayer
},
@ -45,7 +45,7 @@ export default {
visible: false,
modelData: [],
clientHeight: 0,
showVideo: false,
players: []
};
},
@ -57,18 +57,17 @@ export default {
return this.selectTab.cameras || [];
},
videoHeight() {
return (( this.clientHeight - this.selectTab.videoStyleRow * 20 )/ this.selectTab.videoStyleRow ) + 'px'
return (( this.clientHeight)/ this.selectTab.videoStyleRow ) + 'px'
},
},
inject: ['reload'],
//inject: ['reload'],
mounted() {
this.getClientHeight()
this.setVideoServer()
this.getRealTimeList()
if (sessionStorage.getItem('tabKey') == null) {
sessionStorage.setItem('tabKey', 0)
}
this.tabKey = sessionStorage.getItem('tabKey');
this.getClientHeight();
},
destroyed() {
this.destory()
@ -78,13 +77,17 @@ export default {
this.clientHeight = this.$el.clientHeight - 80;
},
getRealTimeList(){
this.showVideo = false;
this.$api.httpApi.getRealTimeList({
data: {}
}).then(res => {
if(res.code == 200) {
this.realTimeListData = res.data.reverse();
this.showVideo = true;
if (sessionStorage.getItem('tabKey') == null) {
console.log("tabKey"+this.realTimeListData[0].id)
sessionStorage.setItem('tabKey', this.realTimeListData[0].streetId)
this.tabKey = sessionStorage.getItem('tabKey');
}
this.$nextTick(() => {
this.autoPlay()
})
@ -97,24 +100,22 @@ export default {
tabsChange(key) {
sessionStorage.setItem('tabKey', key)
this.destory()
this.$nextTick(() => {
this.autoPlay()
})
},
showModel(item) {
this.$nextTick(() => {
this.$router.push({name: "realTimeMonitoringModel", query: {modelData: item}});
})
},
autoPlay(){
this.players = []
for(var a of this.realTimeListData){
for (let b of a.cameras){
let video = document.getElementById('camera'+b.id);
if(video){
console.log("play:"+b.id)
let player = new WebRtcPlayer(video,'camera'+b.id);
player.load('camera'+b.id);
player.play('camera'+b.id);
this.players.push(player)
}

@ -1,123 +0,0 @@
class WebRtcPlayer {
static server = '127.0.0.1:8083';
webrtc = null;
video = null;
server = null;
codecLink = null;
rsdpLink = null;
stream = new MediaStream();
uuid = null;
options={
onStatusChange:null
};
constructor(video1, uuid, options={}) {
console.log("new uuid:"+uuid)
this.server = WebRtcPlayer.server;
//this.video = document.getElementById(id);
this.video = video1
this.uuid = uuid;
Object.assign(this.options, options);
this.createLinks();
this.play();
}
createLinks() {
this.codecLink = "//" + this.server + "/stream/codec/" + this.uuid
this.rsdpLink = "//" + this.server + "/stream/receiver/" + this.uuid
}
play() {
this.webrtc = new RTCPeerConnection({
iceServers: [{
urls: ["stun:stun.l.google.com:19302"]
}]
});
if(this.webrtc){
}else{
console.log("no")
}
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded.bind(this);
this.webrtc.ontrack = this.onTrack.bind(this);
fetch(this.codecLink)
.then((response) => {
response.json().then((data) => {
data.forEach((item, i) => {
this.webrtc.addTransceiver(item.Type, {
'direction': 'sendrecv'
});
});
});
})
.catch((error) => {
console.log(error);
});
this.webrtc.onconnectionstatechange = () => {
if(this.webrtc.connectionState == 'connected' || this.webrtc.connectionState == 'connecting'){
console.log("uuid:"+this.uuid+" status:" + this.webrtc.connectionState)
}else{
console.log(this.webrtc.connectionState)
this.load(this.uuid);
}
}
}
async handleNegotiationNeeded() {
let offer = await this.webrtc.createOffer();
await this.webrtc.setLocalDescription(offer);
let formData = new FormData();
formData.append('suuid', this.uuid);
formData.append('data', btoa(this.webrtc.localDescription.sdp));
fetch(this.rsdpLink, {
method: 'POST',
body: formData
})
.then((response) => {
response.text().then((data) => {
this.webrtc.setRemoteDescription(new RTCSessionDescription({
type: 'answer',
sdp: atob(data)
}))
});
})
.catch((err) => {})
}
onTrack(event) {
this.stream.addTrack(event.track);
this.video.srcObject = this.stream;
this.video.play();
}
load(uuid) {
this.destroy();
this.uuid = uuid;
this.createLinks();
this.play();
}
destroy() {
console.log("destroy uuid:"+this.uuid)
this.webrtc.close();
this.webrtc = null;
this.video.srcObject = null;
this.stream = new MediaStream();
}
getImageUrl() {
let canvas = document.createElement("canvas");
canvas.width = this.video.videoWidth;
canvas.height = this.video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
let dataURL = canvas.toDataURL();
canvas.remove();
return dataURL;
}
static setServer(serv) {
this.server = serv;
}
}
export default WebRtcPlayer;

@ -0,0 +1,192 @@
<template>
<div id="videos">
<a-button type="primary" @click="full" v-if="!isFullscreen"> <a-icon type="right" /> </a-button>
<a-button type="primary" @click="full" v-if="isFullscreen"><a-icon type="left" /> 退出全屏 </a-button>
<a-row v-for='rowIndex in row' :key='rowIndex'>
<a-col v-for='colIndex in column' :key='colIndex' :span="24/column" :style="{height: videoHeight}">
<video class="camera" :id="rowIndex+'-'+colIndex" autoplay muted controls :style="{'height': '100%',width:'100%','object-fit':'fill'}"></video>
</a-col>
</a-row>
</div>
</template>
<script>
import WebRtcPlayer from "../../../public/static/webrtcplayer"
export default {
name: 'top',
components: {},
props: {
id: {
type: String,
default () {
return ''
}
}
},
data () {
return {
row : 0,
column : 0,
a: 0,
clientHeight: 0,
videoH: 0,
isFullscreen: false,
originHeight: 0,
fullHeight: 0
}
},
//watch: {},
computed: {
videoHeight() {
return( this.clientHeight/ this.row ) + 'px';
}
},
mounted () {
this.getWallStyle();
this.$nextTick(() => {
this.getAllCameras()
});
let isFullscreen =
document.fullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
document.fullScreen ||
document.mozFullScreen ||
document.webkitIsFullScreen;
this.isFullscreen = !!isFullscreen;
let that = this;
document.addEventListener("fullscreenchange", () => {
that.isFullscreen = !that.isFullscreen;
});
document.addEventListener("mozfullscreenchange", () => {
that.isFullscreen = !that.isFullscreen;
});
document.addEventListener("webkitfullscreenchange", () => {
that.isFullscreen = !that.isFullscreen;
});
document.addEventListener("msfullscreenchange", () => {
that.isFullscreen = !that.isFullscreen;
});
},
methods: {
getWallStyle(){
this.$api.httpApi.getWallStyle({
data: {}
}).then(res => {
if(res.code == 200) {
this.row = res.data[0];
this.column = res.data[1];
this.getClientHeight();
sessionStorage.setItem('originHeight', this.clientHeight)
}
}).catch(err => {
console.log(err)
})
},
getClientHeight() {
this.clientHeight = this.$el.clientHeight-40;
console.log("clientHeight:"+this.clientHeight)
},
getAllCameras(){
this.$api.httpApi.getAllCameras({
data: {}
}).then(res => {
if(res.code == 200) {
let cameras = res.data;
for(let i = 1;i<=cameras.length;i++){
let rowIndex = Math.floor((i-1) / this.column) + 1;
if(rowIndex > this.row){
return
}
let columnIndex = i % this.column;
if(columnIndex == 0){
columnIndex = this.column;
}
let idName = rowIndex + "-" + columnIndex;
console.log("idName:"+idName);
let video = document.getElementById(idName);
let player = new WebRtcPlayer(video,"camera"+cameras[i].id);
player.play('camera'+cameras[i].id);
}
}
}).catch(err => {
console.log(err)
})
},
full () {
if(this.isFullscreen){
this.exitfullscreen()
}else{
this.enterfullscreen()
}
},
//
enterfullscreen () { //
var docElm = document.getElementById('videos') // id
//W3C
if (docElm.requestFullscreen) {
docElm.requestFullscreen()
}
//FireFox
else if (docElm.mozRequestFullScreen) {
docElm.mozRequestFullScreen()
}
//Chrome
else if (docElm.webkitRequestFullScreen) {
docElm.webkitRequestFullScreen()
}
//IE11
else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen()
}
this.$nextTick(() => {
this.clientHeight = document.body.clientHeight;
console.log("full:"+document.body.clientHeight)
})
},
//退
exitfullscreen () {
console.log("tuichu");
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
this.$nextTick(() => {
let origin = sessionStorage.getItem('originHeight');
if(origin){
this.clientHeight = origin;
}else{
this.getClientHeight();
}
})
}
}
}
</script>
<style>
/* #videos > .ant-row {
height: calc(100% / 8);
}
#videos > .ant-row > .ant-col{
height: calc(100% / 8);
} */
</style>
Loading…
Cancel
Save