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

news2024/9/30 7:16:12

最近前端的一个项目,大屏需要摄像头播放,摄像头厂家是海康威视的,网上找了一圈都没有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、配置

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

行列转换.

表abc&#xff1a; &#xff08;建表语句在文章末尾&#xff09; 想要得到&#xff1a; 方法一 with a as(select 年,产 from abc where 季1), b as(select 年,产 from abc where 季2), c as(select 年,产 from abc where 季3), d as(select 年,产 from abc where 季4) selec…

图像识别概述

图像识别的过程 图像识别技术的过程分以下几步&#xff1a; 1. 信息的获取&#xff1a; 是指通过传感器&#xff0c;将光或声音等信息转化为电信息。也就是获取研究对象的基本信息并通过某种方法将其转变为机器能够认识的信息。 2. 预处理&#xff1a; 主要是指图像处理中的…

行业追踪,2023-07-28

自动复盘 2023-07-28 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

Android中绘制的两个天气相关的View

文章目录 一、前言二、降雨的代码三、风向代码 一、前言 开发天气相关软件时候&#xff0c;做了两个自定义View&#xff0c;这里进行记录&#xff0c;由于涉及类较多&#xff0c;这里仅包含核心代码&#xff0c;需要调整后才可以运行&#xff0c;自定义View范围仅包含网格相关…

机器学习伦理:探讨隐私保护、公平性和透明度

文章目录 &#x1f340;引言&#x1f340;隐私保护&#x1f340;公平性&#x1f340;透明度&#x1f340;结论 随着机器学习技术的不断发展和应用&#xff0c;我们必须面对伦理问题&#xff0c;以确保这些智能系统的发展和使用是符合道德和法律规范的。本文将就机器学习伦理的关…

Revit二次开发 插件加密、打包、发布、授权全套教程

目录 代码加密及授权 添加授权工具引用 添加授权验证代码段 使用VMProtect进行代码保护 代码加密标记 代码加密 发布产品 软件打包 软件发布 相关文件的获取地址 本教程基于mxbim.com所提供的服务。 Revit二次开发 插件加密、打包、发布、授权全套教程 本网站(www.…

实锤研究,ChatGPT能力掉线!

早在一个多月前&#xff0c;ChatGPT性能下降的传闻便开始在网上流行&#xff0c;不少订阅了Plus版的用户纷纷表示&#xff0c;感觉ChatGPT在经历了几轮更新后开始降智&#xff0c;甚至有时反应速度也会出现问题。而如今&#xff0c;这一传闻终于得到了证实。 就在本周&#xf…

如何学好Java并调整学习过程中的心态:学习之路的秘诀

文章目录 第一步&#xff1a;建立坚实的基础实例分析&#xff1a;选择合适的学习路径 第二步&#xff1a;选择合适的学习资源实例分析&#xff1a;参与编程社区 第三步&#xff1a;动手实践实例分析&#xff1a;开发个人项目 调整学习过程中的心态1. 不怕失败2. 持续学习3. 寻求…

ORA-38760: This database instance failed to turn on flashback database

早晨接一个任务&#xff0c;使用rman备份在虚拟化单机上恢复实例&#xff0c;恢复参数文件、控制文件和数据文件都正常&#xff0c;recover归档时报错如下&#xff1a; Starting recover at 2023-07-28 10:25:01 using channel ORA_DISK_1 starting media recovery media reco…

实时云渲染技术:VR虚拟现实应用的关键节点

近年来&#xff0c;虚拟现实&#xff08;Virtual Reality, VR&#xff09;技术在市场上的应用越来越广泛&#xff0c;虚拟现实已成为一个热门的科技话题。相关数据显示&#xff0c;2019年至2021年&#xff0c;我国虚拟现实市场规模不断扩大&#xff0c;从2019年的282.8亿元增长…

攻防世界-Reverse-simple-unpack

题目描述&#xff1a;菜鸡拿到了一个被加壳的二进制文件 1. 思路分析 提示很清楚了&#xff0c;加壳的二进制文件&#xff0c;正好对这一块知识点是残缺的&#xff0c;先了解下加壳到底是什么 通过这段描述&#xff0c;其实加壳的目的是使得逆向起来更难了&#xff0c;因此这里…

基于SSM实现个人随笔分享平台:创作心灵,分享自我

项目简介 本文将对项目的功能及部分细节的实现进行介绍。个人随笔分享平台基于 SpringBoot SpringMVC MyBatis 实现。实现了用户的注册与登录、随笔主页、文章查询、个人随笔展示、个人随笔查询、写随笔、草稿箱、随笔修改、随笔删除、访问量及阅读量统计等功能。该项目登录模…

十六章:可靠性确实重要:一种端到端的弱监督语义分割方法

0.摘要 弱监督语义分割是一项具有挑战性的任务&#xff0c;因为它只利用图像级别的信息作为训练的监督&#xff0c;但在测试时需要产生像素级别的预测。为了应对这样一个具有挑战性的任务&#xff0c;最近最先进的方法提出了采用两步解决方案&#xff0c;即&#xff1a;1&#…

自动上传git

自动上传git 执行脚本 保存为.bat文件 echo off title bat 交互执行git命令 D: cd D:/git/test git add . git commit -m %date:~0,4%年%date:~5,2%月%date:~8,2%日 git push教程如下 1、搜索任务计划程序&#xff08;最好管理员身份运行&#xff0c;普通用户可能无权限&am…

下载JMeter的历史版本——个人推荐5.2.1版本

官网地址&#xff1a;https://archive.apache.org/dist/jmeter/binaries/

【Git|项目管理】Git的常用命令以及使用场景

文章目录 1.前言2.工作区,暂存区,版本库简介3.Git的常用命令4.版本回退5.撤销修改6.删除文件7.总结 1.前言 在学习Git命令之前,需要先了解工作区,暂存区和版本库这三个概念 2.工作区,暂存区,版本库简介 在使用Git进行版本控制时&#xff0c;有三个重要的概念&#xff1a;工作…

机器学习——异常检测

异常点检测(Outlier detection)&#xff0c;⼜称为离群点检测&#xff0c;是找出与预期对象的⾏为差异较⼤的对象的⼀个检测过程。这些被检测出的对象被称为异常点或者离群点。异常点&#xff08;outlier&#xff09;是⼀个数据对象&#xff0c;它明显不同于其他的数据对象。异…

invalid use of incomplete type class ui(new Ui::MainWindow)报错,解决方案

invalid use of incomplete type class ui(new Ui::MainWindow报错&#xff0c;解决方案 原因解决方案 原因 就是在我改控件button的名字的时候&#xff0c;没有选中控件&#xff0c;导致吧mainwindow的名字改了。。。 解决方案 吧mainwindow的名字改回来 MainWindow 完美解…

【LeetCode】101.对称二叉树

题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&#xff1a; 树中节点数…

java项目之社区疫情防控管理信息系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的社区疫情防控管理信息系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Ja…