1130 lines
32 KiB
Vue
1130 lines
32 KiB
Vue
<template>
|
||
<div id="player-main">
|
||
<div id="player"></div>
|
||
<!-- 为每个窗口添加控制按钮容器 -->
|
||
<div
|
||
class="video-controls"
|
||
v-for="i in maxWindows"
|
||
:key="i"
|
||
:id="'controls-' + i"
|
||
:style="{ display: 'none' }"
|
||
>
|
||
<div class="controls-top">
|
||
<div></div>
|
||
<div @click="stopPlay(i)" class="top-close">
|
||
关闭
|
||
<i class="el-icon-close"></i>
|
||
</div>
|
||
</div>
|
||
<div class="controls-bottom">
|
||
<div></div>
|
||
<div>
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${recordingBegin ? '结束' : '开始'}录制`"
|
||
placement="top"
|
||
>
|
||
<div class="bgImage transcribe" @click="isTranscribe(i)"></div>
|
||
</el-tooltip>
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`抓图`"
|
||
placement="top"
|
||
>
|
||
<div class="bgImage screenshot" @click="capture('JPEG', i)"></div>
|
||
</el-tooltip>
|
||
|
||
<!-- <div>流畅</div> -->
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${muted ? '关闭' : '开启'}音量`"
|
||
placement="top"
|
||
>
|
||
<div
|
||
@click="handleVolume(i)"
|
||
:class="muted ? 'openVolume' : 'disableVolume'"
|
||
class="bgImage"
|
||
></div>
|
||
</el-tooltip>
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${isFullScreen ? '退出' : '进入'}全屏模式`"
|
||
placement="top"
|
||
>
|
||
<div
|
||
class="bgImage"
|
||
:class="isFullScreen ? 'exitFullScreen' : 'fullScreen'"
|
||
@click="singleFullScreen(i)"
|
||
></div>
|
||
</el-tooltip>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- <div class="player-tool">
|
||
<el-tooltip class="item" effect="dark" :content="`默认`" placement="top">
|
||
<div class="bgImage splitscreen1" @click="onTwoSubmit(1)"></div>
|
||
</el-tooltip>
|
||
<el-tooltip class="item" effect="dark" :content="`2x2`" placement="top">
|
||
<div class="bgImage splitscreen2" @click="onTwoSubmit(2)"></div>
|
||
</el-tooltip>
|
||
<el-tooltip class="item" effect="dark" :content="`4x4`" placement="top">
|
||
<div class="bgImage splitscreen3" @click="onTwoSubmit(4)"></div>
|
||
</el-tooltip>
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`停止所有播放`"
|
||
placement="top"
|
||
>
|
||
<div class="bgImage stopAll" @click="stopAllPlay"></div>
|
||
</el-tooltip>
|
||
<el-tooltip
|
||
class="item"
|
||
effect="dark"
|
||
:content="`${isFullScreen ? '退出' : '进入'}全屏模式`"
|
||
placement="top"
|
||
>
|
||
<div
|
||
class="bgImage"
|
||
:class="isFullScreen ? 'exitFullScreen' : 'fullScreen'"
|
||
@click="wholeFullScreen(i)"
|
||
></div>
|
||
</el-tooltip>
|
||
</div> -->
|
||
<div class="ant-radio-group3">
|
||
<!-- 时间筛选 -->
|
||
<div class="Progress_timeline">
|
||
<div class="Progress_timelineLeft" @click="onClickOffsetX('left')">
|
||
<i class="el-icon-arrow-left"></i>
|
||
</div>
|
||
<div class="Progress_timelineCenterWrap">
|
||
<div class="Progress_placeholder"></div>
|
||
<div class="Progress_timelineCenter1">
|
||
<div
|
||
class="Progress_timelineCenter"
|
||
@mousemove="mousemoveTime"
|
||
@click="seekTo"
|
||
>
|
||
<div class="Progress_cover"></div>
|
||
<div
|
||
class="Progress_time"
|
||
:style="`transform: translateX(${videoInfo.offsetTranslateX}%);`"
|
||
>
|
||
<div
|
||
class="Progress_timeItem"
|
||
v-for="(item, index) in videoInfo.timeList"
|
||
:key="index"
|
||
>
|
||
{{ item }}
|
||
</div>
|
||
<!-- <div class="Progress_timeItem">1:00</div>
|
||
<div class="Progress_timeItem">2:00</div> -->
|
||
</div>
|
||
<div class="Progress_line"></div>
|
||
<div
|
||
class="Progress_area"
|
||
:style="`transform: translateX(${videoInfo.offsetTranslateX}%);`"
|
||
>
|
||
<div
|
||
class="Progress_areaItem"
|
||
v-for="(item, index) in videoInfo.timeList"
|
||
:key="index"
|
||
>
|
||
{{ item }}
|
||
</div>
|
||
<!-- <div class="Progress_areaItem">1:00</div>
|
||
<div class="Progress_areaItem">2:00</div> -->
|
||
</div>
|
||
<div
|
||
class="Progress_arrowTime"
|
||
:style="`left:${videoInfo.offsetX}%; transform: translateX(${videoInfo.translateX}%);`"
|
||
>
|
||
{{ videoInfo.minuteTime }}
|
||
</div>
|
||
<div
|
||
class="Progress_arrow"
|
||
:style="`left:${videoInfo.offsetX}%`"
|
||
></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="Progress_timelineRight" @click="onClickOffsetX('right')">
|
||
<i class="el-icon-arrow-right"></i>
|
||
</div>
|
||
</div>
|
||
<el-date-picker
|
||
class="date-picker"
|
||
:clearable="false"
|
||
v-model="videoInfo.dateTime"
|
||
type="date"
|
||
value-format="YYYY-MM-DD"
|
||
placeholder="请选择"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
// 请求工具
|
||
// import http from "@/http/http2.js";
|
||
import { callPostPlaybackURLsApi } from "@/assets/js/api/equipmentCenter/cameraList";
|
||
import moment from "moment";
|
||
import dayjs from "dayjs";
|
||
import { Message } from "element-ui";
|
||
export default {
|
||
name: "hik",
|
||
props: [
|
||
"devList",
|
||
"isReplayNum",
|
||
"startTime",
|
||
"endTime",
|
||
"showVideo",
|
||
"locationValue",
|
||
],
|
||
data() {
|
||
return {
|
||
// 监控点编码
|
||
code: "",
|
||
// 播放器对象
|
||
player: null,
|
||
devH5List: [],
|
||
numCount: 1,
|
||
iWndIndex: 0,
|
||
maxWindows: 16, // 最大窗口数
|
||
recordingBegin: false,
|
||
muted: true,
|
||
playback: {
|
||
startTime: "2023-08-16T00:00:00",
|
||
endTime: "2023-08-16T23:00:00",
|
||
valueFormat: moment.HTML5_FMT.DATETIME_LOCAL_SECONDS,
|
||
seekStart: "2023-08-16T10:00:00",
|
||
rate: "",
|
||
},
|
||
isFullScreen: false,
|
||
isFullScreenAll: false,
|
||
videoInfo: {
|
||
// 时间筛选
|
||
dateTime: dayjs(new Date()).format("YYYY-MM-DD"),
|
||
offsetX: 0,
|
||
translateX: 0,
|
||
offsetTranslateX: 0,
|
||
offsetPage: 0,
|
||
timeList: [],
|
||
minuteTime: "0:00",
|
||
},
|
||
};
|
||
},
|
||
watch: {
|
||
//监听value的变化,进行相应的操作即可
|
||
devList: function (a, b) {
|
||
console.log("isc_plugin.vue获取到设备列表", a, b, this.devH5List);
|
||
//a是value的新值,b是旧值
|
||
a.forEach((item, index) => {
|
||
if (this.numCount == 1) {
|
||
this.play(item, this.iWndIndex);
|
||
} else if (a.length == 1) {
|
||
this.play(item, this.iWndIndex);
|
||
this.devH5List.push(item);
|
||
} else {
|
||
this.play(item, index);
|
||
}
|
||
});
|
||
if(a.length > 1) {
|
||
this.devH5List = a;
|
||
}
|
||
},
|
||
isReplayNum: function (newVal, oldVal) {
|
||
console.log("新的值", newVal);
|
||
if (newVal > 0) {
|
||
this.play(this.devH5List[this.iWndIndex], this.iWndIndex);
|
||
} else {
|
||
this.stopAllPlay();
|
||
}
|
||
},
|
||
},
|
||
mounted() {
|
||
this.devH5List = this.devList;
|
||
this.videoInfo.dateTime = dayjs(this.startTime).format("YYYY-MM-DD");
|
||
// 获取时间(24)
|
||
for (let index = 0; index < 24; index++) {
|
||
this.videoInfo.timeList.push(`${index}:00`);
|
||
}
|
||
this.videoInfo.timeList.push(`00:00`);
|
||
console.log("我进来了", this.devList);
|
||
// 页面加载初始化`
|
||
this.initPlayer();
|
||
},
|
||
methods: {
|
||
// 左右偏移
|
||
onClickOffsetX(position) {
|
||
// 内容的宽度
|
||
const timeWidth = document.querySelector(".Progress_time").offsetWidth;
|
||
// 内容的宽度
|
||
const width = document.querySelector(".Progress_cover").offsetWidth;
|
||
// console.log(timeWidth, width, (width / timeWidth) * 100)
|
||
|
||
if (position == "left") {
|
||
if (this.videoInfo.offsetPage == 0)
|
||
return this.$message.warning("已经是最左侧了");
|
||
this.videoInfo.offsetPage -= 1;
|
||
} else if (position == "right") {
|
||
if (this.videoInfo.offsetPage == 1)
|
||
return this.$message.warning("已经是最右侧了");
|
||
this.videoInfo.offsetPage += 1;
|
||
// if (offsetX == 2) offsetX = -80
|
||
}
|
||
const offsetX = -(
|
||
((width - 18) / timeWidth) *
|
||
100 *
|
||
this.videoInfo.offsetPage
|
||
);
|
||
// console.log(this.videoInfo.offsetPage, offsetX - 10)
|
||
this.videoInfo.offsetTranslateX = offsetX;
|
||
},
|
||
onDateChange() {
|
||
console.log(this.videoInfo.dateTime, this.videoInfo.minuteTime);
|
||
},
|
||
// 移入
|
||
mousemoveTime(event) {
|
||
// console.log("鼠标移入", event.offsetX, document.querySelector(".Progress_cover").offsetWidth)
|
||
// 内容的宽度
|
||
const width = document.querySelector(".Progress_cover").offsetWidth;
|
||
// 提示的宽度
|
||
const arrowWidth = document.querySelector(
|
||
".Progress_arrowTime"
|
||
).offsetWidth;
|
||
// 占位符的宽度
|
||
const placeholderWidth = document.querySelector(
|
||
".Progress_placeholder"
|
||
).offsetWidth;
|
||
// 当前鼠标移入的位置
|
||
this.videoInfo.offsetX = (event.offsetX / width) * 100;
|
||
// console.log(arrowWidth, width - event.offsetX)
|
||
console.log(arrowWidth - (width - event.offsetX) >= arrowWidth / 2);
|
||
// 靠右
|
||
if (arrowWidth - (width - event.offsetX) >= arrowWidth / 2) {
|
||
this.videoInfo.translateX = -(
|
||
50 -
|
||
((width - event.offsetX) / arrowWidth) * 100
|
||
);
|
||
// console.log(this.videoInfo.translateX)
|
||
} else if (event.offsetX <= arrowWidth / 2 - placeholderWidth) {
|
||
this.videoInfo.translateX = 50 - (event.offsetX / arrowWidth) * 100;
|
||
// console.log(this.videoInfo.translateX, event.offsetX, arrowWidth, placeholderWidth)
|
||
} else {
|
||
this.videoInfo.translateX = 0;
|
||
}
|
||
// console.log(this.videoInfo.offsetX)
|
||
// 获取时间的宽度
|
||
const timeWidth =
|
||
document.querySelector(".Progress_timeItem").offsetWidth;
|
||
const timeIndex = Math.floor(event.offsetX / timeWidth);
|
||
// 当前分钟的位置
|
||
const minuteIndex = Math.ceil(
|
||
(event.offsetX / timeWidth - timeIndex) * 100
|
||
);
|
||
// 当前分钟
|
||
const minute = Math.ceil((minuteIndex / 100) * 60);
|
||
const offsetIndex =
|
||
this.videoInfo.offsetPage == 0
|
||
? timeIndex
|
||
: 14 * this.videoInfo.offsetPage + timeIndex;
|
||
console.log(offsetIndex, 8, this.videoInfo.offsetPage, timeIndex);
|
||
// 截取当前字符串的时间
|
||
const hour =
|
||
this.videoInfo.timeList[offsetIndex] &&
|
||
this.videoInfo.timeList[offsetIndex].substring(
|
||
0,
|
||
this.videoInfo.timeList[offsetIndex].indexOf(":")
|
||
);
|
||
if (!hour || hour == "00") return;
|
||
if (hour == undefined) return;
|
||
this.videoInfo.minuteTime = `${this.videoInfo.dateTime} ${
|
||
hour < 10 ? "0" + hour : hour
|
||
}:${minute < 10 ? "0" + minute : minute}`;
|
||
// console.log(111111111, width, offsetIndex,)
|
||
|
||
// console.log(Math.floor(event.offsetX / timeWidth), this.videoInfo.timeList[offsetIndex], this.videoInfo.offsetPage)
|
||
},
|
||
// 定位
|
||
seekTo() {
|
||
// 确保时间格式一致,可以统一使用dayjs对象
|
||
const currentTime = dayjs(this.videoInfo.minuteTime);
|
||
const start = dayjs(this.startTime);
|
||
const end = dayjs(this.endTime);
|
||
console.log(this.videoInfo.minuteTime, this.startTime, this.endTime);
|
||
if (currentTime.isBefore(start, "second")) {
|
||
this.$message.warning("不能定位到开始时间之前");
|
||
return;
|
||
}
|
||
if (currentTime.isAfter(end, "second")) {
|
||
this.$message.warning("不能定位到结束时间之后");
|
||
return;
|
||
}
|
||
|
||
let seekStart =
|
||
dayjs(this.videoInfo.minuteTime).format(
|
||
moment.HTML5_FMT.DATETIME_LOCAL_SECONDS
|
||
) + ".000+08:00";
|
||
let endTime =
|
||
dayjs(this.endTime).format(moment.HTML5_FMT.DATETIME_LOCAL_SECONDS) +
|
||
".000+08:00";
|
||
this.player
|
||
.JS_Seek(this.player.currentWindowIndex, seekStart, endTime)
|
||
.then(
|
||
() => {
|
||
console.log("seekTo success");
|
||
},
|
||
(e) => {
|
||
this.$message.error(e);
|
||
}
|
||
);
|
||
},
|
||
// 关闭所有视频
|
||
stopAllPlay() {
|
||
this.player.JS_StopRealPlayAll().then(
|
||
() => {
|
||
this.playback.rate = 0;
|
||
console.log("stopAllPlay success");
|
||
this.devH5List.forEach((item, index) => {
|
||
const wnd = document.querySelector(
|
||
`#player #player-container-${index}`
|
||
);
|
||
if (wnd) {
|
||
const controls = document.getElementById(`controls-${index + 1}`);
|
||
if (controls) {
|
||
controls.classList.remove("video-controls_flex");
|
||
}
|
||
}
|
||
});
|
||
this.devH5List = [];
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
// 关闭单个
|
||
stopPlay(currentWindowIndex, type) {
|
||
this.player.JS_Stop(currentWindowIndex - 1).then(
|
||
() => {
|
||
this.playback.rate = 0;
|
||
console.log("stop realplay success");
|
||
const wnd = document.querySelector(
|
||
`#player #player-container-${currentWindowIndex - 1}`
|
||
);
|
||
if (wnd) {
|
||
const controls = document.getElementById(
|
||
`controls-${currentWindowIndex}`
|
||
);
|
||
if (controls) {
|
||
controls.classList.remove("video-controls_flex");
|
||
}
|
||
if(type == "delete") return;
|
||
this.devH5List.splice(currentWindowIndex - 1, 1);
|
||
}
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
handleVolume(currentWindowIndex) {
|
||
if (this.muted) {
|
||
this.openSound(currentWindowIndex);
|
||
} else {
|
||
this.closeSound(currentWindowIndex);
|
||
}
|
||
},
|
||
/* 声音、抓图、录像 */
|
||
openSound(currentWindowIndex) {
|
||
this.player.JS_OpenSound(currentWindowIndex - 1).then(
|
||
() => {
|
||
console.log("openSound success");
|
||
this.muted = false;
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
closeSound(currentWindowIndex) {
|
||
this.player.JS_CloseSound(currentWindowIndex - 1).then(
|
||
() => {
|
||
console.log("closeSound success");
|
||
this.muted = true;
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
// 单个窗口全屏
|
||
singleFullScreen(currentWindowIndex) {
|
||
if (this.isFullScreenAll) {
|
||
this.wholeFullScreen();
|
||
return;
|
||
}
|
||
this.player.JS_FullScreenSingle(currentWindowIndex - 1).then(
|
||
() => {
|
||
console.log(`singleFullScreen success`);
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
// 整体窗口全屏
|
||
wholeFullScreen() {
|
||
this.player.JS_FullScreenDisplay(this.isFullScreenAll).then(
|
||
() => {
|
||
console.log(`wholeFullScreen success`);
|
||
this.isFullScreenAll = !this.isFullScreenAll;
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
isTranscribe(currentWindowIndex) {
|
||
if (this.recordingBegin) {
|
||
this.recordStop(currentWindowIndex);
|
||
} else {
|
||
this.recordStart("MP4", currentWindowIndex);
|
||
}
|
||
},
|
||
// 开始录制
|
||
recordStart(type, currentWindowIndex) {
|
||
const codeMap = { MP4: 5, PS: 2 };
|
||
//let options = {irecordType: 2, cbStreamCB: streamcb}
|
||
let player = this.player,
|
||
index = currentWindowIndex - 1,
|
||
fileName = `${moment().format("YYYYMMDDHHmmss")}.mp4`,
|
||
typeCode = codeMap[type];
|
||
|
||
player
|
||
.JS_StartSaveEx(index, fileName, typeCode, {
|
||
irecordType: 1,
|
||
cbStreamCB: this.streamcb,
|
||
})
|
||
.then(
|
||
() => {
|
||
this.$message.success("开始录制");
|
||
this.recordingBegin = true;
|
||
console.log("record start ...");
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
// 结束录制
|
||
recordStop(currentWindowIndex) {
|
||
let player = this.player,
|
||
index = currentWindowIndex - 1;
|
||
|
||
player.JS_StopSave(index).then(
|
||
(res) => {
|
||
console.log("record stoped, saving ...", res);
|
||
this.recordingBegin = false;
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
// 抓图
|
||
capture(imageType, currentWindowIndex) {
|
||
let player = this.player,
|
||
index = currentWindowIndex - 1;
|
||
|
||
player.JS_CapturePicture(index, "img", imageType).then(
|
||
() => {
|
||
console.log("capture success", imageType);
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
/**
|
||
* 初始化播放器
|
||
*/
|
||
initPlayer() {
|
||
const _this = this;
|
||
this.player = new JSPlugin({
|
||
// 需要英文字母开头 必填
|
||
szId: "player",
|
||
// 必填,引用H5player.min.js的js相对路径
|
||
szBasePath: "/public/bin",
|
||
|
||
iMaxSplit: 4,
|
||
openDebug: true,
|
||
mseWorkerEnable: false, //是否开启多线程解码,分辨率大于1080P建议开启,否则可能卡顿
|
||
bSupporDoubleClickFull: true, //是否支持双击全屏,true-双击是全屏;false-双击无响应
|
||
|
||
// 分屏播放,默认最大分屏4*4
|
||
// iMaxSplit: 16,
|
||
iCurrentSplit: 1,
|
||
|
||
// 样式
|
||
oStyle: {
|
||
border: "#343434",
|
||
borderSelect: "#FFCC00",
|
||
background: "#000",
|
||
},
|
||
});
|
||
// 事件回调绑定
|
||
this.player.JS_SetWindowControlCallback({
|
||
windowEventSelect: function (iWndIndex) {
|
||
//插件选中窗口回调
|
||
console.log("windowSelect callback: ", iWndIndex);
|
||
_this.iWndIndex = iWndIndex;
|
||
},
|
||
pluginErrorHandler: function (iWndIndex, iErrorCode, oError) {
|
||
//插件错误回调
|
||
console.log("pluginError callback: ", iWndIndex, iErrorCode, oError);
|
||
},
|
||
windowEventOver: function (iWndIndex) {
|
||
//鼠标移过回调
|
||
console.log(iWndIndex);
|
||
// 使用选中事件来定位控制按钮
|
||
const wnd = document.querySelector(
|
||
`#player #player-container-${iWndIndex}`
|
||
);
|
||
console.log(1111222, wnd);
|
||
if (wnd) {
|
||
const controls = document.getElementById(
|
||
`controls-${iWndIndex + 1}`
|
||
);
|
||
console.log(controls, wnd);
|
||
if (controls && !wnd.contains(controls)) {
|
||
// 确保控制按钮只添加一次
|
||
if (!wnd.querySelector(".video-controls")) {
|
||
wnd.appendChild(controls);
|
||
// controls.style.display = "flex";
|
||
}
|
||
}
|
||
if (controls) {
|
||
if (iWndIndex > _this.devH5List.length - 1) return;
|
||
controls.classList.add("video-controls_flex");
|
||
}
|
||
}
|
||
},
|
||
windowEventOut: function (iWndIndex) {
|
||
//鼠标移出回调
|
||
console.log(iWndIndex);
|
||
const wnd = document.querySelector(
|
||
`#player #player-container-${iWndIndex}`
|
||
);
|
||
if (wnd) {
|
||
const controls = document.getElementById(
|
||
`controls-${iWndIndex + 1}`
|
||
);
|
||
if (controls) {
|
||
controls.classList.remove("video-controls_flex");
|
||
}
|
||
}
|
||
},
|
||
windowEventUp: function (iWndIndex) {
|
||
//鼠标mouseup事件回调
|
||
//console.log(iWndIndex);
|
||
},
|
||
windowFullCcreenChange: function (bFull) {
|
||
//全屏切换回调
|
||
console.log("fullScreen callback: ", bFull);
|
||
_this.isFullScreen = bFull;
|
||
_this.isFullScreenAll = false;
|
||
},
|
||
firstFrameDisplay: function (iWndIndex, iWidth, iHeight) {
|
||
//首帧显示回调
|
||
console.log(
|
||
"firstFrame loaded callback: ",
|
||
iWndIndex,
|
||
iWidth,
|
||
iHeight
|
||
);
|
||
},
|
||
performanceLack: function (iWndIndex) {
|
||
//性能不足回调
|
||
console.log("performanceLack callback: ", iWndIndex);
|
||
},
|
||
StreamEnd: function (iWndIndex) {
|
||
//性能不足回调
|
||
console.log("recv StreamEnd: ", iWndIndex);
|
||
},
|
||
StreamHeadChanged: function (iWndIndex) {
|
||
console.log("recv StreamHeadChanged: ", iWndIndex);
|
||
},
|
||
ThumbnailsEvent: (iWndIndex, eventType, eventCode) => {
|
||
console.log(
|
||
"recv ThumbnailsEvent: " +
|
||
iWndIndex +
|
||
", eventType:" +
|
||
eventType +
|
||
", eventCode:" +
|
||
eventCode
|
||
);
|
||
},
|
||
InterruptStream: (iWndIndex, iTime) => {
|
||
console.log(
|
||
"recv InterruptStream: " + iWndIndex + ", iTime:" + iTime
|
||
);
|
||
},
|
||
ElementChanged: (iWndIndex, szElementType) => {
|
||
//回调采用的是video还是canvas
|
||
console.log(
|
||
"recv ElementChanged: " +
|
||
iWndIndex +
|
||
", szElementType:" +
|
||
szElementType
|
||
);
|
||
},
|
||
});
|
||
this.$nextTick(() => {
|
||
this.play(this.devH5List[0], this.iWndIndex);
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 获取取流连接
|
||
* @returns {*}
|
||
*/
|
||
getPreviewUrl(row) {
|
||
let tempCode = row.serialNumber;
|
||
const param = {
|
||
// cameraIndexCode: tempCode,
|
||
// streamType: row.defaultStreamType == 2 ? 0 : row.defaultStreamType,
|
||
// transmode: 1,
|
||
// itemId: row.itemId,
|
||
serialNumber: row.serialNumber,
|
||
projectSn: row.projectSn,
|
||
protocol: "ws",
|
||
|
||
beginTime: this.startTime,
|
||
endTime: this.endTime,
|
||
recordLocation: this.locationValue,
|
||
};
|
||
// 这里
|
||
return callPostPlaybackURLsApi(param);
|
||
},
|
||
|
||
/**
|
||
* 播放
|
||
*/
|
||
play(row, index) {
|
||
const _this = this;
|
||
this.getPreviewUrl({
|
||
...row,
|
||
}).then((res) => {
|
||
if (res.code !== 200) {
|
||
_this.$message.warning("获取视频流失败!");
|
||
return;
|
||
}
|
||
// 视频添加加载中图片
|
||
const id = "player-container-" + index;
|
||
var d1 = document.getElementById(id); //获取div元素
|
||
d1.childNodes.forEach((item) => {
|
||
if (item.nodeName == "" || item.nodeName == "IMG") {
|
||
d1.removeChild(item);
|
||
}
|
||
});
|
||
var im = document.createElement("img"); //创建图片
|
||
im.src = require("@/assets/images/iscImage/loading.gif");
|
||
//图片设置成和div一样大小
|
||
const divHeightNum = d1.style.height.slice(
|
||
0,
|
||
d1.style.height.length - 2
|
||
);
|
||
// const imgHeightNum = divHeightNum * 0.2
|
||
const imgHeightNum = 256;
|
||
im.style.width = imgHeightNum + "px";
|
||
im.style.height = imgHeightNum + "px";
|
||
im.style.position = "absolute";
|
||
im.style.top = "50%";
|
||
im.style.left = "50%";
|
||
const positionNum = imgHeightNum / 2 - imgHeightNum;
|
||
im.style.marginLeft = positionNum + "px";
|
||
im.style.marginTop = positionNum + "px";
|
||
d1.appendChild(im); //图片挂载到div上
|
||
let preUrl = res.result.url;
|
||
console.log(preUrl);
|
||
const param = {
|
||
playURL: preUrl,
|
||
// 1:高级模式 0:普通模式,高级模式支持所有
|
||
mode: 1,
|
||
keepDecoder: 0,
|
||
};
|
||
// 索引默认0
|
||
if (!index) {
|
||
index = 0;
|
||
}
|
||
let startTime =
|
||
dayjs(this.startTime).format(
|
||
moment.HTML5_FMT.DATETIME_LOCAL_SECONDS
|
||
) + ".000+08:00";
|
||
let endTime =
|
||
dayjs(this.endTime).format(moment.HTML5_FMT.DATETIME_LOCAL_SECONDS) +
|
||
".000+08:00";
|
||
console.log(8887777, startTime, endTime);
|
||
_this.player.JS_Play(preUrl, param, index, startTime, endTime).then(
|
||
() => {
|
||
// 播放成功回调
|
||
console.log("播放成功");
|
||
_this.$message.success("播放成功!");
|
||
},
|
||
(err) => {
|
||
const obj = {
|
||
"0x019308cb": "取流失败",
|
||
"0x12f900009": "取流超时,请检查网络状态",
|
||
};
|
||
console.log("播放失败");
|
||
im.src = require("@/assets/images/iscImage/text-to-image.png");
|
||
const imgHeightNum = 20;
|
||
const imgWidthNum = 150;
|
||
im.style.width = imgWidthNum + "px";
|
||
im.style.height = imgHeightNum + "px";
|
||
const positionNum = imgHeightNum / 2 - imgHeightNum;
|
||
const positionWidthNum = imgWidthNum / 2 - imgWidthNum;
|
||
im.style.marginLeft = positionWidthNum + "px";
|
||
im.style.marginTop = positionNum + "px";
|
||
_this.$message.warning(obj[err] || "播放失败");
|
||
}
|
||
);
|
||
});
|
||
},
|
||
/**
|
||
* 分屏,这里我太懒了,就循环了一个视频流
|
||
*/
|
||
onTwoSubmit(num) {
|
||
const _this = this;
|
||
// 这里的分屏,是以列来算的,如果这里参数2,那么就是横竖两列,就是4格
|
||
this.numCount = num;
|
||
this.player.JS_ArrangeWindow(num).then(
|
||
() => {
|
||
// 循环取流
|
||
// for (let i = 0; i < num * num; i++) {
|
||
// _this.play(i);
|
||
// }
|
||
},
|
||
(e) => {
|
||
console.error(e);
|
||
}
|
||
);
|
||
},
|
||
},
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.ant-radio-group3 {
|
||
width: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
|
||
.Progress_timeline {
|
||
background: #19233a;
|
||
border: 1px solid #2b344c;
|
||
border-radius: 4px;
|
||
display: flex;
|
||
height: 44px;
|
||
// width: 431px;
|
||
width: 100%;
|
||
// margin-right: 10px;
|
||
|
||
.Progress_timelineRight,
|
||
.Progress_timelineLeft {
|
||
align-items: center;
|
||
background: #202a43;
|
||
border-left: 1px solid #2b344c;
|
||
border-radius: 0 4px 4px 0;
|
||
color: #7a8bb5;
|
||
display: flex;
|
||
justify-content: center;
|
||
width: 50px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.Progress_timelineCenterWrap {
|
||
margin-top: -50px;
|
||
overflow: hidden;
|
||
padding-top: 50px;
|
||
// width: 391px;
|
||
width: calc(92% - 60px);
|
||
display: flex;
|
||
|
||
> div:first-child {
|
||
width: 20px;
|
||
}
|
||
|
||
.Progress_timelineCenter1 {
|
||
position: relative;
|
||
// width: 371px;
|
||
width: 100%;
|
||
// padding-left: 20px;
|
||
|
||
.Progress_timelineCenter {
|
||
// width: 960px;
|
||
width: 1500px;
|
||
|
||
&:hover .Progress_arrowTime,
|
||
&:hover .Progress_arrow {
|
||
display: block;
|
||
}
|
||
|
||
.Progress_cover {
|
||
width: 100%;
|
||
height: 100%;
|
||
cursor: pointer;
|
||
left: 0;
|
||
position: absolute;
|
||
top: 0;
|
||
z-index: 1;
|
||
}
|
||
|
||
.Progress_time {
|
||
display: flex;
|
||
|
||
.Progress_timeItem {
|
||
min-width: 100px;
|
||
color: #99a0b4;
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
left: 0px;
|
||
line-height: 14px;
|
||
padding: 3px 0;
|
||
position: relative;
|
||
text-align: left;
|
||
}
|
||
}
|
||
|
||
.Progress_line {
|
||
bottom: 0;
|
||
display: flex;
|
||
height: 24px;
|
||
position: absolute;
|
||
// left: 20px;
|
||
}
|
||
|
||
.Progress_area {
|
||
align-items: center;
|
||
border-top: 1px solid #2b344c;
|
||
display: flex;
|
||
height: 24px;
|
||
opacity: 0.5;
|
||
// margin-left: 20px;
|
||
|
||
.Progress_areaItem {
|
||
min-width: 100px;
|
||
border-left: 1px solid #fff;
|
||
height: 10px;
|
||
opacity: 0.1;
|
||
}
|
||
}
|
||
|
||
.Progress_arrowTime {
|
||
background: linear-gradient(180deg, #89a3f8, #516aee);
|
||
border-radius: 10px;
|
||
color: #fff;
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
height: 19px;
|
||
line-height: 19px;
|
||
margin-left: -60px;
|
||
position: absolute;
|
||
text-align: center;
|
||
// top: -45px;
|
||
top: -20px;
|
||
width: 120px;
|
||
// display: none;
|
||
}
|
||
|
||
.Progress_arrow {
|
||
background: linear-gradient(180deg, #89a3f8, #516aee);
|
||
box-shadow: 0 0 6px 0 #5363f2;
|
||
height: 44px;
|
||
position: absolute;
|
||
top: 0;
|
||
width: 2px;
|
||
// display: none;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
:deep() {
|
||
.date-picker {
|
||
width: initial;
|
||
cursor: pointer;
|
||
position: absolute;
|
||
right: 40px;
|
||
width: 20px;
|
||
height: 20px;
|
||
.el-input__icon {
|
||
line-height: 0;
|
||
}
|
||
}
|
||
|
||
.date-picker .el-input__wrapper {
|
||
padding-right: 0;
|
||
padding-left: 8px;
|
||
cursor: pointer;
|
||
background-color: #19233a;
|
||
border: 1px solid #2b344c;
|
||
box-shadow: none;
|
||
}
|
||
|
||
.date-picker .el-input__inner {
|
||
display: none;
|
||
}
|
||
}
|
||
}
|
||
.bgImage {
|
||
width: 18px;
|
||
height: 18px;
|
||
background-repeat: no-repeat;
|
||
background-size: 100% 100%;
|
||
cursor: pointer;
|
||
}
|
||
.transcribe {
|
||
width: 20px;
|
||
height: 20px;
|
||
background-image: url("~@/assets/images/iscImage/transcribe.png");
|
||
}
|
||
.screenshot {
|
||
background-image: url("~@/assets/images/iscImage/screenshot.png");
|
||
}
|
||
.disableVolume {
|
||
background-image: url("~@/assets/images/iscImage/disableVolume.png");
|
||
}
|
||
.fullScreen {
|
||
background-image: url("~@/assets/images/iscImage/fullScreen.png");
|
||
}
|
||
.openVolume {
|
||
background-image: url("~@/assets/images/iscImage/openVolume.png");
|
||
}
|
||
.exitFullScreen {
|
||
background-image: url("~@/assets/images/iscImage/exitFullScreen.png");
|
||
}
|
||
.splitscreen1 {
|
||
background-image: url("~@/assets/images/iscImage/splitscreen1.png");
|
||
}
|
||
.splitscreen2 {
|
||
background-image: url("~@/assets/images/iscImage/splitscreen2.png");
|
||
}
|
||
.splitscreen3 {
|
||
background-image: url("~@/assets/images/iscImage/splitscreen3.png");
|
||
}
|
||
.stopAll {
|
||
background-image: url("~@/assets/images/iscImage/stopAll.png");
|
||
}
|
||
.video-controls_flex {
|
||
display: flex !important;
|
||
}
|
||
/* 添加控制按钮样式 */
|
||
.video-controls {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: absolute;
|
||
z-index: 100;
|
||
// background: rgba(0, 0, 0, 0.7);
|
||
display: none;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
.controls-bottom {
|
||
height: 35px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
background: rgba(0, 0, 0, 0.7);
|
||
color: white;
|
||
padding: 0 16px;
|
||
> div {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
> div:not(:first-child) {
|
||
margin-left: 15px;
|
||
}
|
||
}
|
||
}
|
||
.controls-top {
|
||
padding: 16px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
.top-close {
|
||
width: 84px;
|
||
height: 27px;
|
||
background: rgba(0, 0, 0, 0.7);
|
||
border-radius: 41px;
|
||
font-size: 15px;
|
||
color: #ffffff;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
> i {
|
||
margin-left: 5px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#player-main {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
#player {
|
||
width: 100%;
|
||
height: calc(100% - 46px);
|
||
}
|
||
.player-tool {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
background-color: #3d3d3d;
|
||
height: 40px;
|
||
padding: 0 16px;
|
||
> div:not(:first-child) {
|
||
margin-left: 16px;
|
||
}
|
||
}
|
||
.hikvision-player {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
#video-container {
|
||
width: 100%;
|
||
height: 500px;
|
||
background-color: #000;
|
||
}
|
||
|
||
.control-bar {
|
||
padding: 10px;
|
||
background: #f5f5f5;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.video-source {
|
||
padding: 10px;
|
||
background: #f5f5f5;
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
.volume-control {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
</style> |