uni-app + Vue3 开发H5 页面播放海康ws(Websocket协议)的视频流

发布于:2025-08-30 ⋅ 阅读:(21) ⋅ 点赞:(0)

一、准备工作

1、海康开放平台H5视频播放器开发包下载

海康开放平台

先注册/登录,然后下载开发包

二、播放视频流

1、引入下载的开发包

在项目中创建文件夹 /static/js/Hk,将下载好的开发包解压放到 Hk 文件夹中,

2、引入

在 index.html 文件中引入

<script src="/static/js/HK/h5player.min.js"></script>

如下图:

3、使用

第一步:// 动态加载 h5player.min.js

// 动态加载 h5player.min.js
function loadh5player() {
	return new Promise((resolve, reject) => {
		if (typeof JSPlugin !== "function") {
			resolve();
			return;
		}
		const script = document.createElement("script");
		script.src = "/static/js/Hk/h5player.min.js";
		script.onload = resolve;
		script.onerror = reject;
		document.head.appendChild(script);
	});
}	

第二步:初始化播放窗口

// 初始化播放窗口
playersH5.value = new JSPlugin({
	szId: "player", //需要英文字母开头 必填
	szBasePath: "/static/js/Hk/h5player.min.js", // 必填,引用H5player.min.js的js相对路径
	oStyle: {
		border: "none",
		borderSelect: "none",
		background: "#000",
	}
})

第二步:播放

function playVideo() {
		playersH5.value.JS_Play(playerUrl.value, 1);
		
		// 事件初始化
		playersH5.value.JS_SetWindowControlCallback({
			windowEventSelect: function(iWndIndex) { //插件选中窗口回调
				console.log('windowSelect callback: ', iWndIndex);
			},
			pluginErrorHandler: function(iWndIndex, iErrorCode, oError) { //插件错误回调
				console.log('pluginError callback: ', iWndIndex, iErrorCode, oError);
			},
			windowEventOver: function(iWndIndex) { //鼠标移过回调
				console.log(iWndIndex);
			},
			windowEventOut: function(iWndIndex) { //鼠标移出回调
				console.log(iWndIndex);
			},
			windowEventUp: function(iWndIndex) { //鼠标mouseup事件回调
				console.log(iWndIndex);
			},
			windowFullCcreenChange: function(bFull) { //全屏切换回调
				console.log('fullScreen callback: ', bFull);
			},
			firstFrameDisplay: function(iWndIndex, iWidth, iHeight) { //首帧显示回调
				console.log('firstFrame loaded callback: ', iWndIndex, iWidth, iHeight);
			},
			performanceLack: function(iWndIndex) { //性能不足回调
				console.log('performanceLack callback: ', iWndIndex);
			},
			StreamEnd: function(iWndIndex) { //性能不足回调
				console.log('recv StreamEnd: ', iWndIndex);
			},
			StreamHeadChanged: function(iWndIndex) {
				console.log('recv StreamHeadChanged: ', iWndIndex);
			},
			ThumbnailsEvent: (iWndIndex, eventType, eventCode) => {
				console.log('recv ThumbnailsEvent: ' + iWndIndex + ", eventType:" + eventType + ", eventCode:" +
					eventCode);
			},
			InterruptStream: (iWndIndex, iTime) => {
				console.log('recv InterruptStream: ' + iWndIndex + ", iTime:" + iTime);
			},
			ElementChanged: (iWndIndex, szElementType) => { //回调采用的是video还是canvas 
				console.log('recv ElementChanged: ' + iWndIndex + ", szElementType:" + szElementType);
			},
		});
	}

三、完整代码

父组件:点击方法跳转到视频播放组件页面

function openVideoPlayBack(item) {
	uni.navigateTo({
		url: `/pages/videoPlayback/videoPlayback?url=${item.url}`
	})
}

子组件videoPlayback.vue:视频播放组件

<template>
	<view class="container">
		<view class="box" id='player' :style="{'height':heightInfo + 'px'}" :info='playerUrl' :stop='stopPlay'>
		</view>
		<view class="tipName">
			双击全屏展示
		</view>
	</view>
</template>

<script setup>
	import {
		ref
	} from "vue";
	import {
		onLoad
	} from "@dcloudio/uni-app"
	// 接收页面跳转的传参
	onLoad((e) => {
		let {
			url = null
		} = e;
		initPlayers(url)
	})
	let playersH5 = ref({}); // 存储播放器实例
	let heightInfo = ref();
	//销毁播放窗口状态
	let stopPlay = ref(false);
	let playerUrl = ref({})
	// 初始化播放器
	async function initPlayers(url) {
		try {
			playerUrl.value = url;
			const systemInfo = uni.getSystemInfoSync(); // 获取系统信息
			heightInfo.value = (systemInfo.windowHeight)/2;
			await loadh5player();
			playersH5.value = new JSPlugin({
				szId: "player", //需要英文字母开头 必填
				szBasePath: "/static/js/Hk/h5player.min.js", // 必填,引用H5player.min.js的js相对路径
				oStyle: {
					border: "none",
					borderSelect: "none",
					background: "#000",
				}
			})
			setTimeout(() => {
				playVideo()
			}, 500)

		} catch (error) {
			console.error("Failed to initialize JSPlugin:", error);
		}
	}

	function playVideo() {
		playersH5.value.JS_Play(playerUrl.value, 1);
		
		// 事件回调绑定
		playersH5.value.JS_SetWindowControlCallback({
			windowEventSelect: function(iWndIndex) { //插件选中窗口回调
				console.log('windowSelect callback: ', iWndIndex);
			},
			pluginErrorHandler: function(iWndIndex, iErrorCode, oError) { //插件错误回调
				console.log('pluginError callback: ', iWndIndex, iErrorCode, oError);
			},
			windowEventOver: function(iWndIndex) { //鼠标移过回调
				console.log(iWndIndex);
			},
			windowEventOut: function(iWndIndex) { //鼠标移出回调
				console.log(iWndIndex);
			},
			windowEventUp: function(iWndIndex) { //鼠标mouseup事件回调
				console.log(iWndIndex);
			},
			windowFullCcreenChange: function(bFull) { //全屏切换回调
				console.log('fullScreen callback: ', bFull);
			},
			firstFrameDisplay: function(iWndIndex, iWidth, iHeight) { //首帧显示回调
				console.log('firstFrame loaded callback: ', iWndIndex, iWidth, iHeight);
			},
			performanceLack: function(iWndIndex) { //性能不足回调
				console.log('performanceLack callback: ', iWndIndex);
			},
			StreamEnd: function(iWndIndex) { //性能不足回调
				console.log('recv StreamEnd: ', iWndIndex);
			},
			StreamHeadChanged: function(iWndIndex) {
				console.log('recv StreamHeadChanged: ', iWndIndex);
			},
			ThumbnailsEvent: (iWndIndex, eventType, eventCode) => {
				console.log('recv ThumbnailsEvent: ' + iWndIndex + ", eventType:" + eventType + ", eventCode:" +
					eventCode);
			},
			InterruptStream: (iWndIndex, iTime) => {
				console.log('recv InterruptStream: ' + iWndIndex + ", iTime:" + iTime);
			},
			ElementChanged: (iWndIndex, szElementType) => { //回调采用的是video还是canvas 
				console.log('recv ElementChanged: ' + iWndIndex + ", szElementType:" + szElementType);
			},
		});
	}
	
	// 动态加载 h5player.min.js
	function loadh5player() {
		return new Promise((resolve, reject) => {
			if (typeof JSPlugin !== "function") {
				resolve();
				return;
			}
			const script = document.createElement("script");
			script.src = "/static/js/Hk/h5player.min.js";
			script.onload = resolve;
			script.onerror = reject;
			document.head.appendChild(script);
		});
	}
</script>

<style lang="scss" scoped>
	.container {
		width: 100%;
		height: 600px;
		display: flex;
		justify-content: center;
		align-items: center;
		flex-direction: column;+
		// padding-top: 44px;
	
		.video-container {
			width: 100%;
		}
		.tipName {
			margin-top: 10px;
			color: #3709ee;
		}
	}
</style>