vue对接大华监控视频

91 阅读5分钟

icc开放平台官网

open-icc.dahuatech.com/#/home

Web无插件-WSPlayer

套件介绍

WSPlayer视频播放器,基于大华协议提供web端通用视频业务功能的JavaScript应用视频相关接口的开发包,能够以极简方式快速在您的应用中集成视频功能,实现无控件化视频取流播放,支持windows、mac、ios、android以及国产化(龙芯+统信)操作系统。

功能介绍

功能项实时预览录像回放录像暂停播放拖动定位声音开关语音对讲录像快放录像倒放手动抓图规则线电子放大云台视频格式音频格式
WSPlayer××H264/H265G711/G726/AAC/MP3

性能规格

硬件配置:i5 9500核显 16G内存

****H264 720PH264 1080PH264 2KH265 720PH265 1080PH265 2K首屏延时
软解14621462<2s<2s
硬解25251625169<2s<2s

浏览器兼容性

兼容浏览器ChromeFirefoxEdgeIE统信浏览器360浏览器
WSPlayer×

开发指南

下载WSPlayer套件,pc端查看pc-wsplayer-demo[Version]的开发文档。在线开放文档

约束条件

ICC平台的视频子系统最低V1.0.5版本,建议 >= V1.1.2版本的视频子系统。

Chrome104+的浏览器可以使用H264和H265硬解,解码效率高,同时也需要较高版本的显卡(需要显卡支持硬解)。

Chrome92 ~ Chrome103的浏览器若想实现较高性能播放,需通过https环境下且https代理服务(web服务)全局增加响应头跨域隔离字段:Cross-Origin-Embedder-Policy: require-corp;Cross-Origin-Opener-Policy: same-origin;

【运行环境】

单线程以及多线程的硬解、软解对浏览器的要求:

****解码方式chrome浏览器要求
单线程H265 硬解V104+
单线程H265 软解V71+
单线程H264 硬解V71+
多线程H265 硬解V104+
多线程H265 软解V96+
多线程H264 硬解V96+

【使用说明】

1)ICC平台的视频子系统最低V1.0.5版本,建议 >= V1.1.2版本的视频子系统。

2)Chrome104+的浏览器可以使用H264和H265硬解,解码效率高,同时也需要较高版本的显卡(需要显卡支持硬解)。

3)Chrome92 - Chrome103的浏览器若想实现较高性能播放,需通过https环境下且https代理服务(web服务)全局增加响应头跨域隔离字段:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

开发文档

open-icc.dahuatech.com/wsplayer/

将demo中的文件放到public文件夹中

在HTML中引入

将icc文件放到src文件下

封装播放器组件

<template>
  <div>
    <div class="ws-player-content">
      <div
        v-if="type === 'real'"
        :style="{ width: width, height: height }"
        class="player"
        ref="ws-real-player"
        id="ws-real-player"
        muted="muted"
      ></div>
      <div
        v-if="type === 'record'"
        :style="{ width: width, height: height }"
        class="player"
        ref="ws-record-player"
        id="ws-record-player"
        muted="muted"
      ></div>
    </div>
  </div>
</template>

<script>
import PlayerManager from "../../icc/PlayerManager.js";
import dayjs from "dayjs";
export default {
  props: {
    type: {
      type: String,
      default: "real",
    },
    // 是否显示工具栏
    showControl: {
      type: Boolean,
      default: true,
    },
    width: {
      type: String,
      default: "100%",
    },
    height: {
      type: String,
      default: "95vh",
    },
    // 初始化显示的窗口
    num:{
      type:Number, 
      default:4
    },
    // 进页面就播放
    channelList:{
      type:Array,
      default:()=>[]
    }
  },
  data() {
    return {
      playerManager: null,
      isPlay: true,
      selectWindowIndex: 0,
      realTreeNodeList: [],
      playbackTreeNodeList: [],
      maxNum: 25,
      jumpTime: dayjs().startOf("day"),
      treeNodeList: [],
    };
  },
  watch: {},
  mounted() {
    this.initPlayer();
    this.realPlay(this.channelList)
    this.setPlayerAdapter('stretching')
  },
  beforeUnmount() {
    if (this.playerManager.player) {
      this.playerManager.player.setPlayerNum(1, false);
      this.playerManager.close();
    }
  },
  methods: {
    /**
     * 初始化视频播放器
     */
    initPlayer() {
      if (this.playerManager) {
        return;
      }
      this.playerManager = new PlayerManager({
        el: this.type === "real" ? "ws-real-player" : "ws-record-player", // 实时预览容器id
        pztEl: "ws-pan-tilt", // 云台控制容器id
        type: this.type, // real - 实时预览
        maxNum: this.maxNum, // 最多显示的窗口
        // prefixUrl: 'wsplayer/static',  // 根据环境配置静态资源前缀
        num: this.num, // 初始化显示的窗口
        showControl: this.showControl, // 默认是否显示工具栏
        showIcon: {
          // 自定义按钮,需要的请配置true, 不需要的按钮请配置false,所有的按钮属性都要写上
          streamChangeSelect: this.showControl, // 主辅码流切换
          talkIcon: this.showControl, // 对讲功能按钮
          localRecordIcon: this.showControl, // 录制视频功能按钮
          audioIcon: this.showControl, // 开启关闭声音按钮
          snapshotIcon: this.showControl, // 抓图按钮
          closeIcon: this.showControl, // 关闭视频按钮
        },
        showRecordProgressBar: true, // 录像回放时,录像的进度条是否需要
        // useNginxProxy: false, // 三方使用,请更改为 false,按照文档进行使用
        // proxyServerIp: localStorage.proxyIp, // 三方使用请注释,按照文档来
        receiveMessageFromWSPlayer: this.receiveMessageFromWSPlayer, // 接收来自wsplayer的回调
        draggable: true, // 是否播放器窗口支持拖拽
      });
    },
    /**
     * 设置显示的路数
     * @param e
     */
    setPlayerNum(division) {
      this.playerManager.player && this.playerManager.setPlayerNum(division);
    },
    /**
     * 设置屏幕自适应或者拉伸
     * @param {string} str selfAdaption 自适应 | stretching 拉伸
     */
    setPlayerAdapter(str) {
      this.playerManager.setPlayerAdapter(str);
    },
    /**
     * 关闭视频
     * @param snum 传入要关闭的窗口序号(不传则全部关闭)
     *
     */
    close(snum) {
      this.playerManager.close(snum);
    },
    // ----------------- 视频录像 --------------------------------
    /**
     * 播放某通道的实时视频
     * @param channelList:通道列表
     */
    realPlay(channelList) {
      this.playerManager.playRealVideo({
        channelList: channelList,
        dataType: 1,
        streamType: 1,
      });
    },

    // ----------------- 录像回放 --------------------------------

    /**
     * 录像回放
     * @param data
     */
    playRecordVideo(data) {
      // 将开始时间和结束时间转成时间戳(到秒)

      data.startTime = dayjs(data.startTime,).unix().toString();
      data.endTime = dayjs(data.endTime,).unix().toString();
      this.playerManager.playRecordVideo(data);
    },
    /**
     * 根据时间跳转播放
     */
    jumpPlayByTime() {
      this.playerManager.jumpPlayByTime(this.jumpTime.format("HH:mm:ss"));
    },
    /**
     * 设置选中的窗口索引
     */
    setSelectIndex(index) {
      this.selectWindowIndex = index;
      this.playerManager.setSelectIndex(index);
    },
    /**
     * 接收来自无插件的回调
     * @param method
     * @param data
     */
    receiveMessageFromWSPlayer(method, data, err) {
      switch (method) {
        case "initializationCompleted":
          // 初始化完成,可调用播放方法(适用于动态加载解码库)
          // 若回调未触发时就使用实时预览/录像回放,则无法播放。
          // 此时我们可以调用一个
          // this.playerManager.playRealVideo({
          //   channelList: [
          //     {
          //       id: "1000006$1$0$3", // {String} 通道编码 -- 用于预览,必填
          //       // deviceCode: deviceCode, // {String} 设备编码 -- 用于对讲,对讲必填,无对讲功能可不填
          //       // deviceType: deviceType, // {String} 设备类型 -- 用于对讲,对讲必填,无对讲功能可不填
          //       // channelSeq: channelSeq, // {String|Number} 通道序号 -- 用于对讲,对讲必填,无对讲功能可不填
          //       cameraType: '2', // {String|Number} 摄像头类型 -- 用于云台,云台必填,无云台功能可不填
          //       capability: '00000000000000000000000000000001', // {String} 能力集 -- 用于云台,云台必填,无云台功能可不填
          //     },
            
              
          //   ],
          //   dataType: 1,
          //   streamType: 1, // {Number} 码流类型 1-主码流 2-辅码流
          //   windowIndex: 0, // {Number} 播放窗口序号(从0开始)
          // });
          
          break;
        case "realSuccess": // 实时预览成功
          console.log("实时预览成功");
          break;
        case "realError":
          console.log("实时预览失败", err);
          break;
        case "recordSuccess": // 录像回放成功
          console.log("录像回放成功");
          break;
        case "recordSuccess": // 录像回放失败
          console.log("录像回放失败", err);
          break;
        case "talkError": // 对讲失败
          console.log("对讲失败");
          break;
        case "selectWindowChanged": // 切换窗口回调
          this.selectWindowIndex = data.playIndex;
          break;
        case "windowNumChanged": // 播放器显示的路数发生改变
          console.log(data, "返回显示的窗口数量");
          break;
        case "closeVideo": // 视频关闭回调
          // 点击关闭按钮引发的视频关闭进行提示
          // 切换视频引发的视频关闭不进行提示
          if (!data.changeVideoFlag) {
            console.log(`窗口${data.selectIndex}的视频已关闭`);
          }
          break;
        case "statusChanged": // 视频状态发生改变
          break;
        case "errorInfo": // 错误信息汇总
          console.log(data, "可打印查看错误消息");
      }
    },
  },
};
</script>

<style lang="scss">
.ws-player-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  height: 95vh;
  // margin-top: 10px;
  .player:first-child {
    height: 100%;
  }

  .bottom-menu {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    height: 60px;
    flex-shrink: 0;

    > button {
      margin-right: 20px;
    }

    > i {
      font-size: 24px;
      margin-right: 20px;
    }

    .record-position {
      margin-right: 20px;
    }

    .wsIcon {
      font-size: 24px;
      margin-right: 16px;
    }

    .full-screen-icon {
      cursor: pointer;
    }
  }
}
</style>

调用后端转发接口

注意在 icc是https 我们是http时需要拿掉两个字段

注意看返回的http是ws https是wss 注意端口号