vue/react使用h5player对接海康ws视频流实时播放,监控回放
前端对接海康ws实时视频流,回放基础使用
1.首先在海康开放平台下载这个官方demo
这里我用的是h5player开发
2.将插件引入项目
将下载的demo 文件放到项目的静态资源中,
找到官网下载好的demo点进去,将里边的文件复制到项目的public下,这里使用的是vue,如果是react也和项目位置是一样的
我这里是在public新建了一个lib文件夹放进去
3.然后在index.html进行插件的导入
4.封装海康组件方便使用
封装hkPlayer.js,注意szBasePath的路径,如果跟我一样可以直接cv
const IS_MOVE_DEVICE = document.body.clientWidth < 992;
const MSE_IS_SUPPORT = !!window.MediaSource; // 是否支持mse/*** 海康播放器* @param {*} domid 容器id*/
export default class HkPlayer {constructor(domid) {this.createPlayer(domid);}createPlayer(domid) {console.log('IS_MOVE_DEVICE', domid);const player = new window.JSPlugin({szId: domid,szBasePath: '/lib',iMaxSplit: 1,iCurrentSplit: IS_MOVE_DEVICE ? 1 : 2,openDebug: true,muted: true,// iWidth: 425,// iHeight: 350,mseWorkerEnable: false, //是否开启多线程解码,分辨率大于1080P建议开启,否则可能卡顿mseSupport: MSE_IS_SUPPORT,tabActive: MSE_IS_SUPPORT ? 'mse' : 'decoder',oStyle: {borderSelect: IS_MOVE_DEVICE ? '#000' : '#FFCC00'}});// 事件回调绑定player.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还是canvasconsole.log('recv ElementChanged: ' + iWndIndex + ', szElementType:' + szElementType);}});this.player = player;}// 实时播放startplay(url) {const playURL = url;const index = 1;this.player.JS_Play(playURL, { playURL, mode: 1 }, index).then((res) => {console.log('播放成功', res);},(e) => {console.error('播放失败', e);});}stopPlay() {this.player.JS_Stop().then(() => {console.log('stop realplay success');},(e) => {console.error(e);});}// 回放startBackPlay(url, startTime, endTime) {const index = 1;this.player.JS_Play(url,{playURL: url, // 流媒体播放时必传mode: 0, // 解码类型:0=普通模式; 1=高级模式 默认为0PlayBackMode: 1, //1:绝对时间正放; 3 绝对时间倒放 默认为1keepDecoder: 0 // 0:回收解码资源; 1:不回收解码资源。为1时相同的编码格式,通过直接调用js_play接口切换点位不黑屏。默认0// ...},index, //当前窗口下标// 回放参数startTime,endTime).then(() => {console.info('JS_Play success', startTime, endTime);// do you want...},(err) => {console.info('JS_Play failed:', err);// do you want...});}
}
5.对接实时视频和回放
这里使用的流为ws,不同的流传参不一样,具体的可以登录海康官网查看
注意:回放的传参跟实时的有点区别,还有时间格式为iso的,需要toISOString转一下
<template><div class="centeredVideo" :id="'videoElement'+ playitem.cameraCode" style="width: 100%;height: 100%;"></div>
</template><script>import { string } from 'vue-types';
import HkPlayer from '../utils/hkPlayer';
import { videoList, videoByCameraId, videoBack } from '@/api/tjh/video';
import moment from 'moment';export default {name: 'PlayVideoCom',props: {playitem: {type: Object,required: true},videoType: {type: String,default: () => 'real' // real: 实时视频,back: 回放视频},startTimeStamp: {type: Date,default: () => ''},endTimeStamp: {type: Date,default: () => ''}},data() {return {VideoEltype: [0, 6],HkPlayerObj: null}},watch: {playitem: {immediate: true,handler(newVal) {if (newVal) {console.log(newVal,this, 'newVal');this.$nextTick(() => {this.HKplayVideo();})}}}},beforeUnmount() {this.HKclosePlaying();},methods: {// 海康async HKplayVideo() {try {this.HkPlayerObj = new HkPlayer('videoElement'+this.playitem.cameraCode);if(this.videoType === 'real'){const res = await videoByCameraId(this.playitem.cameraCode);if (res.msg) {this.HkPlayerObj.startplay(res.msg);}}else {let data = {cameraId: this.playitem.cameraCode,beginTime: moment(this.startTimeStamp).format('YYYY-MM-DD HH:mm:ss'),endTime: moment(this.endTimeStamp).format('YYYY-MM-DD HH:mm:ss'),"recordLocation": "1","protocol": "ws"}const res = await videoBack(data);if (res.msg) {this.HkPlayerObj = new HkPlayer('videoElement' + this.playitem.cameraCode);}// let str = 'ws://169.16.10.7:559/openUrl/RRxMHQc?beginTime=20250817T000000&endTime=20250818T000000'this.HkPlayerObj.startBackPlay(res.msg, this.startTimeStamp.toISOString(), this.endTimeStamp.toISOString());}} catch (error) {console.error('Failed to play video:', error);}},HKclosePlaying() {if (this.HkPlayerObj) {console.log('关闭播放');this.HkPlayerObj.stopPlay(() => {});}}}
};
</script>