海康视频播放,包含h5和web插件

Roottt_ 2024-08-22 08:03:01 阅读 65

自行下载

海康开放平台

在这里插入图片描述

demo 都写得很清楚,不多描述

注意,两者需要的数据不一样,web是需要第三方标识,下载安装插件到电脑,要配置海康数据。h5是视频流,只需传接口返回的流地址

1.视频web插件

在这里插入图片描述

ps: 逆天插件,层级非常高,打开弹窗都会被挡住,需要做限制

vue2写法,公共vue文件写法,调用文件即可

开始时需要以下配置,不知道的找对接平台数据的人,必须要,否则播不了

<code>getParameterData: {

port: 443,

ip: "10.10.2.22",

appKey: "20224202",

appSecret: "ndqXXXXXt1jHY2r8Uy",

enableHTTPS: 1,

}, //海康数据

// 注意版本不一样,加载插件的声明不一样,下面vue3的是最新的,声明实例new WebControl切换下

<!-- 海康插件组件 -->

<template>

<div class="video-center" ref="videoCenter">code>

<div :id="playWnd" class="playWnd"></div>code>

</div>

</template>

<script>

const control = require("../video/jsWebControl-1.0.0.min.js");

const jsencrypt = require("../video/jsencrypt.min.js");

export default { -- -->

data() {

return {

oWebControl: null,

pubKey: "",

initCount: 0,

w: 0,

h: 0,

winId: 1,

};

},

props: {

playWnd: {

type: String,

default: 'playWnd',

},

//播放类型 0预览 1回放

playMode: {

type: Number,

default: 0,

},

//初始化数据

initData: {

type: Object,

default() {

return {

enableHttps: 1,

encryptedFields: "secret",

layout: "1x1",

btIds: "0,16,256,257,258,259,260,512,513,514,515,516,517,768,769",

showSmart: 1,

showToolbar: 1,

snapDir: "D:\\SnapDir",

videoDir: "D:\\VideoDir",

};

},

},

},

created: function () {

this.initPlugin();

},

mounted: function () {

this.$nextTick(()=>{

this.h = this.$refs["videoCenter"].clientHeight;

this.w = this.$refs["videoCenter"].clientWidth;

})

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

if (this.$refs["videoCenter"]) {

this.h = this.$refs["videoCenter"].clientHeight;

this.w = this.$refs["videoCenter"].clientWidth;

this.resetFun();

}

});

},

computed: { },

methods: {

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

setWndCover() {

var iWidth = window.width;

var iHeight = window.height;

var oDivRect = document

.querySelector("#"+this.playWnd)

.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 > this.w ? this.w : iCoverLeft;

iCoverTop = iCoverTop > this.h ? this.h : iCoverTop;

iCoverRight = iCoverRight > this.w ? this.w : iCoverRight;

iCoverBottom = iCoverBottom > this.h ? this.h : iCoverBottom;

this.oWebControl.JS_RepairPartWindow(0, 0, this.w + 1, this.h); // 多1个像素点防止还原后边界缺失一个像素条

if (iCoverLeft != 0) {

this.oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, this.h);

}

if (iCoverTop != 0) {

this.oWebControl.JS_CuttingPartWindow(

0,

0,

this.w + 1,

iCoverTop

); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条

}

if (iCoverRight != 0) {

this.oWebControl.JS_CuttingPartWindow(

this.w - iCoverRight,

0,

iCoverRight,

this.h

);

}

if (iCoverBottom != 0) {

this.oWebControl.JS_CuttingPartWindow(

0,

this.h - iCoverBottom,

this.w,

iCoverBottom

);

}

},

// 初始化

init() {

this.getPubKey(() => {

let { appSecret, ...hkData } = this.$store.state.getParameterData;//海康提供的认证信息

this.oWebControl.JS_RequestInterface({

funcName: "init",

argument: JSON.stringify({

appkey: hkData.appKey, //API网关提供的appkey

secret: this.setEncrypt(appSecret), //API网关提供的secret

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

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

port: hkData.port, //端口

snapDir: this.initData.snapDir, //抓图存储路径

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

layout: this.initData.layout, //布局

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

encryptedFields: this.initData.encryptedFields, //加密字段

showToolbar: this.initData.showToolbar, //是否显示工具栏

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

})

}).then((oData) => {

// 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题

this.oWebControl.JS_Resize(this.w, this.h);

});

});

},

/* 视频预览业务功能 */

startPreviewFun(val) {

this.oWebControl.JS_RequestInterface({

funcName: "startPreview",

argument: JSON.stringify({

cameraIndexCode: val,

streamMode: 0,

transMode: 1,

gpuMode: 0,

wndId: this.winId,

}),

}).then((oData) => {

console.log('播放成功',oData)

});

},

/* 视频回放业务功能 */

startPlaybackFun(val, start, end, streamMode = 1) {

this.oWebControl.JS_RequestInterface({

funcName: "startPlayback",

argument: JSON.stringify({

cameraIndexCode: val, //监控点编号

startTimeStamp: start, //录像查询开始时间戳,单位:秒

endTimeStamp: end, //录像结束开始时间戳,单位:秒

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

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

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

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

wndId: this.wndId //可指定播放窗口

})

}).then((oData) => {

console.log('回放',oData)

});

},

// RSA加密

setEncrypt(value) {

var encrypt = new jsencrypt.JSEncrypt();

encrypt.setPublicKey(this.pubKey);

return encrypt.encrypt(value);

},

// 推送消息

cbIntegrationCallBack(oData) {

// 窗口选中

if (oData.responseMsg.type === 1) {

this.winId = oData.responseMsg.msg.wndId

}

},

// 设置窗口控制回调

setCallbacks() {

this.oWebControl.JS_SetWindowControlCallback({

cbIntegrationCallBack: this.cbIntegrationCallBack,

});

},

/* 获取公钥 */

getPubKey(callback) {

this.oWebControl.JS_RequestInterface({

funcName: "getRSAPubKey",

argument: JSON.stringify({

keyLength: 1024,

}),

}).then((oData) => {

if (oData.responseMsg.data) {

this.pubKey = oData.responseMsg.data;

callback();

}

});

},

// 加载插件

initPlugin() {

let _this = this;

this.oWebControl = new control.WebControl({

szPluginContainer: this.playWnd,

iServicePortStart: 15900,

iServicePortEnd: 15909,

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

cbConnectSuccess: function () {

_this.setCallbacks();

_this.oWebControl

.JS_StartService("window", { dllPath: "./VideoPluginConnect.dll"}).then(() => {

_this.oWebControl.JS_CreateWnd(_this.playWnd, _this.w, _this.h).then(() => {

_this.init();

});

},

function () { }

);

},

cbConnectError: function () {

_this.oWebControl = null;

initCount ++;

if (initCount < 3) {

setTimeout(function () {

initPlugin();

}, 3000)

} else {

console.log('插件启动失败,请检查插件是否安装!')

}

},

cbConnectClose: function (bNormalClose) {

console.log("cbConnectClose");

_this.oWebControl = null;

},

});

},

// 重置窗口大小

resetFun() {

if (this.oWebControl != null) {

this.oWebControl.JS_Resize(this.w, this.h);

this.setWndCover();

}

},

},

destroyed() {

this.oWebControl.JS_HideWnd();

this.oWebControl.JS_DestroyWnd().then(

function () {

console.log("销毁插件窗口成功");

},

function () {

console.log("销毁插件窗口失败");

}

);

},

};

</script>

<style scoped="scoped">code>

.video-center { -- -->

width: 100%;

height: 100%;

}

</style>

不完整,自行补充

<template>

<PreviewVideo

ref="webVideo"code>

:playMode="0"code>

:initData="initData"code>

/>

</template>

<script>

export default { -- -->

data() {

return {

initData: {

enableHttps: 0,

encryptedFields: "secret",

layout: "2x2", // 4个窗口

showSmart: 1,

showToolbar: 1,

snapDir: "D:SnapDir",

videoDir: "D:VideoDir",

},

}

},

method () {

//播放时调用

videoPlayFun() {

//预览

//第三方标识,由海康提供,后端传回

this.$refs['webVideo'].startPreviewFun(data.deviceNameEn)

//回放,需要回放时间,若使用element的时间戳,需要/1000,变为秒单位

//playMode传1

this.$refs['webVideo'].startPlaybackFun(

data.deviceNameEn,

startTime,

endTime

)

}

}

}

</script>

vue3+vite

使用版本

在这里插入图片描述

index文件引入

在这里插入图片描述

playVideo传第三方标识,请自行修改以下变量值如上

可直接复制使用vue,点击播放

能直接使用,测试如下,可测试第三方标识能否使用

在这里插入图片描述

<code><template>

<div class="video-center" ref="videoCenter">code>

<div @click="playVideo('1005ede4f95a4447897b8fd1fa8cd6f7', 1)">"1005ede4f95a4447897b8fd1fa8cd6f7"</div>code>

<div @click="playVideo('933d67747cb248ba93e0a65b5ac751ac', 2)">"933d67747cb248ba93e0a65b5ac751ac"</div>code>

<div @click="playVideo('e77fa1c7d9f04c9b893a74d441d5a53b', 3)">"e77fa1c7d9f04c9b893a74d441d5a53b"</div>code>

<div id="playWnd" class="playWnd"></div>code>

</div>

</template>

<script setup lang="ts">code>

import { -- --> onMounted, ref, reactive, unref } from 'vue'

var initCount = 0;

var oWebControl = null

var pubKey = '';

// 创建播放实例

const initPlugin = () => {

oWebControl = new WebControl({

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

iServicePortStart: 15900, // 指定起止端口号,建议使用该值

iServicePortEnd: 15900,

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

cbConnectSuccess: function () { // 创建WebControl实例成功

oWebControl.JS_StartService("window", { // WebControl实例创建成功后需要启动服务

dllPath: "./VideoPluginConnect.dll" // 值"./VideoPluginConnect.dll"写死

}).then(function () { // 启动插件服务成功

oWebControl.JS_SetWindowControlCallback({ // 设置消息回调

cbIntegrationCallBack: cbIntegrationCallBack

});

oWebControl.JS_CreateWnd("playWnd", 1000, 600).then(function () { //JS_CreateWnd创建视频播放窗口,宽高可设定

init(); // 创建播放实例成功后初始化

});

}, function () { // 启动插件服务失败

});

},

cbConnectError: function () { // 创建WebControl实例失败

oWebControl = null;

WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数,采用wakeup来启动程序

initCount ++;

if (initCount < 3) {

setTimeout(function () {

initPlugin();

}, 3000)

} else {

console.log('插件启动失败,请检查插件是否安装!')

// $("#playWnd").html("插件启动失败,请检查插件是否安装!");

}

},

cbConnectClose: function (bNormalClose) {

// 异常断开:bNormalClose = false

// JS_Disconnect正常断开:bNormalClose = true

console.log("cbConnectClose");

oWebControl = null;

console.log('插件未启动,正在尝试启动,请稍候...')

// $("#playWnd").html("插件未启动,正在尝试启动,请稍候...");

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

initCount ++;

if (initCount < 3) {

setTimeout(function () {

initPlugin();

}, 3000)

} else {

console.log('插件启动失败,请检查插件是否安装!')

// $("#playWnd").html("插件启动失败,请检查插件是否安装!");

}

}

});

}

// 推送消息

const cbIntegrationCallBack = (oData) => {

console.log(JSON.stringify(oData.responseMsg))

}

const init = () =>

{

getPubKey(function () {

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

var appkey = "20224202"; //综合安防管理平台提供的appkey,必填

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

var ip = "10.10.11.12"; //综合安防管理平台IP地址,必填

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

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

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

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

var layout = "2x2"; //playMode指定模式的布局

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

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

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

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

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

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

oWebControl.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 //自定义工具条按钮

})

}).then(function (oData) {

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

});

});

}

//获取公钥

const getPubKey = (callback) => {

oWebControl.JS_RequestInterface({

funcName: "getRSAPubKey",

argument: JSON.stringify({

keyLength: 1024

})

}).then(function (oData) {

console.log(oData);

if (oData.responseMsg.data) {

pubKey = oData.responseMsg.data;

callback()

}

})

}

//RSA加密

const setEncrypt = (value) => {

var encrypt = new JSEncrypt();

encrypt.setPublicKey(pubKey);

return encrypt.encrypt(value);

}

onMounted(() => {

initPlugin()

window.addEventListener('unload', () => {

if (oWebControl != null){

oWebControl.JS_HideWnd();

}

})

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

if (oWebControl != null) {

oWebControl.JS_Resize(1000, 600);

setWndCover();

}

})

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

if (oWebControl != null) {

oWebControl.JS_Resize(1000, 600);

setWndCover();

}

})

})

const setWndCover = () => {

var iWidth = window.innerWidth;

var iHeight = window.innerHeight;

var oDivRect = document.querySelector("#playWnd").getBoundingClientRect();

console.log('oDivRect', oDivRect)

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 > 1000) ? 1000 : iCoverLeft;

iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;

iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;

iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;

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

if (iCoverLeft != 0) {

oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);

}

if (iCoverTop != 0) {

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

}

if (iCoverRight != 0) {

oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);

}

if (iCoverBottom != 0) {

oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);

}

}

const playVideo = (val:string, i) => {

oWebControl.JS_RequestInterface({

funcName: "startPreview",

argument: JSON.stringify({

cameraIndexCode:val, //监控点编号

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

transMode: 1, //传输协议

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

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

})

})

}

</script>

<style>

.playWnd {

width: 1000px; /*播放容器的宽和高设定*/

height: 600px;

border: 1px solid red;

}

</style>

2.H5视频播放器

vue3写法,将下载的文件复制到public下

在index.html 引入

<script src="/js/h5player.min.js"></script>code>

在这里插入图片描述

<code><!-- 海康插件 -->

<template>

<div :id="props.playId" class="w-full"></div>code>

</template>

<script setup lang="ts">code>

const message = useMessage() // 消息弹窗

const props = defineProps({ -- -->

playId: {

require: true,

type: String,

default: () => {

return 'player'

}

}

})

const player = ref()

onMounted(() => {

initPlayer()

// 设置播放容器的宽高并监听窗口大小变化

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

player.value.JS_Resize()

})

})

const emit = defineEmits(['error'])

const initPlayer = () => {

// @ts-ignore

player.value = new JSPlugin({

szId: props.playId,

szBasePath: '/js', //public下命名的文件名

bSupporDoubleClickFull: true,

// 当容器div#play_window有固定宽高时,可不传iWidth和iHeight,窗口大小将自适应容器宽高

// iWidth: props.iWidth,

// iHeight: props.iHeight,

// 分屏播放,默认最大分屏4*4

iMaxSplit: 4,

iCurrentSplit: 1

})

// 事件回调绑定

player.value.JS_SetWindowControlCallback({

//插件选中窗口回调

windowEventSelect: (iWndIndex) => {

console.log('windowSelect callback: ', iWndIndex)

wndIndex.value = iWndIndex

},

// @ts-ignore 取流失败,流中断等错误都会触发该回调函数

pluginErrorHandler: (index, iErrorCode, oError) => {

// 取流失败

if (iErrorCode === '0x12f910011') emit('error')

}

})

}

const wndIndex = ref(0)

const createPlayer = (url: string, i = wndIndex.value) => {

console.log('视频流地址:', url, props.playId)

if (!url) return

player.value.JS_Play(url, { playURL: url, mode: 0 }, i).then(

() => {

console.log('play success=============')

},

(err) => {

// message.warning('播放失败!')

console.info('JS_Play failed:', err)

}

)

}

// 分屏

const splitPlayer = (num) => {

if (num === 1) wndIndex.value = 0

player.value.JS_ArrangeWindow(num)

}

// 全屏

const fullScreen = (isFull) => {

player.value.JS_FullScreenDisplay(isFull)

}

// 回放

const replayFun = (data) => {

player.value

.JS_Play(data.url, { playURL: data.url, mode: 0 }, 0, data.startTime, data.endTime)

.then(

() => {

console.log('playbackStart success')

},

(err) => {

console.info('JS_Play failed:', err)

}

)

}

// 设置窗口大小

const resizeFun = (iWidth, iHeight) => {

player.value.JS_Resize(iWidth, iHeight)

}

const stopAllPlay = () => {

player.value.JS_StopRealPlayAll().then(() => {

console.info('JS_StopRealPlayAll success')

})

}

const playerFun = {

createPlayer,

splitPlayer,

fullScreen,

replayFun,

resizeFun,

stopAllPlay

}

defineExpose({ playerFun })

</script>

不完整,自行补充

上传了代码,可以参考下,在hkvideo.vue文件下

测试代码地址

<player class="w-full h-400px" ref="playRef" />code>

在这里插入图片描述

这是我本地的地址,需要后端返回类似的

ws和hls都试过可以播放,ws基本没延迟,优先使用

<code> unref(playRef).playerFun.createPlayer(item, index)

回放时间格式要转为 format('YYYY-MM-DDTHH:mm:ss.SSSZ')

unref(playRef).playerFun.replayFun({ ... })



声明

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