vue3+setup使用rtsp视频流实现实时监控,全屏,拍摄,自动拍摄等功能(纯前端)

Vue3+setup纯前端实现RTSP视频流监控等功能

vue3+setup使用rtsp视频流实现实时监控,全屏,拍摄,自动拍摄等功能(纯前端)

概要

本文介绍了如何在Vue应用中通过WebRTC技术获取摄像头的rtsp视频流,同时展示了实时监控,全屏,拍摄,自动拍摄等功能。

一、获取rtsp流并确保其可用

1.因为是纯前端角度,所以从后端可以获取http开头的视频流地址(其实是在后端电脑打开,然后本地接入后端电脑,进行查看或修改配置)因为rstp流需要转码,所以在摄像头配置里面要修改转码格式
2.前端自己可以下载安装VLC播放器然后进行调试设置
在这里插入图片描述

二、在vue3项目里引入rtsp流

1.下载webrtc-streamer
下载地址:https://github.com/mpromonet/webrtc-streamer/releases
下载版本根据自己电脑进行选择,双击webrtc-streamer.exe可执行文件后在浏览器访问http://127.0.0.1:8000,可以看到自己电脑正在操作的内容。
2.将/html/libs目录下的adapter.min.js和/html目录下面的webrtcstreamer.js文件分别拷贝到vue项目public中,并在index.html文件全局引入。

 <script src="/adapter.min.js"></script>
 <script src="/webrtcstreamer.js"></script>

三、具体代码,video封装

1.父页面

<script setup>

import {
     
      ref } from 'vue'

import videoRtmp from './videoRtmp.vue'
const list = ref([])
const idlist = ref([])
const imgArr = ref([]) // 手动抓拍的图片
const screenshotUrl = ref([]) // 自动抓拍的图片

const total = ref(0)
const currentPage = ref(1)
const keyWord = ref('')
const rtmpUrl = ref('rtsp://用户:密码@电脑网址:554')
// videoFlag 判断是单个还是多个video 对应不同的样式 false是单个 true是多个
const form = ref({
     
      videoFlag: false, videoList: [] })
const openVideo = ref(false)
const screenButton = ref(false) // 默认解禁 点击抓拍按钮后禁止 抓拍完成后解禁
const sButton = ref(true) // 默认禁止 加载完成后解禁
let screenNums = 0 // 加载完成的数量

const loadData = (pageNum = currentPage.value, pageSize = 10) => {
     
     
 
  list.value = [
    {
     
     
      id: 1,
      idName: 'id1',
      name: '设备1',
      rtmpUrl: 'rtsp://用户:密码@电脑网址:554',
      userName: 'admin',
      screenFlag: false,
    },
    {
     
     
      id: 2,
      idName: 'id2',
      name: '设备2',
      code: '002',
      userName: 'admin',
      password: 'VWEFKS',
      screenFlag: false,
      rtmpUrl: 'rtsp://用户:密码@电脑网址:554',
    },
  ]
  total.value = list.value.length
}

//分页
const handlePageChange = (page) => {
     
     
  currentPage.value = page
  loadData()
}
// 搜索
const searchHandle = async () => {
     
     
  currentPage.value = 1
  loadData()
}
/** 选择条数  */
function handleSelectionChange(selection) {
     
     
  console.log(selection)
  idlist.value = selection
}
//单个点击观看
const videoLook = (row) => {
     
     
  console.log(row)
  form.value.videoList = [row]
  form.value.videoFlag = false
  openVideo.value = true
}
//多个观看
const videoAllLook = (row) => {
     
     
  console.log(row)
  form.value.videoList = idlist.value
  form.value.videoFlag = idlist.value.length > 1 ? true : false
  openVideo.value = true
}

//点击叉号
const closeHandle = () => {
     
     
  resetData()
}
//清空数据
const resetData = () => {
     
     
  openVideo.value = false
  imgArr.value = []  
  screenshotUrl.value = []
  screenNums = 0
  screenButton.value = false
  form.value = {
     
     }
  loadData()
<think> 我们正在处理一个关于在Vue项目中使用大华摄像头播放多个视频并管理多个实例的问题。用户特别提到了需要创建多个实例对象并能够关闭视频流。根据背景信息,我们使用PlayerControl.js SDK,并且是在Vue3环境中。 步骤: 1. 创建多个播放器实例:每个视频流需要一个独立的播放器实例。我们可以通过循环或者根据动态数据(例如数组)来创建多个实例。 2. 每个实例需要绑定到不同的DOM元素上(例如不同的div容器)。 3. 在组件销毁时(或需要关闭视频流时),需要正确地释放每个播放器实例,以关闭视频流并释放资源。 具体实现思路: - 在Vue组件中,我们可以使用一个数组(比如playerList)来存储多个播放器实例。 - 在模板中,使用v-for循环生成多个视频容器,每个容器设置一个唯一的ref(或id)。 - 在mounted(或适当的生命周期)中,遍历需要播放的视频流,为每个容器初始化播放器实例,并开始播放视频。 - 在组件销毁前(beforeUnmount或unmounted生命周期),遍历playerList,调用每个实例的销毁方法(如destroy)来关闭视频流。 参考示例代码: 1. 模板部分(使用v-for生成多个视频容器): ```html <template> <div v-for="(item, index) in videoList" :key="index"> <!-- 每个视频容器需要设置一个唯一的id,例如:&#39;dahua-player-&#39;+index --> <div :id="&#39;dahua-player-&#39;+index"></div> </div> </template> ``` 2. 脚本部分: ```javascript import { onMounted, onBeforeUnmount } from &#39;vue&#39;; // 假设已经引入PlayerControl.js,全局有PlayerControl对象 export default { setup() { const videoList = ref([ { url: &#39;rtsp://...&#39;, type: &#39;dahua&#39; }, // ... 多个视频源 ]); const playerList = ref([]); // 用于存储播放器实例 onMounted(() => { // 在DOM渲染后初始化播放器 videoList.value.forEach((item, index) => { // 每个播放器容器的id const containerId = &#39;dahua-player-&#39; + index; // 初始化播放器 const player = new PlayerControl({ id: containerId, // 绑定到对应的div url: item.url, type: item.type, // 其他配置... }); player.play(); // 播放 playerList.value.push(player); // 存储实例 }); }); // 在组件销毁前,销毁所有播放器实例 onBeforeUnmount(() => { playerList.value.forEach(player => { player.destroy(); // 调用销毁方法,关闭视频流并释放资源 }); playerList.value = []; // 清空数组 }); return { videoList }; } }; ``` 注意事项: - 每个播放器实例需要一个独立的DOM容器,所以循环生成时id必须唯一。 - 销毁播放器实例非常重要,否则可能导致资源泄露或视频流无法关闭。 - 大华SDK的具体初始化参数可能有所不同,请参考官方文档。上述代码中,我们假设PlayerControl的构造函数接受一个配置对象,其中包含id(容器id)、url(视频流地址)和type(设备类型)等。 另外,如果需要在播放过程中动态关闭某个视频流,可以单独调用该实例的destroy方法,并从playerList中移除。 例如,提供一个关闭单个视频的方法: ```javascript function closeVideo(index) { if (playerList.value[index]) { playerList.value[index].destroy(); playerList.value.splice(index, 1); // 从数组中移除 // 同时可能需要移除videoList中的对应项,根据业务逻辑 } } ``` 以上是一个基本的实现框架,具体细节需要根据PlayerControl.js SDK的API进行调整。 引用背景中提到的是在Vue3使用,所以我们使用了Composition API(setup)的写法。 由于用户要求生成相关问题,下面是相关问题: §§相关问题§§ 1. 如何动态添加或移除大华摄像头视频流? 2. 在使用大华PlayerControl.js SDK时,如何处理视频播放的错误和重连? 3. 大华摄像头视频流播放时如何实现全屏功能? </think> 在 Vue 项目中实现大华摄像头多视频播放、多实例管理及视频流关闭的方法如下: ### 1. 多实例创建与播放实现 ```html <template> <div class="video-container"> <!-- 动态生成视频容器 --> <div v-for="(camera, index) in cameras" :key="index" :ref="el => setVideoRef(el, index)" class="video-item" ></div> </div> </template> <script setup> import { ref, onMounted, onBeforeUnmount } from &#39;vue&#39;; import PlayerControl from &#39;@dahua/playercontrol&#39;; // 大华播放器SDK // 摄像头配置数组 const cameras = ref([ { url: &#39;rtsp://cam1/stream&#39;, container: null }, { url: &#39;rtsp://cam2/stream&#39;, container: null } ]); // 播放器实例数组 const players = ref([]); // 设置视频容器引用 const setVideoRef = (el, index) => { if (el) cameras.value[index].container = el; }; // 初始化所有摄像头 onMounted(() => { cameras.value.forEach((camera, index) => { if (!camera.container) return; // 创建播放器实例 const player = new PlayerControl({ id: camera.container, url: camera.url, autoplay: true, width: &#39;100%&#39;, height: &#39;100%&#39; }); players.value.push(player); }); }); </script> ``` ### 2. 视频流关闭与资源释放 ```javascript // 关闭指定摄像头 const closeCamera = (index) => { if (players.value[index]) { players.value[index].stop(); // 停止播放 players.value[index].destroy(); // 销毁实例 players.value[index] = null; // 释放引用 } }; // 关闭所有摄像头 const closeAllCameras = () => { players.value.forEach((player, index) => { if (player) { player.stop(); player.destroy(); } }); players.value = []; // 清空实例数组 }; // 组件卸载时自动释放资源 onBeforeUnmount(() => { closeAllCameras(); }); ``` ### 3. 关键注意事项 1. **DOM 容器管理** - 每个播放器需要独立的 DOM 容器 - 使用 `ref` 动态绑定容器元素 - 容器尺寸需明确设置(避免 0x0 容器) 2. **资源释放最佳实践** ```javascript // 正确的销毁顺序 player.stop(); // 停止视频流 player.disconnect();// 断开连接 player.destroy(); // 销毁实例 player = null; // 释放内存引用 ``` 3. **多实例性能优化** - 限制同时播放的摄像头数量(建议 ≤ 4) - 使用 `requestAnimationFrame` 进行渲染控制 - 非活跃窗口暂停播放: ```javascript const handleVisibilityChange = () => { if (document.hidden) { players.value.forEach(p => p.pause()); } else { players.value.forEach(p => p.play()); } }; document.addEventListener(&#39;visibilitychange&#39;, handleVisibilityChange); ``` ### 4. 错误处理建议 ```javascript // 初始化时添加错误监听 players.value.forEach(player => { player.on(&#39;error&#39;, (err) => { console.error(&#39;播放器错误:&#39;, err); // 自动重连逻辑 setTimeout(() => player.reconnect(), 3000); }); }); ``` ### 5. 封装可复用组件建议 ```javascript // CameraPlayer.vue export default { props: { url: String, autoplay: Boolean }, setup(props) { const containerRef = ref(null); let playerInstance = null; onMounted(() => { playerInstance = new PlayerControl({ id: containerRef.value, url: props.url, autoplay: props.autoplay }); }); onBeforeUnmount(() => { playerInstance?.destroy(); }); return { containerRef }; } } ``` > **重要提示**:实际使用时需根据大华 SDK 的版本调整 API 调用方式,最新版 SDK 可能要求使用 `dispose()` 代替 `destroy()`[^1]。建议参考官方文档的实例管理章节。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值