使用ezuikit-js封装一个对接摄像头的组件
ezuikit-js 是一个基于 JavaScript 的视频播放库,主要用于在网页中嵌入实时视频流播放功能。它通常用于与支持 RTSP、RTMP、HLS 等协议的摄像头或视频流服务器进行交互,提供流畅的视频播放体验。
主要功能
多协议支持:支持 RTSP、RTMP、HLS 等主流视频流协议。
实时播放:低延迟播放实时视频流。
多平台兼容:支持 PC 端和移动端浏览器。
丰富的 API:提供 JavaScript API,方便开发者自定义控制和集成。
轻量级:库文件体积小,加载速度快。
使用场景
安防监控:实时查看摄像头视频流。
直播应用:嵌入直播视频流到网页中。
视频会议:播放远程会议视频流。
PlayVideomonitor.vue组件
<template>
<el-dialog
v-model="dialogVisible"
:width="isLargeScreen ? 1680 : 840"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<template #title>
<div style="display: flex; align-items: center">
监控摄像头 ({{ playName }})
<el-button
type="text"
size="mini"
class="refresh-btn"
@click="refreshFun"
title="点击刷新"
>
<template #icon>
<span class="ti-shuaxin"></span>
</template>
</el-button>
</div>
</template>
<el-tabs v-model="playType" class="demo-tabs" @tab-click="tabeChange">
<el-tab-pane label="实时视频" name="pcLive">
<div :id="playConfig" class="videoMonitor-content"></div>
</el-tab-pane>
<el-tab-pane label="历史回放" name="pcRec">
<div :id="playRecConfig" class="videoMonitor-content"></div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</template>
<script lang="ts" setup>
import EZUIKit from "ezuikit-js";
import { uuid } from "vue-uuid";
import { ElMessage } from "element-plus";
import {
computed,
getCurrentInstance,
onMounted,
ref,
defineProps,
defineEmits,
} from "vue";
import userInfoStorage from "@/userInfoStorage";
import { useMediaQuery } from "@vueuse/core";
const { proxy }: any = getCurrentInstance();
const props = defineProps<{
modelValue: Boolean;
playId: string | null;
projectId: string;
playName: string;
}>();
const emits = defineEmits<{
(e: "update:modelValue", value: Boolean): void;
}>();
const isLargeScreen = useMediaQuery("(min-height:2000px)");
//公司id
const companyId = computed(() => {
return userInfoStorage.getCompanyId();
});
let player: any = null;
let playerRec: any = null;
const dialogVisible = computed({
get() {
return props.modelValue;
},
set(v: Boolean) {
emits("update:modelValue", v);
},
});
const playConfig = ref(uuid.v4());
const playRecConfig = ref(uuid.v4());
const playType = ref("pcLive");
const getAccessToken = () => {
if (playType.value !== "") {
proxy.axios
.get(
`/cloud/camera/company/${companyId.value}/project/${props.projectId}/play-video/${props.playId}?linkType=0 `
)
.then(({ data }: { data: any }) => {
if (data.errorcode == 0) {
if (playType.value == "pcLive") {
init(data.data.accessToken, data.data.url, "pcLive");
} else if (playType.value == "pcRec") {
initRec(data.data.accessToken, data.data.url, "pcRec");
}
} else {
ElMessage.warning(data.message);
}
})
.catch((err: any) => {
console.error(err);
});
}
};
const tabeChange = (val: any) => {
if (playType.value == "pcLive") {
if (player) {
destroy();
}
} else {
if (playerRec) {
destroyRec();
}
}
getAccessToken();
};
function init(token: any, url: any, playType: any) {
if (player) {
destroy();
}
player = new EZUIKit.EZUIKitPlayer({
id: playConfig.value, // 视频容器ID
accessToken: token,
url: url,
width: isLargeScreen.value ? 1600 : 800,
height: isLargeScreen.value ? 900 : 450,
template: playType,
});
setTimeout(() => {
player.play();
}, 500);
}
function initRec(token: any, url: any, playType: any) {
if (playerRec) {
destroyRec();
}
player = new EZUIKit.EZUIKitPlayer({
id: playRecConfig.value, // 视频容器ID
accessToken: token,
url: url,
width: isLargeScreen.value ? 1600 : 800,
height: isLargeScreen.value ? 900 : 450,
template: playType,
});
playerRec.play();
}
function destroy() {
if (player) {
player.destroy();
}
player = null;
}
function destroyRec() {
if (playerRec) {
playerRec.destroy();
}
playerRec = null;
}
const refreshFun = () => {
getAccessToken();
};
onMounted(() => {
getAccessToken();
});
</script>
<style scoped>
.videoMonitor-content {
height: 400px;
}
.el-dialog:deep(.el-dialog__body) {
padding: 0 var(--el-dialog-padding-primary);
}
@media (min-height: 2000px) {
.videoMonitor-content {
height: 800px;
}
}
</style>
父组件使用
<!-- 遍历video信息 把每一个信息传给monitorClick事件 -->
<template v-if="videoData && videoData.length > 0">
<div v-for="(item, index) in videoData" :key="item.cameraId">
<span
:title="item.alias"
class="imgconetnt"
@click="monitorClick(item)"
>
<img src="@/assets/img/monitor1.png" class="monitor-img" />
</span>
</div>
</template>
<PlayVideomonitor
v-model="monitorVis"
v-if="monitorVis"
:playId="playId"
:playName="playName"
:projectId="projectId"
/>
//projectId是自定义属性,业务工程id
const monitorVis = ref<boolean>(false);
const playId = ref("");
const playName = ref("");
//获取video信息
const videoData = ref<any[]>([]);
const getVideoData = () => {
appAxios
.get(
`/cloud/camera/company/${companyId.value}/project/${props.projectId}/cameras?linkType=0`
)
.then(({ data }: { data: any }) => {
if (data.errorcode == 0) {
let res = data.data;
videoData.value = res;
} else {
ElMessage.error(data.message);
}
})
.catch((err) => {
console.error(err);
});
};
//点击每一个摄像头拿到每一个信息
const monitorClick = (row: any) => {
if (row.status == 2) {
return notificationMessage("摄像头状态异常,无法播放", "提示", "warning");
}
if (row.status == 0) {
return notificationMessage("摄像头已被禁用,无法播放", "提示", "error");
}
monitorVis.value = true;
playId.value = row.cameraId;
playType.value = row.videoQuality;
playName.value = row.alias;
};