海康web控件实现播放rtsp流-回放预览等功能-vue3

狐逍超 2024-07-09 15:03:01 阅读 82

注:vue2的写法请前往:web端海康插件播放rtst流-实现回放预览等功能-vue2_rtsp 插件-CSDN博客

1、使用场景

pc端后端无法给到前端flv、hls、m3u8等流进行播放时,不得不采用海康的web端播放器插件进行播放时使用;

2、优劣势区分

        优点:前端负责对接就行,减少了后端工作内容,因为时播放器控件-里面有相应的下载、截图、云台控制等功能;

        劣势: 网页一般多人使用时-没台电脑都需要下载播放器才能进行播放,大大影响了使用体验; 

3、使用步骤

        1、下载海康平台web控件1.5.1等版本;

         2、组件里配置好需要的基本参数;

        3、引入组件放入父组件中;

        4、父组件调用初始化然后调用播放即可实现;

        注:没播放可以在调用回放预览时使用定时器延迟1000毫秒左右-确保已渲染; 

4、基本功能

        1、 组件做了自适应布局-播放器框可以注定到指定位置-控件可以随着弹框大小自适应变化;

        2、采用了vue3的写法-已将初始化、预览、回放方法暴露;

5、下面就是组件完整代码

<code><template>

<div class="video_box" ref="playWndBox">code>

<div :id="`playWnd`" class="playWnd" :style="{ height: playWndHeight + 'px', width: playWndWidth + 'px' }"></div>code>

</div>

</template>

<script setup>

const { proxy } = getCurrentInstance()

import { onMounted, ref } from "vue"

const props = defineProps({

// 综合安防管理平台提供的appkey

appkey: {

type: String,

default: "25309621",

},

// 综合安防管理平台提供的secret

secret: {

type: String,

default: "XwUwntqpAF9DXF5A3oWr",

},

// 综合安防管理平台IP地址

playIp: {

type: String,

default: "192.168.1.43",

},

// 综合安防管理平台端口

port: {

type: Number,

default: 9901,

},

// // 获取输入的监控点编号值

// cameraIndexCode: {

// type: String,

// default: "72cacf537a4240629c494205949899dc",

// },

// 播放模式

playMode: {

type: Number,

default: 1,

},

// 是否显示控件

showToolbar: {

type: Number,

default: 1,

},

})

const initCount = ref(0)

const pubKey = ref("")

const playWndWidth = ref(null)

const playWndHeight = ref(null)

const oWebControl = ref(null)

const playWndBox = ref(null)

function monResize() {

window.addEventListener("resize", (e) => {

if (oWebControl.value != null) {

setWndCover()

}

})

}

/* 创建插件实例 */

function initPlugin() {

console.log("每次都应该创建")

oWebControl.value = new window.WebControl({

szPluginContainer: `playWnd`, // 指定容器id

iServicePortStart: 15900,

iServicePortEnd: 15909,

// szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid

cbConnectSuccess: () => {

oWebControl.value

.JS_StartService("window", {

dllPath: "./VideoPluginConnect.dll",

})

.then(() => {

oWebControl.value.JS_SetWindowControlCallback({

cbIntegrationCallBack: cbIntegrationCallBack(),

})

//启动插件服务成功

oWebControl.value.JS_CreateWnd(`playWnd`, playWndWidth.value, playWndHeight.value).then(() => {

//JS_CreateWnd创建视频播放窗口,宽高可设定

init() //初始化

})

})

},

// 创建WebControl实例失败

cbConnectError: function () {

oWebControl.value = null

proxy.$message.warning("插件未启动,正在尝试启动,请稍候...")

// 程序未启动时执行error函数,采用wakeup来启动程序

window.WebControl.JS_WakeUp("VideoWebPlugin://")

initCount.value++

if (initCount.value < 3) {

setTimeout(function () {

initPlugin()

}, 2000)

} else {

proxy.$message.warning("插件启动失败,请检查插件是否安装!")

proxy.$tips("是否确定下载播放插件", (done, instance) => {

const url = `${import.meta.env.VITE_APP_FILE}${proxy.$file}/software/VideoWebPlugin.exe` // 下载链接

console.log(url, "下载链接")

// 创建一个隐藏的a标签

const link = document.createElement("a")

link.href = url

link.setAttribute("download", "VideoWebPlugin.exe") // 指定下载的文件名

document.body.appendChild(link)

// 触发点击事件,弹出下载框

link.click()

done()

instance.confirmButtonLoading = false

})

}

},

cbConnectClose: () => {

oWebControl.value = null

proxy.$message.warning("插件未启动,正在尝试启动,请稍候...")

window.WebControl.JS_WakeUp("VideoWebPlugin://")

initCount.value++

if (initCount.value < 3) {

setTimeout(function () {

initPlugin()

}, 3000)

} else {

proxy.$message.warning("插件启动失败,请检查插件是否安装!")

}

},

})

}

// 初始化

function init() {

getPubKey(() => {

var appkey = props.appkey //综合安防管理平台提供的appkey,必填

var secret = setEncrypt(props.secret) //综合安防管理平台提供的secret,必填

var ip = props.playIp //综合安防管理平台IP地址,必填

var playMode = props.playMode //初始播放模式:0-预览,1-回放

var port = props.port //综合安防管理平台端口,若启用HTTPS协议,默认443

var snapDir = "D:\\SnapDir" //抓图存储路径

var videoDir = "D:\\VideoDir" //紧急录像或录像剪辑存储路径

var layout = "1x1" //playMode指定模式的布局

var enableHTTPS = 1 //是否启用HTTPS协议与综合安防管理平台交互,这里总是填1

var encryptedFields = "secret" //加密字段,默认加密领域为secret

var showToolbar = props.showToolbar //是否显示工具栏,0-不显示,非0-显示

var showSmart = 1 //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示

var buttonIDs = "0,16,256,257,258,259,260,512,513,514,515,516,517,768,769" //自定义工具条按钮

//var reconnectTimes = 2; // 重连次数,回放异常情况下有效

//var reconnectTime = 4; // 每次重连的重连间隔 >= reconnectTime

// 请自行修改以上变量值

console.log("参数配置参数", appkey, secret, ip, port)

oWebControl.value

.JS_RequestInterface({

funcName: "init",

argument: JSON.stringify({

appkey: appkey, //API网关提供的appkey

secret: secret, //API网关提供的secret

ip: ip, //API网关IP地址

playMode: playMode, //播放模式(决定显示预览还是回放界面)

port: port, //端口

snapDir: snapDir, //抓图存储路径

videoDir: videoDir, //紧急录像或录像剪辑存储路径

layout: layout, //布局

enableHTTPS: enableHTTPS, //是否启用HTTPS协议

encryptedFields: encryptedFields, //加密字段

showToolbar: showToolbar, //是否显示工具栏

showSmart: showSmart, //是否显示智能信息

buttonIDs: buttonIDs, //自定义工具条按钮

//reconnectTimes:reconnectTimes, //重连次数

//reconnectDuration:reconnectTime //重连间隔

}),

})

.then(function (oData) {

// oWebControl.value.value.JS_SetDocOffset({

// left: 800,

// top: 500,

// });

oWebControl.value.JS_Resize(playWndWidth.value, playWndHeight.value) // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题

// startPlayback(oWebControl.value);

// if (callback) {

// callback()

// }

// startPlayback()

})

})

}

/* 获取公钥 */

function getPubKey(callback) {

oWebControl.value

.JS_RequestInterface({

funcName: "getRSAPubKey",

argument: JSON.stringify({

keyLength: 1024,

}),

})

.then(function (oData) {

if (oData.responseMsg.data) {

pubKey.value = oData.responseMsg.data

callback()

// startPlayback(oWebControl.value);

}

})

}

/* 视频流RSA加密 */

function setEncrypt(value) {

const encrypt = new window.JSEncrypt()

encrypt.setPublicKey(pubKey.value)

return encrypt.encrypt(value)

}

// 回调的消息

function cbIntegrationCallBack(oData) {

// let { responseMsg: type } = oData

// if (type === "error") {

// } else {

// }

}

// 视频预览功能

function previewVideo(data) {

let cameraIndexCode = data // 获取输入的监控点编号值,必填

let streamMode = 0 // 主子码流标识:0-主码流,1-子码流

let transMode = 1 // 传输协议:0-UDP,1-TCP

let gpuMode = 0 // 是否启用GPU硬解,0-不启用,1-启用

let wndId = -1 // 播放窗口序号(在2x2以上布局下可指定播放窗口)

oWebControl.value

.JS_RequestInterface({

funcName: "startPreview",

argument: JSON.stringify({

cameraIndexCode: cameraIndexCode, // 监控点编号

streamMode: streamMode, // 主子码流标识

transMode: transMode, // 传输协议

gpuMode: gpuMode, // 是否开启GPU硬解

wndId: wndId, // 可指定播放窗口

}),

})

.then(function () {

oWebControl.value.JS_SetWindowControlCallback({})

})

}

//录像回放功能

function startPlayback(time) {

if (!time) return

var cameraIndexCode = time.cameraIndexCode //获取输入的监控点编号值,必填

var startTimeStamp = Date.parse(time.beginTime) - 300000 //回放开始时间戳,必填

var endTimeStamp = Date.parse(time.endTime) //回放结束时间戳,必填

console.log(startTimeStamp, endTimeStamp, time.endTime, "这里都没进来")

var recordLocation = 0 //录像存储位置:0-中心存储,1-设备存储

var transMode = 1 //传输协议:0-UDP,1-TCP

var gpuMode = 0 //是否启用GPU硬解,0-不启用,1-启用

var wndId = -1 //播放窗口序号(在2x2以上布局下可指定播放窗口)

oWebControl.value.JS_RequestInterface({

funcName: "startPlayback",

argument: JSON.stringify({

cameraIndexCode: cameraIndexCode, //监控点编号

startTimeStamp: Math.floor(startTimeStamp / 1000).toString(), //录像查询开始时间戳,单位:秒

endTimeStamp: Math.floor(endTimeStamp / 1000).toString(), //录像结束开始时间戳,单位:秒

recordLocation: recordLocation, //录像存储类型:0-中心存储,1-设备存储

transMode: transMode, //传输协议:0-UDP,1-TCP

gpuMode: gpuMode, //是否启用GPU硬解,0-不启用,1-启用

wndId: wndId, //可指定播放窗口

}),

})

}

// 停止回放

function stopAllPlayback() {

oWebControl.value.JS_RequestInterface({

funcName: "stopAllPlayback",

})

}

// 设置窗口裁剪,当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口

function setWndCover() {

var iWidth = $(window).width()

var iHeight = $(window).height()

var oDivRect = $("#playWnd").get(0).getBoundingClientRect()

var iCoverLeft = oDivRect.left < 0 ? Math.abs(oDivRect.left) : 0

var iCoverTop = oDivRect.top < 0 ? Math.abs(oDivRect.top) : 0

var iCoverRight = oDivRect.right - iWidth > 0 ? Math.round(oDivRect.right - iWidth) : 0

var iCoverBottom = oDivRect.bottom - iHeight > 0 ? Math.round(oDivRect.bottom - iHeight) : 0

iCoverLeft = iCoverLeft > 2041 ? 2041 : iCoverLeft

iCoverTop = iCoverTop > 945 ? 945 : iCoverTop

iCoverRight = iCoverRight > 2041 ? 2041 : iCoverRight

iCoverBottom = iCoverBottom > 945 ? 945 : iCoverBottom

oWebControl.value.JS_RepairPartWindow(0, 0, 2041, 946) // 多1个像素点防止还原后边界缺失一个像素条

if (iCoverLeft != 0) {

oWebControl.value.JS_CuttingPartWindow(0, 0, iCoverLeft, 946)

}

if (iCoverTop != 0) {

oWebControl.value.JS_CuttingPartWindow(0, 0, 2041, iCoverTop) // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条

}

if (iCoverRight != 0) {

oWebControl.value.JS_CuttingPartWindow(2041 - iCoverRight, 0, iCoverRight, 946)

}

if (iCoverBottom != 0) {

oWebControl.value.JS_CuttingPartWindow(0, 946 - iCoverBottom, 2041, iCoverBottom)

}

}

// 关闭

function closeHide() {

oWebControl.value.JS_HideWnd() // 先让窗口隐藏,规避插件窗口滞后于浏览器消失问题

if (oWebControl.value != null) {

oWebControl.value.JS_RequestInterface({

funcName: "stopAllPreview",

})

// oWebControl.value.JS_Disconnect().then()

}

}

function logParentSize() {

playWndWidth.value = playWndBox.value.clientWidth

playWndHeight.value = playWndBox.value.clientHeight

console.log(playWndWidth.value, playWndHeight.value, "playWndHeight.value")

}

onMounted(() => {

nextTick(() => {

logParentSize()

})

// // 监听scroll事件,使插件窗口尺寸跟随DIV窗口变化

window.addEventListener("scroll", () => {

if (oWebControl.value != null) {

oWebControl.value.JS_Resize(playWndBox.value.clientWidth, playWndBox.value.clientHeight)

}

})

window.addEventListener("resize", () => {

if (oWebControl.value != null) {

oWebControl.value.JS_Resize(playWndBox.value.clientWidth, playWndBox.value.clientHeight)

}

})

logParentSize()

initPlugin()

})

// setTimeout(() => {

// }, 2000)

defineExpose({

previewVideo,

startPlayback,

closeHide,

initPlugin,

})

</script>

<style lang="scss" scoped>code>

.video_box {

width: 100%;

height: 100%;

}

</style>

6、总结

        直接睡觉-到处睡觉-到头就睡; 



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。