You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

438 lines
11 KiB

<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;
8 months ago
opacity: 0.5;
border: none;
outline: none;
cursor: pointer;
padding: 9px 4px;
}
.scroll-btn:hover {
8 months ago
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>