feat(video): 实现后台转码视频播放功能
- 新增“播放后台转码视频”按钮,用于启动转码并播放HLS流- 替换原有大华设备直接播放逻辑为调用后端转码接口 - 引入HLS.js库以支持HLS流播放,并增加错误处理机制 - 修改播放器组件,移除默认控制栏,增加定时检测转码进度逻辑 - 实现转码开始与停止接口调用,增强播放流程的可控性 - 更新弹窗标题与关闭逻辑,优化用户体验 - 调整视频播放器样式,提升视觉效果与兼容性dev
parent
b269359715
commit
54ca5e9e4c
|
|
@ -1,29 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="dialogVisible" title="视频播放" width="50%" @close="handleStop">
|
<el-dialog v-model="dialogVisible" title="播放后台转码视频" width="50%">
|
||||||
<!-- 原生video播放器 -->
|
<!-- 原生video播放器 - 移除了controls属性以去掉默认控制栏 -->
|
||||||
<video
|
<video ref="videoRef" playsinline class="video-player"></video>
|
||||||
ref="videoRef"
|
|
||||||
playsinline
|
|
||||||
controls
|
|
||||||
class="video-player"
|
|
||||||
@error="handleVideoError"
|
|
||||||
></video>
|
|
||||||
|
|
||||||
<!-- 底部操作按钮 -->
|
<!-- 底部操作按钮 -->
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button type="primary" @click="handleStopPreview">
|
<el-button type="primary" @click="dialogVisible = false">
|
||||||
停止播放
|
关闭播放
|
||||||
</el-button>
|
|
||||||
<el-button @click="dialogVisible = false">
|
|
||||||
关闭
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, onBeforeUnmount } from "vue";
|
import { ref, watch } from "vue";
|
||||||
|
import Hls from "hls.js"; // 引入HLS解析库
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
import { getTranscodeStatus, stopTransCode } from "@/request/video_info.js"; // 后端“停止转码”接口
|
||||||
|
|
||||||
// 接收父组件传递的属性
|
// 接收父组件传递的属性
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
|
@ -33,42 +26,61 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
src: {
|
src: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
required: true, // 必须传递HLS流地址
|
||||||
|
},
|
||||||
|
videoId: {
|
||||||
|
type: String,
|
||||||
|
required: true, // 视频Id
|
||||||
},
|
},
|
||||||
channel: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 向父组件传递事件
|
// 向父组件传递事件
|
||||||
const emit = defineEmits(["update:visible"]);
|
const emit = defineEmits(["update:visible", "onStop"]);
|
||||||
|
|
||||||
// 控制弹窗显示(内部响应props.visible)
|
// 控制弹窗显示(内部响应props.visible)
|
||||||
const dialogVisible = ref(props.visible);
|
const dialogVisible = ref(props.visible);
|
||||||
const videoRef = ref(null); // video元素引用
|
const videoRef = ref(null); // video元素引用
|
||||||
|
const isPlaying = ref(false); // 视频播放状态
|
||||||
|
let hlsInstance = null; // HLS实例(用于管理流解析)
|
||||||
|
|
||||||
// 监听父组件visible变化,同步到内部dialogVisible
|
// 监听父组件visible变化,同步到内部dialogVisible
|
||||||
watch(
|
watch(
|
||||||
() => props.visible,
|
() => props.visible,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
dialogVisible.value = newVal;
|
dialogVisible.value = newVal;
|
||||||
if (newVal) {
|
|
||||||
// 延迟一点播放视频,确保DOM已更新
|
|
||||||
setTimeout(() => {
|
|
||||||
handlePlay();
|
|
||||||
}, 100);
|
|
||||||
} else {
|
|
||||||
handleStop();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 定义定时器变量
|
||||||
|
let checkInterval = null;
|
||||||
|
|
||||||
|
// 弹窗打开时执行的方法
|
||||||
|
const onDialogOpen = () => {
|
||||||
|
// 每3秒调用一次接口
|
||||||
|
checkInterval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
// 假设接口名为checkVideoProgress,需自行导入
|
||||||
|
const response = await getTranscodeStatus({ id: props.videoId });
|
||||||
|
if (response.progress > 2) {
|
||||||
|
handlePlay();
|
||||||
|
// 播放后清除定时器
|
||||||
|
if (checkInterval) {
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
checkInterval = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 可根据需要处理接口返回结果
|
||||||
|
} catch (error) {}
|
||||||
|
}, 3000); // 3秒间隔
|
||||||
|
};
|
||||||
|
|
||||||
// 监听内部dialogVisible变化,通知父组件
|
// 监听内部dialogVisible变化,通知父组件
|
||||||
watch(dialogVisible, (newVal) => {
|
watch(dialogVisible, (newVal) => {
|
||||||
emit("update:visible", newVal);
|
emit("update:visible", newVal);
|
||||||
if (!newVal) {
|
if (newVal) {
|
||||||
handleStop();
|
onDialogOpen();
|
||||||
|
} else {
|
||||||
|
destroyPlayer(); // 弹窗关闭时销毁播放器
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -80,68 +92,115 @@ const handlePlay = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 先清空之前的资源
|
||||||
|
video.src = "";
|
||||||
|
|
||||||
|
// 检查src是否有效
|
||||||
if (!props.src) {
|
if (!props.src) {
|
||||||
ElMessage.error("视频源地址为空");
|
ElMessage.error("视频源地址为空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置视频源
|
// HLS.js 支持检测
|
||||||
video.src = props.src;
|
if (Hls.isSupported()) {
|
||||||
|
// 如果已有实例,先销毁
|
||||||
// 尝试播放视频
|
if (hlsInstance) {
|
||||||
video.play().then(() => {
|
hlsInstance.destroy();
|
||||||
ElMessage.success("视频开始播放");
|
|
||||||
}).catch((err) => {
|
|
||||||
ElMessage.error(`播放失败:${err.message}`);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 停止播放
|
|
||||||
const handleStop = () => {
|
|
||||||
const video = videoRef.value;
|
|
||||||
if (video) {
|
|
||||||
video.pause();
|
|
||||||
video.removeAttribute('src'); // 移除src属性
|
|
||||||
video.load(); // 重新加载以清空视频内容
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 处理视频错误
|
|
||||||
const handleVideoError = (e) => {
|
|
||||||
console.error("视频播放错误:", e);
|
|
||||||
ElMessage.error("视频播放出现错误,请检查网络连接或设备状态");
|
|
||||||
};
|
|
||||||
|
|
||||||
// 停止预览
|
|
||||||
const handleStopPreview = async () => {
|
|
||||||
try {
|
|
||||||
const response = await fetch('/dahuaVideo/stopPreview', {
|
|
||||||
method: 'POST',
|
|
||||||
});
|
|
||||||
const result = await response.json();
|
|
||||||
if (result.success) {
|
|
||||||
ElMessage.success("停止预览成功");
|
|
||||||
handleStop();
|
|
||||||
} else {
|
|
||||||
ElMessage.error("停止预览失败: " + result.message);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
ElMessage.error("停止预览失败: " + (error.message || "未知错误"));
|
hlsInstance = new Hls({
|
||||||
|
maxBufferLength: 30, // 增加缓冲长度
|
||||||
|
maxMaxBufferLength: 60,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听错误事件
|
||||||
|
hlsInstance.on(Hls.Events.ERROR, (event, data) => {
|
||||||
|
if (data.fatal) {
|
||||||
|
switch (data.type) {
|
||||||
|
case Hls.ErrorTypes.NETWORK_ERROR:
|
||||||
|
hlsInstance.startLoad();
|
||||||
|
break;
|
||||||
|
case Hls.ErrorTypes.MEDIA_ERROR:
|
||||||
|
hlsInstance.recoverMediaError();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 无法恢复的错误,需要重新初始化
|
||||||
|
destroyPlayer();
|
||||||
|
handlePlay();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
hlsInstance.loadSource(props.src);
|
||||||
|
hlsInstance.attachMedia(video);
|
||||||
|
|
||||||
|
hlsInstance.on(Hls.Events.MANIFEST_PARSED, () => {
|
||||||
|
video.play().then(() => {
|
||||||
|
isPlaying.value = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (video.canPlayType("application/vnd.apple.mpegurl")) {
|
||||||
|
// Safari等原生支持HLS的浏览器
|
||||||
|
video.src = props.src;
|
||||||
|
video.addEventListener("loadedmetadata", () => {
|
||||||
|
video
|
||||||
|
.play()
|
||||||
|
.then(() => {
|
||||||
|
isPlaying.value = true;
|
||||||
|
ElMessage.success("视频开始播放");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
ElMessage.error(`播放失败:${err.message}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ElMessage.error("您的浏览器不支持HLS视频流播放,请更换浏览器");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 组件卸载前停止播放
|
// 销毁播放器时清除定时器
|
||||||
onBeforeUnmount(() => {
|
const destroyPlayer = () => {
|
||||||
handleStop();
|
// 清除定时器
|
||||||
});
|
if (checkInterval) {
|
||||||
|
clearInterval(checkInterval);
|
||||||
|
checkInterval = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 原有逻辑保持不变
|
||||||
|
isPlaying.value = false;
|
||||||
|
if (hlsInstance) {
|
||||||
|
hlsInstance.destroy();
|
||||||
|
hlsInstance = null;
|
||||||
|
}
|
||||||
|
if (videoRef.value) {
|
||||||
|
const video = videoRef.value;
|
||||||
|
video.pause();
|
||||||
|
video.src = "";
|
||||||
|
}
|
||||||
|
handleStopTranscode();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 停止转码(调用后端接口)
|
||||||
|
const handleStopTranscode = async () => {
|
||||||
|
try {
|
||||||
|
await stopTransCode({ id: props.videoId }); // 调用后端“停止转码”接口
|
||||||
|
emit("onStop"); // 通知父组件“转码已停止”
|
||||||
|
dialogVisible.value = false; // 关闭弹窗
|
||||||
|
} catch (error) {
|
||||||
|
if (error !== "cancel") {
|
||||||
|
ElMessage.error(`停止转码失败:${error.message || "未知错误"}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.video-player {
|
.video-player {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 600px;
|
min-height: 600px;
|
||||||
object-fit: contain;
|
object-fit: contain; /* 保持视频比例 */
|
||||||
background-color: #000;
|
background-color: #000; /* 增加黑色背景,使视频区域更明显 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-controls {
|
.video-controls {
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
<div>
|
<div>
|
||||||
<el-card>
|
<el-card>
|
||||||
<el-form
|
<el-form
|
||||||
:model="searchForm"
|
:model="searchForm"
|
||||||
label-width="60px"
|
label-width="60px"
|
||||||
@submit.prevent="fnResetPagination"
|
@submit.prevent="fnResetPagination"
|
||||||
>
|
>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
|
|
@ -16,7 +16,10 @@
|
||||||
<el-form-item label-width="10px">
|
<el-form-item label-width="10px">
|
||||||
<el-button type="primary" native-type="submit">搜索</el-button>
|
<el-button type="primary" native-type="submit">搜索</el-button>
|
||||||
<el-button native-type="reset" @click="fnResetPagination"
|
<el-button native-type="reset" @click="fnResetPagination"
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
|
>
|
||||||
|
<el-button type="success" @click="handleStartTranscode"
|
||||||
|
>播放后台转码视频</el-button
|
||||||
>
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -26,9 +29,9 @@
|
||||||
|
|
||||||
<layout-card>
|
<layout-card>
|
||||||
<layout-table
|
<layout-table
|
||||||
v-model:pagination="pagination"
|
v-model:pagination="pagination"
|
||||||
:data="list"
|
:data="list"
|
||||||
@get-data="fnGetData"
|
@get-data="fnGetData"
|
||||||
>
|
>
|
||||||
<!-- 表格列定义(保持不变) -->
|
<!-- 表格列定义(保持不变) -->
|
||||||
<el-table-column label="序号" width="70">
|
<el-table-column label="序号" width="70">
|
||||||
|
|
@ -42,9 +45,9 @@
|
||||||
<el-table-column property="PLS_ID" label="是否定位">
|
<el-table-column property="PLS_ID" label="是否定位">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-popover
|
<el-popover
|
||||||
placement="top-start"
|
placement="top-start"
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
content="定位后才能在Bi页上展示"
|
content="定位后才能在Bi页上展示"
|
||||||
>
|
>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-tag v-if="row.PLS_ID" type="success"> 是 </el-tag>
|
<el-tag v-if="row.PLS_ID" type="success"> 是 </el-tag>
|
||||||
|
|
@ -56,25 +59,25 @@
|
||||||
<el-table-column label="操作" width="250">
|
<el-table-column label="操作" width="250">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="row.ISSHOW === 0"
|
v-if="row.ISSHOW === 0"
|
||||||
type="primary"
|
type="primary"
|
||||||
text
|
text
|
||||||
link
|
link
|
||||||
@click="fnUpToBi(row.videomanagerId)"
|
@click="fnUpToBi(row.videomanagerId)"
|
||||||
>置顶</el-button
|
>置顶</el-button
|
||||||
>
|
>
|
||||||
<!-- <el-button type="primary" text link @click="fnSetPositioning(row)">-->
|
<!-- <el-button type="primary" text link @click="fnSetPositioning(row)">-->
|
||||||
<!-- {{ row.PLS_ID ? "修改定位" : "添加定位" }}-->
|
<!-- {{ row.PLS_ID ? "修改定位" : "添加定位" }}-->
|
||||||
<!-- </el-button>-->
|
<!-- </el-button>-->
|
||||||
<el-button link type="primary" @click="fnPreviewVideo(row)"
|
<el-button link type="primary" @click="fnPreviewVideo(row)"
|
||||||
>播放视频</el-button
|
>播放视频</el-button
|
||||||
>
|
>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="row.videomanagerId"
|
v-if="row.videomanagerId"
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="fnDeleteVideo(row)"
|
@click="fnDeleteVideo(row)"
|
||||||
>移除定位</el-button
|
>移除定位</el-button
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -83,37 +86,38 @@
|
||||||
|
|
||||||
<!-- 其他弹窗(保持不变) -->
|
<!-- 其他弹窗(保持不变) -->
|
||||||
<add
|
<add
|
||||||
v-model:visible="data.addDialog.Visible"
|
v-model:visible="data.addDialog.Visible"
|
||||||
v-model:form="data.addDialog.form"
|
v-model:form="data.addDialog.form"
|
||||||
:type="data.addDialog.type"
|
:type="data.addDialog.type"
|
||||||
@get-data="fnResetPagination"
|
@get-data="fnResetPagination"
|
||||||
/>
|
/>
|
||||||
<layout-video
|
<layout-video
|
||||||
v-if="data.videoDialog.visible"
|
v-if="data.videoDialog.visible"
|
||||||
v-model:visible="data.videoDialog.visible"
|
v-model:visible="data.videoDialog.visible"
|
||||||
:src="data.videoDialog.src"
|
:src="data.videoDialog.src"
|
||||||
/>
|
/>
|
||||||
<selecting-points
|
<selecting-points
|
||||||
:id="data.selectingPointsDialog.id"
|
:id="data.selectingPointsDialog.id"
|
||||||
v-model:visible="data.selectingPointsDialog.visible"
|
v-model:visible="data.selectingPointsDialog.visible"
|
||||||
:index-code="data.selectingPointsDialog.indexCode"
|
:index-code="data.selectingPointsDialog.indexCode"
|
||||||
:region-path-name="data.selectingPointsDialog.regionPathName"
|
:region-path-name="data.selectingPointsDialog.regionPathName"
|
||||||
:cam-name="data.selectingPointsDialog.camName"
|
:cam-name="data.selectingPointsDialog.camName"
|
||||||
:videomanager-id="data.selectingPointsDialog.videomanagerId"
|
:videomanager-id="data.selectingPointsDialog.videomanagerId"
|
||||||
@get-data="fnResetPagination"
|
@get-data="fnResetPagination"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 大华视频播放器 -->
|
<!-- 转码视频播放器(修改后:双向绑定visible + 传递src) -->
|
||||||
<play-video
|
<play-video
|
||||||
v-model:visible="data.dahuaVideoDialog.visible"
|
v-model:visible="data.transcodeVideoDialog.visible"
|
||||||
:src="data.dahuaVideoDialog.src"
|
:src="data.transcodeVideoDialog.src"
|
||||||
:channel="data.dahuaVideoDialog.channel"
|
:video-id="data.transcodeVideoDialog.id"
|
||||||
|
@on-stop="onTranscodeStopped"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { serialNumber } from "@/assets/js/utils.js";
|
import {serialNumber} from "@/assets/js/utils.js";
|
||||||
import useListData from "@/assets/js/useListData.js";
|
import useListData from "@/assets/js/useListData.js";
|
||||||
import {
|
import {
|
||||||
getHkVideoManagerList,
|
getHkVideoManagerList,
|
||||||
|
|
@ -121,13 +125,13 @@ import {
|
||||||
setVideoManagerDelete,
|
setVideoManagerDelete,
|
||||||
} from "@/request/video_manager.js";
|
} from "@/request/video_manager.js";
|
||||||
import Add from "./components/add.vue";
|
import Add from "./components/add.vue";
|
||||||
import { reactive } from "vue";
|
import {reactive} from "vue";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import {ElMessage, ElMessageBox} from "element-plus";
|
||||||
import SelectingPoints from "./components/selecting_points.vue";
|
import SelectingPoints from "./components/selecting_points.vue";
|
||||||
import LayoutVideo from "@/components/video/index.vue";
|
import LayoutVideo from "@/components/video/index.vue";
|
||||||
import { setVideoManagerList } from "@/request/eightwork_videomanager.js";
|
import {setVideoManagerList} from "@/request/eightwork_videomanager.js";
|
||||||
import PlayVideo from "@/views/video_manager/video_manager/components/playVideo.vue";
|
import PlayVideo from "@/views/video_manager/video_manager/components/playVideo.vue"; // 引入新播放器组件
|
||||||
import {loginDahua} from "@/request/video_info.js";
|
import {startTransCode, stopTransCode} from "@/request/video_info.js"; // 转码接口
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
addDialog: {
|
addDialog: {
|
||||||
|
|
@ -151,16 +155,31 @@ const data = reactive({
|
||||||
videomanagerId: "",
|
videomanagerId: "",
|
||||||
visible: false,
|
visible: false,
|
||||||
},
|
},
|
||||||
dahuaVideoDialog: {
|
transcodeVideoDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
src: "",
|
src: "http://localhost:8100/api/hls/stream.m3u8", // 后端转码后HLS流的访问路径
|
||||||
channel: 0,
|
id: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 启动转码并显示播放器
|
||||||
|
const handleStartTranscode = async () => {
|
||||||
|
try {
|
||||||
|
await startTransCode(); // 调用后端“启动转码”接口
|
||||||
|
data.transcodeVideoDialog.visible = true; // 显示播放器弹窗
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error("启动转码失败: " + (error.message || "未知错误"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 转码停止后的回调
|
||||||
|
const onTranscodeStopped = async () => {
|
||||||
|
await stopTransCode(); // 调用后端“停止转码”接口
|
||||||
|
};
|
||||||
|
|
||||||
// 列表数据逻辑(保持不变)
|
// 列表数据逻辑(保持不变)
|
||||||
const { list, pagination, searchForm, fnGetData, fnResetPagination } =
|
const {list, pagination, searchForm, fnGetData, fnResetPagination} =
|
||||||
useListData(getHkVideoManagerList);
|
useListData(getHkVideoManagerList);
|
||||||
|
|
||||||
// 其他方法(保持不变)
|
// 其他方法(保持不变)
|
||||||
// const fnSetPositioning = async (row) => {
|
// const fnSetPositioning = async (row) => {
|
||||||
|
|
@ -176,28 +195,19 @@ const fnUpToBi = async (videomanagerId) => {
|
||||||
await ElMessageBox.confirm("确定要置顶吗?置顶后将会默认展示在Bi页", {
|
await ElMessageBox.confirm("确定要置顶吗?置顶后将会默认展示在Bi页", {
|
||||||
type: "warning",
|
type: "warning",
|
||||||
});
|
});
|
||||||
await setUpToBi({ videomanagerId });
|
await setUpToBi({videomanagerId});
|
||||||
ElMessage({ message: "操作成功", type: "success" });
|
ElMessage({message: "操作成功", type: "success"});
|
||||||
};
|
};
|
||||||
|
|
||||||
const fnPreviewVideo = async (row) => {
|
const fnPreviewVideo = async (row) => {
|
||||||
try {
|
try {
|
||||||
// 先登录大华设备
|
const resData = await startTransCode({url: row.url, id: row.PLS_ID}); // 调用后端“启动转码”接口
|
||||||
const loginResult = await loginDahua();
|
data.transcodeVideoDialog.visible = true; // 显示播放器弹窗
|
||||||
console.log("大华设备登录结果:", loginResult);
|
data.transcodeVideoDialog.id = row.PLS_ID; // 显示播放器弹窗
|
||||||
|
data.transcodeVideoDialog.src =
|
||||||
if (!loginResult.success) {
|
"http://172.16.70.226:7811/" + resData.videoUrl + "stream.m3u8";
|
||||||
ElMessage.error("设备登录失败: " + loginResult.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调用大华SDK接口播放视频
|
|
||||||
data.dahuaVideoDialog.visible = true;
|
|
||||||
data.dahuaVideoDialog.channel = row.PLS_ID || 0;
|
|
||||||
data.dahuaVideoDialog.src = `/dahuaVideo/start-preview?channel=${row.PLS_ID || 0}`;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("播放视频过程出错:", error);
|
ElMessage.error("启动转码失败: " + (error.message || "未知错误"));
|
||||||
ElMessage.error("播放视频失败: " + (error.message || "未知错误"));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -211,8 +221,8 @@ const fnDeleteVideo = async (row) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await ElMessageBox.confirm(
|
await ElMessageBox.confirm(
|
||||||
"移除定位将会结束视频推送,并删除推送信息。确定要移除定位吗?",
|
"移除定位将会结束视频推送,并删除推送信息。确定要移除定位吗?",
|
||||||
{ type: "warning" }
|
{type: "warning"}
|
||||||
);
|
);
|
||||||
await setVideoManagerDelete({
|
await setVideoManagerDelete({
|
||||||
VIDEOMANAGER_ID: row.videomanagerId,
|
VIDEOMANAGER_ID: row.videomanagerId,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue