|
|
|
|
<template>
|
|
|
|
|
<div class="container">
|
|
|
|
|
<div class="video-title">
|
|
|
|
|
<div class="main-title">车辆实时监控</div>
|
|
|
|
|
<div class="title-btn">
|
|
|
|
|
<img src="../assets/images/sx.png" alt="" />
|
|
|
|
|
刷新
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="carousel">
|
|
|
|
|
<div @click="scroll(-1)" class="scroll-btn left">
|
|
|
|
|
<i class="el-icon-arrow-left"></i>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="items-wrapper" ref="itemsWrapper">
|
|
|
|
|
<div v-for="(item, index) in items" :key="index" class="item">
|
|
|
|
|
<video
|
|
|
|
|
:id="'video' + index"
|
|
|
|
|
class="video-src"
|
|
|
|
|
autoplay="autoplay"
|
|
|
|
|
@timeupdate="handleTimeUpdate($event, index)"
|
|
|
|
|
/>
|
|
|
|
|
<div class="video-bg" v-show="item.sate != 0">
|
|
|
|
|
{{ item.sate == 1 ? "正在播放中" : "已播放结束" }}
|
|
|
|
|
</div>
|
|
|
|
|
<div class="video-data">
|
|
|
|
|
<div class="video-name">{{ item.tdhName }}</div>
|
|
|
|
|
<img
|
|
|
|
|
@click="handleVideo(item, index)"
|
|
|
|
|
class="video-icon"
|
|
|
|
|
src="../assets/images/zoom.png"
|
|
|
|
|
alt=""
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div @click="scroll(1)" class="scroll-btn right">
|
|
|
|
|
<i class="el-icon-arrow-right"></i>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<el-dialog
|
|
|
|
|
custom-class="video-dialog"
|
|
|
|
|
:visible.sync="dialogVisible"
|
|
|
|
|
append-to-body
|
|
|
|
|
:modal="false"
|
|
|
|
|
:destroy-on-close="true"
|
|
|
|
|
>
|
|
|
|
|
<div class="video-dialog-top">
|
|
|
|
|
<div class="video-name-data">001号线_01_早送_守押001_苏E</div>
|
|
|
|
|
<div class="dialog-close" @click="handleClose('0521')">
|
|
|
|
|
<img src="../assets/images/dialog-close.png" alt="" />
|
|
|
|
|
收起
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<video
|
|
|
|
|
v-if="dialogSate"
|
|
|
|
|
id="videoBig"
|
|
|
|
|
autoplay="autoplay"
|
|
|
|
|
@timeupdate="handleTimeUpdate($event, '0521')"
|
|
|
|
|
/>
|
|
|
|
|
<div class="dialog-videoNodata" v-else>
|
|
|
|
|
<div class="video-title">
|
|
|
|
|
<div class="main-title">已播放结束</div>
|
|
|
|
|
<div class="title-btn">
|
|
|
|
|
<img src="../assets/images/sx.png" alt="" />
|
|
|
|
|
刷新
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { getCarPoint } from "@/api/yunkun/yunkun.js";
|
|
|
|
|
export default {
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
video_player: {},
|
|
|
|
|
video_uuid: {},
|
|
|
|
|
dialogVisible: false,
|
|
|
|
|
dialogIndex: 0,
|
|
|
|
|
dialogSate: false,
|
|
|
|
|
items: [],
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
created() {
|
|
|
|
|
this.getCarInfo();
|
|
|
|
|
},
|
|
|
|
|
beforeDestroy() {
|
|
|
|
|
this.items.forEach((item, index) => {
|
|
|
|
|
this.toclose(index);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
/**获取该车辆 */
|
|
|
|
|
async getCarInfo() {
|
|
|
|
|
this.items = [];
|
|
|
|
|
let result = await getCarPoint({ carIds: this.$route.query.carId });
|
|
|
|
|
if (result.list && result.list.length > 0) {
|
|
|
|
|
let videos = JSON.parse(result.list[0].videos);
|
|
|
|
|
videos.vs = videos.vs.split(",");
|
|
|
|
|
videos.vs.forEach((str) => {
|
|
|
|
|
let firstPart = str.split(":")[0];
|
|
|
|
|
let secondPart = str.split(":")[1];
|
|
|
|
|
this.items.push({
|
|
|
|
|
tdh: firstPart,
|
|
|
|
|
tdhName: secondPart,
|
|
|
|
|
allStr: str,
|
|
|
|
|
sate: 0, //0 未播放 1 播放中 2 播放完
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.items.forEach((item, index) => {
|
|
|
|
|
this.toplay(index, item.tdh);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
handleTimeUpdate(event, index) {
|
|
|
|
|
const currentTime = event.target.currentTime;
|
|
|
|
|
//自动播放分钟 == 300
|
|
|
|
|
if (currentTime >= 15) {
|
|
|
|
|
this.toclose(index);
|
|
|
|
|
if (index == "0521") {
|
|
|
|
|
this.dialogSate = false;
|
|
|
|
|
this.items[this.dialogIndex].sate = 2;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.items[index].sate = 2;
|
|
|
|
|
}
|
|
|
|
|
// console.log("Current time: ", event.target.currentTime, index);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleVideo(item, index) {
|
|
|
|
|
//清除当前列表中的该项
|
|
|
|
|
if (this.video_uuid[index]) {
|
|
|
|
|
this.toclose(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.items[index].sate = 1;
|
|
|
|
|
this.dialogIndex = index;
|
|
|
|
|
this.dialogSate = true;
|
|
|
|
|
this.dialogVisible = true;
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.toplay("0521", item.tdh, true);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
toplay(id, chn, type) {
|
|
|
|
|
var stream;
|
|
|
|
|
var http = "ws://192.168.0.91:9988";
|
|
|
|
|
var user = 99999; //用户
|
|
|
|
|
var pwd =
|
|
|
|
|
"2bc7676023122670f0df72eb2303f724040953cad991eb2e20537eb056ea7a5d"; //密码
|
|
|
|
|
var car = this.$route.query.carId; //车id
|
|
|
|
|
var chn = chn; //视频通道号
|
|
|
|
|
stream = 1; //码流1(流畅)或0(高清
|
|
|
|
|
this.video_uuid[id] = this.newUUID();
|
|
|
|
|
var url = [
|
|
|
|
|
http,
|
|
|
|
|
"real_play",
|
|
|
|
|
encodeURI(user) + "*" + pwd,
|
|
|
|
|
this.video_uuid[id],
|
|
|
|
|
encodeURI(car),
|
|
|
|
|
chn,
|
|
|
|
|
stream,
|
|
|
|
|
].join("/");
|
|
|
|
|
|
|
|
|
|
this.video_player[id] = flvjs.createPlayer(
|
|
|
|
|
{
|
|
|
|
|
type: "flv",
|
|
|
|
|
isLive: true,
|
|
|
|
|
hasAudio: false,
|
|
|
|
|
hasVideo: true,
|
|
|
|
|
cors: true,
|
|
|
|
|
url: url,
|
|
|
|
|
onmsg: function (msg) {
|
|
|
|
|
if (!msg || !msg.cmd) return;
|
|
|
|
|
if (msg.cmd == "real_play") {
|
|
|
|
|
// console.log(1);
|
|
|
|
|
// alert("<22>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>" + msg.ret); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ն˶Բ<CBB6><D4B2><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>Ӧ<EFBFBD><D3A6>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ն<EFBFBD><D5B6>ϴ<EFBFBD><CFB4><EFBFBD>Ƶ<EFBFBD><C6B5>
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (msg.cmd == "tmn_open") {
|
|
|
|
|
console.log(2);
|
|
|
|
|
// alert("<22>յ<EFBFBD><D5B5>ն<EFBFBD><D5B6><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msg.cmd == "play_flow") {
|
|
|
|
|
// console.log(3);
|
|
|
|
|
// console.log("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>ֽ<EFBFBD>)<29><>" + msg.flow); //ÿ<><C3BF>һ<EFBFBD><D2BB>
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (msg.cmd == "tmn_close") {
|
|
|
|
|
// console.log(4);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
console.log(JSON.stringfiy(msg));
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ enableStashBuffer: false, fixAudioTimestampGap: false }
|
|
|
|
|
);
|
|
|
|
|
let video;
|
|
|
|
|
if (type) {
|
|
|
|
|
video = document.getElementById("videoBig");
|
|
|
|
|
} else {
|
|
|
|
|
video = document.getElementById(`video${id}`);
|
|
|
|
|
}
|
|
|
|
|
console.log(video);
|
|
|
|
|
this.video_player[id].attachMediaElement(video);
|
|
|
|
|
this.video_player[id].on(flvjs.Events.MEDIA_INFO, function () {
|
|
|
|
|
//<2F>յ<EFBFBD><D5B5><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
|
|
|
|
// console.log("<22><><EFBFBD>ųɹ<C5B3>");
|
|
|
|
|
});
|
|
|
|
|
this.video_player[id].load();
|
|
|
|
|
this.video_player[id].play();
|
|
|
|
|
},
|
|
|
|
|
toclose(id) {
|
|
|
|
|
this.video_player[id].send(
|
|
|
|
|
{ cmd: "real_close", uuid: this.video_uuid[id] },
|
|
|
|
|
function (result) {
|
|
|
|
|
alert("<22><>Ƶ<EFBFBD>ر<EFBFBD><D8B1>ն<EFBFBD>Ӧ<EFBFBD><D3A6>:" + result.ret);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
this.video_player[id].destroy();
|
|
|
|
|
this.video_player[id] = null;
|
|
|
|
|
|
|
|
|
|
this.video_player[id] = undefined;
|
|
|
|
|
this.video_uuid[id] = undefined;
|
|
|
|
|
},
|
|
|
|
|
handleClose(id) {
|
|
|
|
|
this.items[this.dialogIndex].sate = 2;
|
|
|
|
|
this.toclose(id);
|
|
|
|
|
this.dialogVisible = false;
|
|
|
|
|
},
|
|
|
|
|
scroll(direction) {
|
|
|
|
|
const itemsWrapper = this.$refs.itemsWrapper;
|
|
|
|
|
if (itemsWrapper) {
|
|
|
|
|
const scrollAmount = itemsWrapper.clientWidth / 5; // 每次滚动一个格子距离,这里假设每个格子宽度相同
|
|
|
|
|
itemsWrapper.scrollLeft += direction * scrollAmount;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
newUUID() {
|
|
|
|
|
var S4 = function () {
|
|
|
|
|
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
|
|
|
|
};
|
|
|
|
|
return S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4();
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.container {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.video-title {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
.main-title,
|
|
|
|
|
.title-btn {
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
.title-btn {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
background: #0084ff;
|
|
|
|
|
border-radius: 15px;
|
|
|
|
|
padding: 3px 6px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
img {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
height: 20px;
|
|
|
|
|
width: 20px;
|
|
|
|
|
margin-right: 4px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.carousel {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
position: relative;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.scroll-btn {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 50%;
|
|
|
|
|
z-index: 50;
|
|
|
|
|
transform: translateY(-50%);
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
opacity: 0.5;
|
|
|
|
|
border: none;
|
|
|
|
|
outline: none;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
padding: 9px 4px;
|
|
|
|
|
}
|
|
|
|
|
.scroll-btn:hover {
|
|
|
|
|
opacity: 0.8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.left {
|
|
|
|
|
left: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.right {
|
|
|
|
|
right: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.items-wrapper {
|
|
|
|
|
width: 800px;
|
|
|
|
|
display: flex;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
scroll-behavior: smooth; /* 可以平滑滚动 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.item {
|
|
|
|
|
position: relative;
|
|
|
|
|
flex: 0 0 calc(100% / 6); /* 每行显示5个格子 */
|
|
|
|
|
height: 140px;
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
.video-src {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
object-fit: fill;
|
|
|
|
|
background-color: #000;
|
|
|
|
|
background-size: 0;
|
|
|
|
|
}
|
|
|
|
|
.video-bg {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
background: url("../assets/images/cell-video.png");
|
|
|
|
|
background-size: 100% 100%;
|
|
|
|
|
z-index: 10;
|
|
|
|
|
font-weight: 400;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
text-align: center;
|
|
|
|
|
line-height: 108px;
|
|
|
|
|
}
|
|
|
|
|
.video-data {
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
height: 32px;
|
|
|
|
|
width: 100%;
|
|
|
|
|
z-index: 20;
|
|
|
|
|
background: rgba(0, 52, 101, 0.9);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
padding: 0 10px;
|
|
|
|
|
.video-name {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
.video-icon {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
height: 14px;
|
|
|
|
|
width: 14px;
|
|
|
|
|
transition: transform 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
.video-icon:hover {
|
|
|
|
|
transform: scale(1.2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* CSS */
|
|
|
|
|
.items-wrapper {
|
|
|
|
|
// overflow-y: scroll; /* 强制显示垂直滚动条 */
|
|
|
|
|
scrollbar-width: thin; /* 滚动条宽度,可以是 auto, thin 或 none */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Webkit浏览器特有样式 */
|
|
|
|
|
|
|
|
|
|
.video-dialog-top {
|
|
|
|
|
height: 40px;
|
|
|
|
|
background: rgba(0, 52, 101, 0.9);
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
padding: 0 10px;
|
|
|
|
|
.video-name-data {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
.dialog-close {
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #fff;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
img {
|
|
|
|
|
margin-right: 6px;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
height: 14px;
|
|
|
|
|
width: 14px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#videoBig {
|
|
|
|
|
height: calc(100% - 40px);
|
|
|
|
|
width: 100%;
|
|
|
|
|
object-fit: fill;
|
|
|
|
|
background-color: #000;
|
|
|
|
|
background-size: 0;
|
|
|
|
|
}
|
|
|
|
|
.dialog-videoNodata {
|
|
|
|
|
height: calc(100% - 40px);
|
|
|
|
|
width: 100%;
|
|
|
|
|
object-fit: fill;
|
|
|
|
|
background: url("../assets/images/zw.png");
|
|
|
|
|
background-size: 100% 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
.title-btn {
|
|
|
|
|
margin-left: 13px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</style>
|