自行下载
海康开放平台
demo 都写得很清楚,不多描述
1.视频web插件
vue2写法,公共vue文件写法,调用文件即可
开始时需要以下配置,不知道的找对接平台数据的人,必须要,否则播不了
getParameterData: {
port: 443,
ip: "10.10.1.12",
appKey: "20294202",
appSecret: "ndqCAFyke4t1jHY2r8Uy",
enableHTTPS: 1,
}, //海康数据
<!-- 海康插件组件 -->
<template>
<div class="video-center" ref="videoCenter">
<div :id="playWnd" class="playWnd"></div>
</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,
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">
.video-center {
width: 100%;
height: 100%;
}
</style>
不完整,自行补充
<template>
<PreviewVideo
ref="webVideo"
:playMode="0"
:initData="initData"
/>
</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
playVideo传第三方标识,请自行修改以下变量值如上
可直接复制使用vue,点击播放
能直接使用,测试如下,可测试第三方标识能否使用
<template>
<div class="video-center" ref="videoCenter">
<div @click="playVideo('1005ede4f95a4447897b8fd1fa8cd6f7', 1)">"1005ede4f95a4447897b8fd1fa8cd6f7"</div>
<div @click="playVideo('933d67747cb248ba93e0a65b5ac751ac', 2)">"933d67747cb248ba93e0a65b5ac751ac"</div>
<div @click="playVideo('e77fa1c7d9f04c9b893a74d441d5a53b', 3)">"e77fa1c7d9f04c9b893a74d441d5a53b"</div>
<div id="playWnd" class="playWnd"></div>
</div>
</template>
<script setup lang="ts">
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 = "20294202"; //综合安防管理平台提供的appkey,必填
var secret = setEncrypt("ndqCAFyke4t1jHY2r8Uy"); //综合安防管理平台提供的secret,必填
var ip = "10.10.1.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>
<!-- 海康插件 -->
<template>
<div :id="props.playId" class="w-full"></div>
</template>
<script setup lang="ts">
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',
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>
不完整,自行补充
<player class="w-full h-400px" ref="playRef" />
这是我本地的地址,需要后端返回类似的
ws和hls都试过可以播放,ws基本没延迟,优先使用
unref(playRef).playerFun.createPlayer(item, index)
回放时间格式要转为 format('YYYY-MM-DDTHH:mm:ss.SSSZ')
unref(playRef).playerFun.replayFun({ ... })