Vue 3 + ezuikit-js 7.7.7 集成萤石云:3步实现监控、云台控制与全屏

发布时间:2026/9/27 15:37:52

Vue 3 + ezuikit-js 7.7.7 集成萤石云:3步实现监控、云台控制与全屏
Vue 3 集成萤石云监控从零实现播放、云台控制与全屏功能在智能安防和远程监控需求日益增长的今天前端开发者经常需要将视频监控功能集成到Web应用中。本文将详细介绍如何使用Vue 3和官方ezuikit-js SDK7.7.7版本快速实现萤石云摄像头的核心功能集成。1. 环境准备与SDK集成1.1 创建Vue 3项目使用Vite快速初始化一个Vue 3项目npm create vitelatest vue3-ezviz-demo --template vue cd vue3-ezviz-demo npm install1.2 安装ezuikit-js特别注意版本兼容性问题7.7.7版本经过验证稳定性最佳npm install ezuikit-js7.7.71.3 获取萤石云开发凭证在集成前需要准备以下关键信息设备序列号摄像头的唯一标识访问令牌(accessToken)通过萤石云开放平台API获取视频地址通常格式为ezopen://open.ys7.com/[设备序列号]/[通道号].hd.live提示accessToken有效期通常为7天生产环境需要实现自动刷新机制2. 基础播放器实现2.1 组件初始化创建EzvizPlayer.vue组件实现基础播放功能template div classezviz-container div idezviz-player refplayerContainer/div /template script import { ref, onMounted, onBeforeUnmount } from vue import EZUIKit from ezuikit-js export default { props: { deviceSerial: { type: String, required: true }, accessToken: { type: String, required: true }, channelNo: { type: Number, default: 1 } }, setup(props) { const player ref(null) const playerContainer ref(null) const initPlayer () { player.value new EZUIKit.EZUIKitPlayer({ id: ezviz-player, accessToken: props.accessToken, url: ezopen://open.ys7.com/${props.deviceSerial}/${props.channelNo}.hd.live, autoplay: true, width: 100%, height: 500, template: pcLive, // PC端优化模板 header: [capture, save, zoom], // 显示截图、保存、缩放按钮 footer: [talk, broadcast, hd, fullScreen] // 显示对讲、语音播报、清晰度切换、全屏按钮 }) } onMounted(() { initPlayer() }) onBeforeUnmount(() { if (player.value) { player.value.destroy() } }) return { playerContainer } } } /script style scoped .ezviz-container { position: relative; width: 100%; margin-bottom: 20px; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } /style2.2 播放器参数详解关键配置参数说明参数类型说明推荐值idString播放器容器ID必须与DOM元素ID一致accessTokenString接口调用凭证通过API获取urlString视频流地址格式ezopen://open.ys7.com/设备号/通道号.hd.livewidthNumber/String播放器宽度数字或100%heightNumber/String播放器高度根据布局需要autoplayBoolean自动播放truetemplateString界面模板pcLive或mobileLive3. 云台控制功能实现3.1 云台控制API封装创建ptzControl.js工具类import axios from axios const PTZ_API { START: https://open.ys7.com/api/lapp/device/ptz/start, STOP: https://open.ys7.com/api/lapp/device/ptz/stop } export const ptzControl { directions: { UP: 0, DOWN: 1, LEFT: 2, RIGHT: 3, UP_LEFT: 4, UP_RIGHT: 6, DOWN_LEFT: 5, DOWN_RIGHT: 7 }, /** * 开始云台控制 * param {Object} params * param {String} params.accessToken * param {String} params.deviceSerial * param {Number} params.channelNo * param {Number} params.direction * param {Number} [params.speed2] 1-8 */ async start(params) { try { const res await axios.post(PTZ_API.START, null, { params: { accessToken: params.accessToken, deviceSerial: params.deviceSerial, channelNo: params.channelNo || 1, direction: params.direction, speed: params.speed || 2 } }) return res.data } catch (error) { console.error(PTZ start error:, error) throw error } }, /** * 停止云台控制 * param {Object} params * param {String} params.accessToken * param {String} params.deviceSerial * param {Number} params.channelNo */ async stop(params) { try { const res await axios.post(PTZ_API.STOP, null, { params: { accessToken: params.accessToken, deviceSerial: params.deviceSerial, channelNo: params.channelNo || 1 } }) return res.data } catch (error) { console.error(PTZ stop error:, error) throw error } } }3.2 云台控制UI实现在播放器组件中添加控制按钮template div classcontrol-panel div classdirection-control button clickcontrolPTZ(UP_LEFT) classcontrol-btn i classicon-arrow-up-left/i /button button clickcontrolPTZ(UP) classcontrol-btn i classicon-arrow-up/i /button button clickcontrolPTZ(UP_RIGHT) classcontrol-btn i classicon-arrow-up-right/i /button button clickcontrolPTZ(LEFT) classcontrol-btn i classicon-arrow-left/i /button button clickstopPTZ classcontrol-btn stop-btn i classicon-stop/i /button button clickcontrolPTZ(RIGHT) classcontrol-btn i classicon-arrow-right/i /button button clickcontrolPTZ(DOWN_LEFT) classcontrol-btn i classicon-arrow-down-left/i /button button clickcontrolPTZ(DOWN) classcontrol-btn i classicon-arrow-down/i /button button clickcontrolPTZ(DOWN_RIGHT) classcontrol-btn i classicon-arrow-down-right/i /button /div div classspeed-control label云台速度/label input typerange min1 max8 v-modelptzSpeed changeupdateSpeed span{{ ptzSpeed }}/span /div /div /template script import { ref } from vue import { ptzControl } from ../utils/ptzControl export default { props: { deviceSerial: String, accessToken: String, channelNo: Number }, setup(props) { const ptzSpeed ref(3) const controlPTZ async (direction) { try { await ptzControl.start({ accessToken: props.accessToken, deviceSerial: props.deviceSerial, channelNo: props.channelNo, direction: ptzControl.directions[direction], speed: ptzSpeed.value }) } catch (error) { console.error(PTZ control failed:, error) } } const stopPTZ async () { try { await ptzControl.stop({ accessToken: props.accessToken, deviceSerial: props.deviceSerial, channelNo: props.channelNo }) } catch (error) { console.error(PTZ stop failed:, error) } } const updateSpeed () { console.log(PTZ speed updated to:, ptzSpeed.value) } return { ptzSpeed, controlPTZ, stopPTZ, updateSpeed } } } /script style scoped .control-panel { margin-top: 15px; padding: 15px; background: #f5f7fa; border-radius: 8px; } .direction-control { display: grid; grid-template-columns: repeat(3, 60px); grid-template-rows: repeat(3, 60px); gap: 5px; justify-content: center; } .control-btn { width: 100%; height: 100%; border: 1px solid #dcdfe6; border-radius: 4px; background: white; cursor: pointer; transition: all 0.3s; } .control-btn:hover { background: #f2f6fc; border-color: #c0c4cc; } .stop-btn { grid-column: 2; grid-row: 2; background: #f56c6c; color: white; } .speed-control { margin-top: 15px; text-align: center; } .speed-control input { width: 200px; margin: 0 10px; } /style4. 高级功能实现4.1 全屏控制优化虽然SDK自带全屏按钮但我们可以通过浏览器API实现更灵活的控制const handleFullscreen () { const playerEl document.getElementById(ezviz-player) if (!document.fullscreenElement) { playerEl.requestFullscreen().catch(err { console.error(全屏错误: ${err.message}) }) } else { document.exitFullscreen() } } // 监听全屏变化 onMounted(() { document.addEventListener(fullscreenchange, () { console.log(全屏状态变化:, !!document.fullscreenElement) }) })4.2 音频控制实现音频的开启/关闭功能const audioEnabled ref(false) const toggleAudio () { if (!player.value) return if (audioEnabled.value) { player.value.closeSound() } else { player.value.openSound() } audioEnabled.value !audioEnabled.value }4.3 异常处理与重连机制增强播放器的稳定性const initPlayerWithRetry async (retryCount 3) { try { initPlayer() // 监听错误事件 player.value.on(error, (error) { console.error(播放器错误:, error) if (retryCount 0) { setTimeout(() { initPlayerWithRetry(retryCount - 1) }, 3000) } }) } catch (error) { console.error(播放器初始化失败:, error) if (retryCount 0) { setTimeout(() { initPlayerWithRetry(retryCount - 1) }, 3000) } } }5. 生产环境优化建议5.1 Token自动刷新实现accessToken的自动刷新机制let refreshTimer null const setupTokenRefresh () { // 假设token有效期为7天(604800秒)提前1小时刷新 const refreshInterval 604800 - 3600 refreshTimer setInterval(async () { try { const newToken await fetchNewToken() player.value.updateToken(newToken) props.accessToken newToken } catch (error) { console.error(Token刷新失败:, error) } }, refreshInterval * 1000) } onMounted(() { setupTokenRefresh() }) onBeforeUnmount(() { if (refreshTimer) { clearInterval(refreshTimer) } })5.2 性能优化技巧懒加载播放器当监控组件不在可视区域时暂停播放清晰度自适应根据网络状况动态调整视频清晰度心跳检测定期检查视频流状态异常时自动恢复// 使用IntersectionObserver实现懒加载 const setupLazyLoad () { const observer new IntersectionObserver((entries) { entries.forEach(entry { if (entry.isIntersecting) { if (player.value player.value.isPaused()) { player.value.play() } } else { if (player.value !player.value.isPaused()) { player.value.pause() } } }) }, { threshold: 0.1 }) observer.observe(playerContainer.value) }5.3 移动端适配针对移动设备的特殊处理const checkMobile () { return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) } const initPlayer () { const isMobile checkMobile() player.value new EZUIKit.EZUIKitPlayer({ // ...其他配置 template: isMobile ? mobileLive : pcLive, width: isMobile ? window.innerWidth : 100%, height: isMobile ? window.innerHeight * 0.6 : 500 }) }

相关新闻

vLLM CPU推理优化:Phi-4-da8w8-torchao-v0.16.0环境变量设置最佳实践

vLLM CPU推理优化:Phi-4-da8w8-torchao-v0.16.0环境变量设置最佳实践

2026/8/23 0:30:47

vLLM CPU推理优化:Phi-4-da8w8-torchao-v0.16.0环境变量设置最佳实践 【免费下载链接】Phi-4-da8w8-torchao-v0.16.0 项目地址: https://ai.gitcode.com/hf_mirrors/amd/Phi-4-da8w8-torchao-v0.16.0 Phi-4-da8w8-torchao-v0.16.0是基于Phi3架构的大语言模型…

OpenAPI规范验证终极指南:使用OAS-Kit oas-validator确保API定义正确性

OpenAPI规范验证终极指南:使用OAS-Kit oas-validator确保API定义正确性

2026/9/23 12:56:36

OpenAPI规范验证终极指南:使用OAS-Kit oas-validator确保API定义正确性 【免费下载链接】oas-kit Convert Swagger 2.0 definitions to OpenAPI 3.0 and resolve/validate/lint 项目地址: https://gitcode.com/gh_mirrors/oa/oas-kit 在API开发过程中&#x…

超星平台学习行为分析:8维度K-Means聚类实战,准确率86.3%

超星平台学习行为分析:8维度K-Means聚类实战,准确率86.3%

2026/8/23 0:30:47

超星平台学习行为分析:8维度K-Means聚类实战与模型优化 1. 教育数据挖掘的技术演进与现状 教育数据挖掘(Educational Data Mining)作为一门交叉学科,正在深刻改变在线教育行业的运营模式。根据国际教育数据挖掘协会的最新报告&am…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/26 19:14:12

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/27 1:30:29

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/27 1:30:37

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/27 1:30:35

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/27 1:30:34

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/26 16:36:51

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/26 14:29:04

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/26 13:57:22

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/26 23:35:16

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…