Newer
Older
safe_production_front / src / utils / DHVideo.ts
import ajax from 'ajax'
import { ElMessage } from 'element-plus'
import { playback } from '@/api/monitor/hik'
// import { BrowserType, PlayerControl, RPC, _getSession, pubsub } from './module/PlayerControl'

// id:dom的id
export function loginDH(
  ip,
  port,
  username,
  password,
  channel,
  id,
  isPlayback = false,
  StartTime = '',
  EndTime = ''
) {
  return new Promise((resolve, reject) => {
    setIP(`${ip}:${port}`)
    RPC.login(username, password, false)
      .then((res: any) => {
        console.info('登录成功', res)
        setCookie('DWebClientSessionID', '', -1)
        setCookie('DhWebClientSessionID', '', -1)
        /**
         * RPC.keepAlive 保活
         */
        RPC.keepAlive(300, 60000, _getSession(), `${ip}:${port}`)
        const browser = BrowserType()
        if (browser.includes('ie')) {
          window.onunload = () => {
            ajax({
              url: 'global.logout'
            })
          }
        } else if (browser.includes('chrome')) {
          const params = {
            method: 'global.logout',
            params: null,
            id: 10000,
            session: _getSession()
          }
          pubsub.subscribe('onbeforeunload', () => {
            navigator.sendBeacon('/RPC2', JSON.stringify(params))
          })
        } else {
          pubsub.subscribe('onbeforeunload', () => {
            ajax({
              url: 'global.logout'
            })
          })
        }
        if (!isPlayback) {
          const player = onPreview(
            ip,
            port,
            username,
            password,
            channel,
            id,
            isPlayback
          )
          window.player = player
          resolve(player)
        } else {
          playBackDH(
            ip,
            port,
            username,
            password,
            channel,
            id,
            StartTime,
            EndTime
          )
          resolve(null)
        }
      })
      .catch((err: any) => {
        console.log(err)
        reject(err)
      })
  })
}

export function onPreview(
  ip,
  port,
  username,
  password,
  channel,
  id,
  isPlayback,
  list = [],
  playIndex = 0,
  StartTime = 0,
  EndTime = 0
) {
  let url
  if (isPlayback) {
    url = list[playIndex].FilePath
  }
  const options = {
    wsURL: `ws://${ip}:${port}/rtspoverwebsocket`,
    rtspURL: !isPlayback
      ? `rtsp://${ip}:${port}/cam/realmonitor?channel=${
          Number(channel) + 1
        }&subtype=0&proto=Private3`
      : `rtsp://${ip}:${port}/${url}`,
    username,
    password,
    lessRateCanvas: true,
    playback: isPlayback,
    isPrivateProtocol: false,
    realm: RPC.realm, // 设备登录返回的realm
    // playbackIndex: 0,
    range: !isPlayback
      ? 0
      : playIndex === 0
      ? new Date(StartTime).getTime() / 1000 -
        new Date(list[0].StartTime).getTime() / 1000
      : 0,
    h265AccelerationEnabled: true // 硬解码是否开启,默认不开启
  }

  const videoplayerObj = document.getElementById(`dhVideo${id}`)
  const canvasplayerObj = document.getElementById(`dhCanvas${id}`)
  const player = new PlayerControl(options)

  player.on('PlayStart', (e: any) => {
    // console.log(e)
  })
  player.on('WorkerReady', () => {
    player.connect()
  })
  player.on('Error', (rs: any) => {
    console.log(rs)
  })
  if (isPlayback) {
    player.on('FileOver', () => {
      // 播下个录像
      onPreview(
        ip,
        port,
        username,
        password,
        channel,
        id,
        true,
        list,
        playIndex + 1,
        StartTime,
        EndTime
      )
    })
    player.on('UpdateTimeStamp', (e: any) => {
      // const s = new Date(StartTime).getTime() / 1000
      const end = new Date(EndTime).getTime() / 1000
      if (e.timestamp > end) {
        player.stop()
        player.close()
      }
    })
  }

  player.init(canvasplayerObj, videoplayerObj)
  return player
}

export function playBackDH(
  ip,
  port,
  username,
  password,
  channel,
  id,
  StartTime,
  EndTime
) {
  onSearchRecord(channel, StartTime, EndTime)
    .then((result: any) => {
      if (result.recordNums !== 0) {
        onPreview(
          ip,
          port,
          username,
          password,
          channel,
          id,
          true,
          result.allRecords,
          0,
          StartTime,
          EndTime
        )
      }
    })
    .catch((err: any) => {
      console.log(err, 'playBackDH')
    })
}
export async function onSearchRecord(
  Channel: any,
  StartTime: any,
  EndTime: any
) {
  let tmpDir = []
  try {
    /**
     * RPC.getDeviceAllInfo 获取存储信息
     * @param {string} 'getDeviceAllInfo' 方法名
     * @return {Promise}
     */
    tmpDir = await RPC.getDeviceAllInfo('getDeviceAllInfo')
  } catch (e) {
    console.log(e)
  }
  let dirs = null
  if (tmpDir.info && tmpDir.info.length > 1) {
    dirs = 'All'
  } else {
    dirs =
      (tmpDir.info &&
        tmpDir.info[0] &&
        tmpDir.info[0].Detail &&
        tmpDir.info[0].Detail[0] &&
        tmpDir.info[0].Detail[0].Path) ||
      '/mnt/sd'
  }
  const params = {
    condition: {
      Channel: Number(Channel),
      Dirs: [dirs],
      StartTime,
      EndTime,
      Flags: null,
      Events: ['*'],
      Types: ['dav']
    }
  }
  return new Promise((resolve, reject) => {
    getMediaFile(params)
      .then((result: any) => {
        resolve(result)
      })
      .catch((err: any) => {
        if (err && err.error && err.error.code === 285409409) {
          ElMessage.warning('回放功能需要确保SD卡经过设备认证')
        } else {
          ElMessage.warning('无数据')
        }
        reject(err)
      })
  })
}

export function getMediaFile(params: any) {
  return new Promise((resolve, reject) => {
    /**
     * RPC.MediaFileFind.instance 创建媒体文件查找实例
     * @returns {Promise}
     */
    RPC.MediaFileFind.instance()
      .then((json: any) => {
        const queryId = json.result
        /**
         * RPC.MediaFileFind.findFile 设置查找条件,并判断是否存在文件
         * @param {number} queryId 实例id
         * @param {object} params condition参数
         * @returns {Promise}
         */
        RPC.MediaFileFind.findFile(queryId, params)
          .then(() => {
            findNextFile(queryId)
              .then((result: any) => {
                resolve(result)
              })
              .catch((err: any) => {
                reject(err)
              })
          })
          .catch((err: any) => {
            reject(err)
          })
      })
      .catch((err: any) => {
        reject(err)
      })
  })
}

export function findNextFile(queryId: any) {
  return new Promise((resolve, reject) => {
    /**
     * RPC.MediaFileFind.findNextFile 在指定条件基础上查询文件信息
     * @param {number} queryId 实例
     * @param {object} 需要查找的数目
     * @returns {Promise}
     */
    RPC.MediaFileFind.findNextFile(queryId, { count: 100 })
      .then((data: any) => {
        if (Number.isInteger(data.found)) {
          const recordNums = data.found
          const allRecords = [...data.infos]
          stopFind(queryId).then(() => {})
          resolve({
            recordNums,
            allRecords
          })
        } else {
          stopFind(queryId).then(() => {})
          resolve({
            recordNums: 0,
            allRecords: []
          })
        }
      })
      .catch((err: any) => {
        reject(err)
        stopFind(queryId).then(() => {})
      })
  })
}

export function stopFind(object: any) {
  return new Promise((resolve, reject) => {
    /**
     * PC.MediaFileFind.close 结束查询
     * @param {number} object 媒体文件查找实例ID
     * @returns {Promise}
     */
    RPC.MediaFileFind.close(object)
      .then(() => {
        /**
         * PC.MediaFileFind.destroy 销毁媒体文件查找实例
         * @param {number} object 媒体文件查找实例ID
         */
        RPC.MediaFileFind.destroy(object)
        resolve(true)
      })
      .catch((err: any) => {
        reject(err)
      })
      .finally(() => {})
  })
}

export function onStartCut(
  ip,
  port,
  username,
  password,
  channel,
  startTime,
  endTime
) {
  let isCuting = false
  let isCuting1 = false
  const videoplayerObj = document.getElementById('dhVideo0')
  const canvasplayerObj = document.getElementById('dhCanvas0')
  onSearchRecord(channel, startTime, endTime)
    .then((result: any) => {
      if (result.recordNums !== 0) {
        const optionsRecord = {
          wsURL: `ws://${ip}:${port}/rtspoverwebsocket`,
          rtspURL: `rtsp://${ip}:${port}/${result.allRecords[0].FilePath}`,
          username,
          password,
          isPrivateProtocol: false, // 是否私有协议,默认false
          realm: RPC.realm, // 登录返回的设备Realm值
          speed: 16, // 倍速拉流,16倍速
          playback: true, // 是都回放
          isDownLoad: true,
          range:
            new Date(startTime).getTime() / 1000 -
            new Date(result.allRecords[0].StartTime).getTime() / 1000 // 视频裁剪时间与视频的StartTime时间差值
        }
        const cutPlayer = new PlayerControl(optionsRecord)
        cutPlayer.on('FileOver', () => {
          console.log('File Over')
          cutPlayer.startCut(false)
          isCuting = false
          if (result.recordNums > 1) {
            // 录制第二个文件
            const optionsRecord1 = {
              wsURL: `ws://${ip}:${port}/rtspoverwebsocket`,
              rtspURL: `rtsp://${ip}:${port}/${result.allRecords[1].FilePath}`,
              username,
              password,
              isPrivateProtocol: false, // 是否私有协议,默认false
              realm: RPC.realm, // 登录返回的设备Realm值
              speed: 16, // 倍速拉流,16倍速
              playback: true, // 是都回放
              isDownLoad: true,
              range: 0 // 视频裁剪时间与视频的StartTime时间差值
            }
            const cutPlayer1 = new PlayerControl(optionsRecord1)
            cutPlayer1.on('FileOver', () => {
              console.log('File Over')
              cutPlayer1.startCut(false)
              isCuting1 = false
            })
            cutPlayer1.on('UpdateTimeStamp', (e: any) => {
              const s1 = new Date(startTime).getTime() / 1000
              const e1 = new Date(endTime).getTime() / 1000
              if (e.timestamp >= s1 && !isCuting1) {
                cutPlayer1.startCut(true)
                isCuting1 = true
              }
              if (e.timestamp >= e1 && isCuting1) {
                cutPlayer1.startCut(false)
                isCuting1 = false
              }
            })
            cutPlayer1.init(canvasplayerObj, videoplayerObj)
            cutPlayer1.connect(true)
          }
        })
        cutPlayer.on('UpdateTimeStamp', (e: any) => {
          const s1 = new Date(startTime).getTime() / 1000
          const e1 = new Date(endTime).getTime() / 1000
          if (e.timestamp >= s1 && !isCuting) {
            cutPlayer.startCut(true)
            isCuting = true
          }
          if (e.timestamp >= e1 && isCuting) {
            cutPlayer.startCut(false)
            isCuting = false
          }
        })
        cutPlayer.init(canvasplayerObj, videoplayerObj)
        cutPlayer.connect(true)
      }
    })
    .catch((err: any) => {
      console.log(err)
    })
}