React的UmiJS搭建的项目集成海康威视h5player播放插件H5视频播放器开发包 V2.1.2

最近前端的一个项目,大屏需要摄像头播放,摄像头厂家是海康威视的,网上找了一圈都没有React集成的,特别是没有使用UmiJS搭脚手架搭建的,所以记录一下。

海康威视的开放平台的API地址,相关插件和文档都可以下载:

海康威视综合安防管理平台【海康开放平台】

 下载下来后,核心需要的包如下,其中xxx.wasm文件是官方使用C++编写的WebAssembly文件,是基于堆栈的虚拟机的二进制指令格式,一种低级汇编语言,旨在非常接近已编译的机器代码,并且非常接近本机性能。

 

其中集成的难点是在于官方开发包的引入,因为下载下来的demo是用HTML写的,直接可以在Head标签中导入,所以没什么问题,但UmiJS框架搭建的组件化项目直接就没有了HTML文件,所以得找到额外script脚本引入的地方,不同框架搭建的项目,建议去看官方文档。那里是最直接的说明书。UmiJS框架的引入最终在官方文档中找到了入口。配置

 找到之后在配置中引入即可,注意引用的路径,整个JS包是放在了public文件夹下。

 然后就可以引用了,直接上代码HFivePlayer.ts,其中用了AntD的部分组件,自己导入或更换

import {FC, useEffect, useState} from 'react'
import styles from './index.module.less'
import {message, Spin} from "antd";

/**
 * 海康视频H5插件视频播放
 * @author QC班长
 * @since 20230727
 */
interface IProps {
  wsUrl: string,//流媒体URL,支持ws协议
  playerID: string,//播放器实例ID
}

const HFivePlayer: FC<IProps> = ({wsUrl, playerID}) => {
  let player: any = {}// 播放器对象
  const [isLoading, setIsLoading] = useState<boolean>(false)
  /**
   * 初始化播放器
   */
  const initPlayer = () => {
    player = new window.JSPlugin({
      // 需要英文字母开头 必填
      szId: 'player' + playerID,
      // 必填,引用H5player.min.js的js相对路径
      szBasePath: '/js/h5player/',
      // 当容器div#play_window有固定宽高时,可不传iWidth和iHeight,窗口大小将自适应容器宽高
      iWidth: '100%',
      iHeight: '100%',
      // 分屏播放,默认最大分屏4*4
      // iMaxSplit: 16,
      // iCurrentSplit: 1,
      // 样式
      oStyle: {
        border: 'rgb(53 116 237)',
        borderSelect: '#1d325d',
        background: '#1d325d',
      }
    })
    // 设置播放容器的宽高并监听窗口大小变化
    window.addEventListener('resize', () => {
      setTimeout(() => {
        player.JS_Resize()
      }, 50)
    })
    //初始化插件
    initPlugin()
  }

  /**
   * 事件初始化
   */
  const initPlugin = () => {

    player.JS_SetWindowControlCallback({
      windowEventSelect(iWindIndex: any) {
        // 插件选中窗口回调
        // console.log('windowSelect callback: ', iWindIndex)
        //点击视频全屏显示
        wholeFullScreen()
      },
      pluginErrorHandler(iWindIndex: any, iErrorCode: any, oError: any) {
        // 插件错误回调
        // console.error(`window-${iWindIndex}, errorCode: ${iErrorCode}`, oError)
        message.error('播放失败:' + VideoPlayerException[iErrorCode])
        //重新播放
        // initPlayer()
      },
      windowEventOver(iWindIndex: any) {
        // 鼠标移过回调
        // console.log('鼠标移过回调', iWindIndex)
      },
      windowEventOut(iWindIndex: any) {
        // 鼠标移出回调
        // console.log('鼠标移出回调', iWindIndex)
      },
      windowFullScreenChange(bFull: any) {
        // 全屏切换回调
        // console.log('全屏切换回调', bFull)
      },
      firstFrameDisplay(iWndIndex: any, iWidth: any, iHeight: any) {
        // 首帧显示回调
        // console.log('首帧显示回调', iWndIndex, iWidth, iHeight)
        //停止加载
        setIsLoading(false)
      },
      performanceLack(iWndIndex: any) {
        // 性能不足回调
        console.log('性能不足回调', iWndIndex)
      }
    })
    //播放
    play()
  }

  /**
   * 播放
   */
  const play = () => {
    if (wsUrl != "" && wsUrl != null) {
      setIsLoading(true) //开始加载
      let preUrl = wsUrl  // 播放地址
      const param = {
        playURL: preUrl,
        // 1:高级模式  0:普通模式,高级模式支持所有
        mode: 0
      }
      // 当前播放窗口下标
      let index = 0
      player.JS_Play(preUrl, param, index).then(() => {
          // 播放成功回调
          // console.log('播放成功')
        }, (err: any) => {
          // console.log('播放失败')
          // console.info('JS_Play failed:', err)
          message.error('播放失败:' + VideoPlayerException[err])
        }
      )

    }
  }

  /**
   * 全屏
   */
  const wholeFullScreen = () => {
    player.JS_FullScreenDisplay(true).then(() => {
        // console.log(`wholeFullScreen success`)
      }, (e: any) => {
        console.error(e)
      }
    )
  }

  /**
   * 暂停
   */
  // const stopPlay = () => {
  //   player.JS_Stop().then(() => {
  //    console.log('stop realPlay success')
  //     }, (e: any) => {
  //       console.error(e)
  //     }
  //   )
  // }

  useEffect(() => {
    initPlayer()
  }, [])

  return (
    <div className={styles.video}>
      <Spin spinning={isLoading} tip='加载中...' wrapperClassName={styles.loading}>
        <div id={'player' + playerID} className={styles.player}/>
      </Spin>
    </div>
  )
}
export default HFivePlayer

/**
 * 海康威视视频播放异常错误代码常量
 */
export const VideoPlayerException = {
  '0x12f900001': '接口调用参数错误',
  '0x12f900002': '不在播放状态',
  '0x12f900003': '仅回放支持该功能',
  '0x12f900004': '普通模式不支持该功能',
  '0x12f900005': '高级模式不支持该功能',
  '0x12f900006': '高级模式的解码库加载失败',
  '0x12f900008': 'url格式错误',
  '0x12f900009': '取流超时错误',
  '0x12f900010': '设置或者是获取音量失败,因为没有开启音频的窗口',
  '0x12f900011': '设置的音量不在1-100范围',
  '0x12f910000': 'websocket连接失败,请检查网络是否通畅,URL是否正确',
  '0x12f910010': '取流失败',
  '0x12f910011': '流中断,电脑配置过低,程序卡主线程都可能导致流中断',
  '0x12f910014': '没有音频数据',
  '0x12f910015': '未找到对应websocket,取流套接字被动关闭的报错',
  '0x12f910016': 'websocket不在连接状态',
  '0x12f910017': '不支持智能信息展示',
  '0x12f910018': 'websocket长时间未收到message',
  '0x12f910019': 'wss连接失败,原因:端口尚未开通、证书未安装、证书不安全',
  '0x12f910020': '单帧回放时不能暂停',
  '0x12f910021': '已是最大倍速',
  '0x12f910022': '已是最小倍速',
  '0x12f910023': 'ws/wss连接超时,默认6s超时时间,原因:网络异常,网络不通',
  '0x12f910026': 'jsdecoder1.0解码报错视频编码格式不支持',
  '0x12f910027': '后端取流超时,主动关闭连接(设备突然离线或重启,网络传输超时20s)',
  '0x12f910028': '设置的缓冲区大小无效,大小0-510241024,不在该范围的报错',
  '0x12f910029': '普通模式的报错,码流异常导致黑屏,尝试重新取流',
  '0x12f910031': '普通模式下播放卡主会出现',
  '0x12f910032': '码流编码格式普通模式下不支持,可切换高级模式尝试播放',
  '0x12f920015': '未调用停止录像,再次调用开始录像',
  '0x12f920016': '未开启录像调用停止录像接口错误',
  '0x12f920017': '紧急录像目标格式不支持,非ps/mp4',
  '0x12f920018': '紧急录像文件名为null',
  '0x12f930010': '内存不足',
  '0x12f930011': '首帧显示之前无法抓图,请稍后重试',
  '0x12f950000': '采集音频失败,可能是在非https域下使用对讲导致',
  '0x12f950001': '对讲不支持这种音频编码格式',
}

样式文件index.module.less

.video {
  width: 100%;
  height: 100%;
}

.loading {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  :global {
    //让视频插件100%撑满
    .ant-spin-container {
      width: 100%;
      height: 100%;
    }

    //修改ant-spin的默认最大高度
    div > .ant-spin {
      max-height: fit-content;
    }
  }
}

.player {
  cursor: pointer;
  width: 100%;
  height: 100%;
}

参考文献:

0、海康开放平台

1、海康视频H5插件 v2.0.0开发总结_pixle0的博客-CSDN博客

2、vue h5player.min.js对接海康威视,踩过的坑_h5player 海康威视_阿凯 i的博客-CSDN博客

 3、​​​​​​​vue集成海康威视H5视频播放器(H5player)开发包 V2.1.2_海康威视h5player_动感坤坤的博客-CSDN博客

4、构建 - Ant Design Pro 

5、配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/55523.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CUDA_CHECK(cudaFree(...))报错CUDA error 1

GPT-3.5太好用了&#xff0c;报错情况如下&#xff1a; 总结一下, 在使用cudaFree释放之前cudaMalloc()分配的GPU内存时&#xff0c;报错cuda error,最有可能的几个原因就是&#xff1a; 试图释放已经释放的gpu内存&#xff0c;在调用cudafree&#xff08;&#xff09;时确保没…

C# Solidworks二次开发:自动创建虚拟零件及使用注意事项

今天要讲的是关于在solidworks中如何自动创建虚拟零件的功能&#xff0c;也就是solidworks中插入新零件这个功能。 实现这个功能需要使用的API如下所示&#xff1a; InsertNewVirtualPart&#xff08;swFaceOrPlane1, out swcomp2&#xff09;&#xff1b; 其中这个方法中使…

【深度学习】InST,Inversion-Based Style Transfer with Diffusion Models,论文,风格迁移,实战

代码&#xff1a;https://github.com/zyxElsa/InST 论文&#xff1a;https://arxiv.org/abs/2211.13203 文章目录 AbstractIntroductionRelated WorkImage style transferText-to-image synthesisInversion of diffusion models MethodOverview ExperimentsComparison with Sty…

登月再进一步:Apollo自动驾驶的里程碑

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★前端炫酷代码分享 ★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ 解决算法&#xff0c;一个专栏就够了★ ★ 架…

spark-sql数据重复之File Output Committer问题

前言 我们先来回顾下之前介绍过的三种Committer&#xff1a;FileOutputCommitter V1、FileOutputCommitter V2、S3A Committer&#xff0c;其基本代表了整体的演进趋势。 核心代码讲解详细参照&#xff1a;Spark CommitCoordinator 保证数据一致性 OutputCommitter commitTask…

Android如何用系统签名打包应用

前言 应用使用系统签名可以在用户不需要手动授权的情况下自动获取权限。适合一些定制系统中集成apk的方案商。 步骤 需要在AndroidManifest.xml中添加共享系统进程属性&#xff1a; android:sharedUserId"android.uid.system"如下图所示&#xff1a; 找到系统定制…

C++函数模板

2023年8月2日&#xff0c;周三上午 目录 模板的分类语法模板实例化示例程序深入理解模板参数 模板的分类 模板分为函数模板和类模板。 语法 template<typename 模板参数1,...> 返回值类型 函数名(参数列表){} template是一个关键字&#xff0c;用于声明模板 <>…

MPLS虚拟专用网跨域--OptionB方案

OptionB方案 跨域VPN-OptionB中,两个ASBR通过MP-EBGP交换它们从各自AS的PE设备接收的标签VPN-IPv4路由。图中,VPN LSP表示私网隧道,LSP表示公网隧道。 跨域VPN-OptionB方案中,ASBR接收本域内和域外传过来的所有跨域VPN-IPv4路由,再把VPN-IPv4路由发布出去。但MPLS VPN的…

C++多线程环境下的单例类对象创建

使用C无锁编程实现多线程下的单例模式 贺志国 2023.8.1 一、尺寸较小的类单例对象创建 如果待创建的单例类SingletonForMultithread内包含的成员变量较少&#xff0c;整个类占用的内存空间较小&#xff0c;则可以使用如下方法来创建单例对象&#xff08;如果类的尺寸较大则不…

穷举深搜暴搜回溯剪枝(1)

一)全排列: 46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 1)先画出决策树: 越详细越好&#xff0c;就是我们在进行暴力枚举这道题的过程中&#xff0c;如何不重不漏地将所有的情况全部枚举到&#xff0c;把这个思想历程给画下来&#xff0c;就可以了&#xff0c;把每一步…

PHP高级检索功能的实现以及动态拼接sql

我们学习了解了这么多关于PHP的知识&#xff0c;不知道你们对PHP高级检索功能的实现以及动态拼接sql是否已经完全掌握了呢&#xff0c;如果没有&#xff0c;那就跟随本篇文章一起继续学习吧! PHP高级检索功能的实现以及动态拼接sql。完成的功能有&#xff1a;可以单独根据一个…

k8s部署xxl-job分布式任务调度服务

一、背景 什么时候需要把xxl-job部署到k8s里 当你的java服务部署到K8S后&#xff0c;因为xxl-job的任务调度器需要对注册上来的执行器进行健康检测&#xff0c;而java服务作为执行器&#xff0c;注册地址是pod的Ip地址&#xff1b;所以&#xff0c;调度器想要访问执行器的网路…

DevExpress WPF Tree List组件,让数据可视化程度更高!(二)

DevExpress WPF Tree List组件是一个功能齐全、数据感知的TreeView-ListView混合体&#xff0c;可以把数据信息显示为REE、GRID或两者的组合&#xff0c;在数据绑定或非绑定模式下&#xff0c;具有完整的数据编辑支持。 在上文中&#xff08;点击这里回顾DevExpress WPF Tree …

JavaScript 简单实现观察者模式和发布-订阅模式

JavaScript 简单实现观察者模式和发布-订阅模式 1. 观察者模式1.1 什么是观察者模式1.2 代码实现 2. 发布-订阅模式2.1 什么是发布-订阅模式2.2 代码实现2.2.1 基础版2.2.2 取消订阅2.2.3 订阅一次 1. 观察者模式 1.1 什么是观察者模式 概念&#xff1a;观察者模式定义对象间…

IBM Spectrum LSF (“LSF“ ,简称为负载共享设施) 用户案例

IBM Spectrum LSF (“LSF” &#xff0c;简称为负载共享设施) 用户案例 IBM Spectrum LSF (“LSF” &#xff0c;简称为负载共享设施) 软件是业界领先的企业级软件。 LSF 在现有异构 IT 资源之间分配工作&#xff0c;以创建共享&#xff0c;可扩展且容错的基础架构&#xff0c…

纯css实现九宫格图片

本篇文章所分享的内容主要涉及到结构伪类选择器&#xff0c;不熟悉的小伙伴可以了解一下&#xff0c;在常用的css选择器中我也有分享相关内容。 话不多说&#xff0c;接下来我们直接上代码&#xff1a; <!DOCTYPE html> <html lang"en"><head>&l…

如何在烟草行业运用IPD?

从当前的世界烟草行业来看&#xff0c;烟草经济的发展十分迅速&#xff0c;中国是烟草生产与消费第一大国&#xff0c;每年由我国生产与出售的烟草远销世界各地。与此同时&#xff0c;中国烟草行业的集中度越来越高&#xff0c;企业的数量与规模稳步上升&#xff0c;行业迈向规…

【iOS】通知原理

我们可以通过看通知的实现机制来了解通知中心是怎么实现对观察者的引用的。由于苹果对Foundation源码是不开源的&#xff0c;我们具体就参考一下GNUStep的源码实现。GNUStep的源码地址为&#xff1a;GNUStep源码GitHub下载地址, 具体源码可以进行查看。 通知的主要流程 通知全…

简单工厂模式(Simple Factory)

简单工厂模式&#xff0c;又称为静态工厂方法(Static Factory Method)模式。在简单工厂模式中&#xff0c;可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例&#xff0c;被创建的实例通常都具有共同的父类。简单工厂模式不属于GoF的23个…

瑞吉外卖项目----(2)缓存优化

1 缓存优化 1.0 问题说明 1.1 环境搭建 将项目推送到远程仓库里&#xff0c;教程在git 提交远程仓库前建议取消代码检查 创建新的分支v1.0&#xff08;用于实现缓存优化&#xff09;并推送到远程仓库 1.1.1 maven坐标 导入spring-data-redis的maven坐标&#xff1a; &l…