React の UmiJS によって構築されたプロジェクトには、Hikvision h5player 再生プラグイン H5 ビデオ プレーヤー開発キット V2.1.2 が統合されています。

最近のフロントエンド プロジェクトでは、大きな画面で再生するためにカメラが必要です。カメラのメーカーは Hikvision です。インターネットで検索しましたが、特に UmiJS スキャフォールディングで構築されていない場合は、React の統合が見つかりませんでした。記録しておきます。

Hikvision のオープン プラットフォームの API アドレス、関連するプラグイン、ドキュメントは次の場所からダウンロードできます。

Hikvision 統合セキュリティ管理プラットフォーム[ Hikvision オープン プラットフォーム]

 ダウンロード後、必要なコア パッケージは次のとおりです。xxx.wasm ファイルは、C++ で書かれた公式 WebAssembly ファイルです。これは、スタック ベースの仮想マシンのバイナリ命令形式であり、非常に簡単に実行できるように設計された低レベル アセンブリ言語です。コンパイルされたマシンコードに近く、ネイティブのパフォーマンスに非常に近いです。

 

統合の難しさは、公式の開発キットの導入にあります。ダウンロードしたデモは HTML で書かれており、Head タグに直接インポートできるため問題ありませんが、UmiJS フレームワークによって直接ビルドされたコンポーネント プロジェクトはそうではありません。 HTML ファイルがあるため、追加のスクリプトが導入されている場所を見つける必要があり、異なるフレームワークで構築されたプロジェクトの場合は、公式ドキュメントを読むことをお勧めします。最も直接的な指示があります。UmiJS フレームワークの導入について、ついに公式ドキュメントに記載が見つかりました。構成

 見つけたら、構成にインポートできます。参照されたパスに注意してください。JS パッケージ全体がパブリック フォルダーに配置されます。

 次に、それを引用し、AntD のいくつかのコンポーネントを使用するコード HFivePlayer.ts を直接アップロードし、自分でインポートまたは置き換えることができます。

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. Hikvision オープン プラットフォーム

1. Haikang Video H5 プラグイン v2.0.0_pixle0 のブログ - CSDN ブログの開発概要

2. Vue h5player.min.js を Hikvision に接続、踏まれた穴_h5player Hikvision_Akai's Blog-CSDN Blog

 3. Vue はHikvision H5 ビデオ プレーヤー (H5player) 開発キット V2.1.2 を統合_Hikvision h5player_Dynamic Kunkun のブログ - CSDN ブログ

4.ビルド - Ant Design Pro 

5.構成

おすすめ

転載: blog.csdn.net/qq_35624642/article/details/131988533