实现结果:
主要实现海康视频实时预览、云台控制、画面放大、缩小、截图
一、环境准备
1.1 官网下载开发包
官网链接:海康开放平台
1.2 demo查看 下载WebSDK_V3.3.0(231027)
先配置基本信息 再点击登录–开始预览 进行查看视频
二、代码引入
在/public中引入图片上三个文件 并在index.html中引用
方法封装:
import { uploadSnap } from '/@/api/deviceManager/videoList';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { Action } from 'element-plus';
// 初始化插件
// 全局保存当前选中窗口
var g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
var g_oLocalConfig = null; //本地配置
//错误码
//通用错误
var ERROR_CODE_UNKNOWN = 1000; //未知错误
var ERROR_CODE_NETWORKERROR = 1001; //网络错误
var ERROR_CODE_PARAMERROR = 1002; //缺少插件元素
//登录模块
var ERROR_CODE_LOGIN_NOLOGIN = 2000; // 未登录
var ERROR_CODE_LOGIN_REPEATLOGIN = 2001; //设备已登录,重复登录
var ERROR_CODE_LOGIN_NOSUPPORT = 2002; //当前设备不支持Digest登录
//预览播放
var ERROR_CODE_PLAY_PLUGININITFAIL = 3000; //插件初始化失败
var ERROR_CODE_PLAY_NOREPEATPLAY = 3001; //当前窗口已经在预览
var ERROR_CODE_PLAY_PLAYBACKABNORMAL = 3002; //回放异常
var ERROR_CODE_PLAY_PLAYBACKSTOP = 3003; //回放停止
var ERROR_CODE_PLAY_NOFREESPACE = 3004; //录像过程中,硬盘容量不足
//对讲
var ERROR_CODE_TALK_FAIL = 5000; //语音对讲失败
var version = 'V3.3.0build20230322';
var szDeviceIdentify = '';
export const videoFn = {
// 插件播放初始化
init(data) {
// 初始化插件参数及插入插件
WebVideoCtrl.I_InitPlugin({
bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
iWndowType: 1,
// 是窗口选中事件的回调函数,用户可以传入函数,选中窗口后,开发包会自动调用这个函数,参数是一个 XML,
cbSelWnd: function (xmlDoc) {
g_iWndIndex = parseInt($(xmlDoc).find('SelectWnd').eq(0).text(), 10);
},
cbDoubleClickWnd: function (iWndIndex, bFullScreen) {
var szInfo = '当前放大的窗口编号:' + iWndIndex;
if (!bFullScreen) {
szInfo = '当前还原的窗口编号:' + iWndIndex;
}
},
// 插件的异常事件回调函数,有两个参数,第一个参数是事件类型(具体值在异常事件回调中有说明),第二个是触发事件的窗口号。
cbEvent: function (iEventType, iParam1, iParam2) {
if (2 == iEventType) {
// 回放正常结束
} else if (-1 == iEventType) {
} else if (3001 == iEventType) {
// clickStopRecord(g_szRecordType, iParam1);
}
},
cbInitPluginComplete: function () {
let that = this;
WebVideoCtrl.I_InsertOBJECTPlugin(data.id).then(
() => {
videoFn.clickLogin(data);
},
() => {
ElMessageBox.confirm('插件初始化失败,请确认是否已安装插件;如果未安装,请先下载插件后进行安装!', {
confirmButtonText: '下载',
cancelButtonText: '取消',
})
.then(() => {
window.open('https://zjsos.net:7058/api/admin/sys-file/download/HCWebSDKPlugin.zip');
})
.catch(() => {
// catch error
});
}
);
},
});
// 窗口事件绑定
$(window).bind({
resize: function () {
//WebVideoCtrl.I_Resize($("body").width(), $("body").height());
},
});
},
// 登录
clickLogin(data: any) {
var szIP = data.ip,
szPort = data.port,
szUsername = data.username,
szPassword = data.password;
if ('' == szIP || '' == szPort) {
return;
}
szDeviceIdentify = szIP + '_' + szPort;
WebVideoCtrl.I_Login(szIP, 1, szPort, szUsername, szPassword, {
timeout: 3000,
success: function (xmlDoc) {
setTimeout(function () {
setTimeout(function () {
videoFn.getChannelInfo();
}, 1000);
videoFn.getDevicePort();
}, 10);
},
error: function (oError) {
if (ERROR_CODE_LOGIN_REPEATLOGIN == status) {
} else {
}
},
});
},
// 获取通道
getChannelInfo() {
// 模拟通道
WebVideoCtrl.I_GetAnalogChannelInfo(szDeviceIdentify, {
success: function (xmlDoc) {
videoFn.clickStartRealPlay();
},
error: function (oError) {},
});
},
// 获取端口
getDevicePort() {
WebVideoCtrl.I_GetDevicePort(szDeviceIdentify).then(
(oPort) => {},
(oError) => {
var szInfo = '获取端口失败!';
}
);
},
// 开始预览
clickStartRealPlay(iStreamType?: any) {
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex),
iChannelID = '1',
bZeroChannel = false,
szInfo = '';
if ('undefined' === typeof iStreamType) {
// 码流类型 默认主码流
iStreamType = 1;
}
if (null == szDeviceIdentify) {
return;
}
var startRealPlay = function () {
WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
iStreamType: iStreamType,
iChannelID: iChannelID,
bZeroChannel: bZeroChannel,
success: function () {
szInfo = '开始预览成功!';
},
error: function (oError) {},
});
};
if (oWndInfo != null) {
// 已经在播放了,先停止
WebVideoCtrl.I_Stop({
success: function () {
startRealPlay();
},
});
} else {
startRealPlay();
}
},
// PTZ控制 9为自动,1,2,3,4,5,6,7,8为方向PTZ
mouseDownPTZControl(iPTZIndex) {
var g_bPTZAuto = false;
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex),
bZeroChannel = false,
// 云台速度
iPTZSpeed = 4;
if (bZeroChannel) {
// 零通道不支持云台
return;
}
if (oWndInfo != null) {
if (9 == iPTZIndex && g_bPTZAuto) {
iPTZSpeed = 0; // 自动开启后,速度置为0可以关闭自动
} else {
g_bPTZAuto = false; // 点击其他方向,自动肯定会被关闭
}
WebVideoCtrl.I_PTZControl(iPTZIndex, false, {
iPTZSpeed: iPTZSpeed,
success: function (xmlDoc) {
if (9 == iPTZIndex && g_bPTZAuto) {
} else {
}
if (9 == iPTZIndex) {
g_bPTZAuto = !g_bPTZAuto;
}
},
error: function (oError) {},
});
}
},
// 方向PTZ停止
mouseUpPTZControl() {
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex);
if (oWndInfo != null) {
WebVideoCtrl.I_PTZControl(1, true, {
success: function (xmlDoc) {},
error: function (oError) {},
});
}
},
PTZZoomIn() {
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex);
if (oWndInfo != null) {
WebVideoCtrl.I_PTZControl(10, false, {
iWndIndex: g_iWndIndex,
success: function (xmlDoc) {},
error: function (oError) {},
});
}
},
PTZZoomout() {
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex);
if (oWndInfo != null) {
WebVideoCtrl.I_PTZControl(11, false, {
iWndIndex: g_iWndIndex,
success: function (xmlDoc) {},
error: function (oError) {},
});
}
},
PTZZoomStop() {
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex);
if (oWndInfo != null) {
WebVideoCtrl.I_PTZControl(11, true, {
iWndIndex: g_iWndIndex,
success: function (xmlDoc) {},
error: function (oError) {},
});
}
},
// 抓图
async clickCapturePic(szType) {
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex),
szInfo = '';
if (oWndInfo != null) {
var oLocalConfig = await WebVideoCtrl.I_GetLocalCfg();
var szCaptureFileFormat = '0';
if (oLocalConfig) {
szCaptureFileFormat = oLocalConfig.captureFileFormat;
}
console.log(oLocalConfig, szCaptureFileFormat);
var szChannelID = 1;
var szPicName = oWndInfo.szDeviceIdentify + '_' + szChannelID + '_' + new Date().getTime();
//如果是回放抓图,需要增加如下前缀:"playback_"
if ('playback' === szType) {
szPicName = 'playback_' + oWndInfo.szDeviceIdentify + '_' + szChannelID + '_' + new Date().getTime();
}
szPicName += '0' === szCaptureFileFormat ? '.jpg' : '.bmp';
WebVideoCtrl.I_CapturePic(szPicName, {
bDateDir: true, //是否生成日期文件
}).then(
function () {
szInfo = '抓图成功!';
// showOPInfo(oWndInfo.szDeviceIdentify + " " + szInfo);
},
function (oError) {
szInfo = ' 抓图失败!';
// showOPInfo(oWndInfo.szDeviceIdentify + szInfo, oError.errorCode, oError.errorMsg);
}
);
}
},
clickCapturePicData() {
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex),
szInfo = '';
if (oWndInfo != null) {
WebVideoCtrl.I_CapturePicData().then(
function (data) {
const base64 = videoFn.base64toBlob(data);
console.log(base64, 'base64');
videoFn.uploadImage(base64);
szInfo = 'base64';
},
function () {
szInfo = '抓图失败!';
}
);
}
},
base64toBlob(base64, type = 'application/octet-stream') {
const bstr = atob(base64);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type });
},
// 上传图片到服务器
async uploadImage(base64Image) {
if (base64Image) {
try {
// 创建FormData对象
const formData = new FormData();
formData.append('file', base64Image, 'image.png'); // 假设服务器接收的字段是'image'
formData.append('deviceNum', '11'); // 假设服务器接收的字段是'image'
console.log(formData, 'formData');
// 发送请求到服务器
await uploadSnap(formData).then((res) => {});
// if (response.ok) {
// console.log('图片上传成功');
// } else {
// console.error('图片上传失败');
// }
} catch (error) {
console.error('图片上传异常:', error);
}
}
},
// 停止预览
clickStopRealPlay() {
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex),
szInfo = '';
if (oWndInfo != null) {
WebVideoCtrl.I_Stop({
success: function () {
szInfo = '停止预览成功!';
},
error: function (oError) {},
});
}
},
// 退出
clickLogout() {
if (null == szDeviceIdentify) {
return;
}
WebVideoCtrl.I_DestroyPlugin(szDeviceIdentify).then(
() => {},
() => {}
);
WebVideoCtrl.I_Logout(szDeviceIdentify).then(
() => {
// showOPInfo(szDeviceIdentify + " " + "退出成功!");
},
() => {
// showOPInfo(szDeviceIdentify + " " + "退出失败!");
}
);
},
};
关闭弹窗时要调用停止预览和退出登录的方法(videoFn.clickStopRealPlay();videoFn.clickLogout())