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的部分组件,自己导入或更换

TypeScript 复制代码
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

css 复制代码
.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、配置

相关推荐
m0_748236583 分钟前
本地部署轻量级web开发框架Flask并实现无公网ip远程访问开发界面
前端·tcp/ip·flask
Jet_closer_burning13 分钟前
Vue2 和 Vue3 的响应式原理对比
前端·javascript·vue.js·html
xing251641 分钟前
pytest-html
前端·html·pytest
努力的白熊嗨1 小时前
一文带你搞懂前端大文件上传
前端·javascript
茂茂在长安1 小时前
Linux 命令大全完整版(11)
java·linux·运维·服务器·前端·centos
知识分享小能手1 小时前
Html5学习教程,从入门到精通,HTML5 简介语法知识点及案例代码(1)
开发语言·前端·javascript·学习·前端框架·html·html5
IT、木易1 小时前
大白话React第二章深入理解阶段
前端·javascript·react.js
晚安7202 小时前
Ajax相关
前端·javascript·ajax
图书馆钉子户2 小时前
怎么使用ajax实现局部刷新
前端·ajax·okhttp
bin91532 小时前
DeepSeek 助力 Vue 开发:打造丝滑的单选按钮(Radio Button)
前端·javascript·vue.js·ecmascript·deepseek