vue3:海康web3.3对接流程

2,127 阅读4分钟

实现结果:image.png 主要实现海康视频实时预览、云台控制、画面放大、缩小、截图

一、环境准备

1.1 官网下载开发包

官网链接:海康开放平台

image.png 1.2 demo查看 下载WebSDK_V3.3.0(231027)

image.png 先配置基本信息 再点击登录–开始预览 进行查看视频

image.png 二、代码引入

在/public中引入图片上三个文件 并在index.html中引用

image.png 方法封装:

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())