Newer
Older
smartwell_front / src / components / HKplayer / index.vue
liyaguang on 9 May 6 KB 新需求修改*2
<!--
  Description: 海康视频播放插件  h5视频播放器插件包  相关js文件需要到海康官网下载 csdn教程https://blog.csdn.net/java1024p/article/details/144423696
  Author: 李亚光
  Date: 2023-07-08
 -->

<script lang="ts" setup name="HKPlayer">
import { errorCode } from './errorCode.js'
import errorImg from './error.png'
import loadingImg from './loading.gif'
import { ElMessage } from 'element-plus'
import { RefreshRight } from '@element-plus/icons-vue'
const props = defineProps({
  playId: {
    require: true,
    type: String,
    default: () => {
      return 'player'
    }
  },
  iWidth: {
    require: true,
    type: Number,
    default: 500
  },
  iHeight: {
    require: true,
    type: Number,
    default: 300
  },
})
const emit = defineEmits(['error', 'complete'])
const player = ref()
const playerInfo = ref({})
const error = ref(false)
const initPlayer = () => {
  emit('complete')
  // console.log(props.iWidth, 'props.iWidth')
  // console.log(props.iHeight, 'props.iHeight')
  // @ts-ignore

  player.value = new JSPlugin({
    szId: props.playId,
    szBasePath: '/H5player-HK/', //public下命名的文件名
    bSupporDoubleClickFull: true,
    mseWorkerEnable: false,
    // 当容器div#play_window有固定宽高时,可不传iWidth和iHeight,窗口大小将自适应容器宽高
    iWidth: props.iWidth,
    iHeight: props.iHeight,
    // 分屏播放,默认最大分屏4*4
    iMaxSplit: 1,
    iCurrentSplit: 1
  })
  // 事件回调绑定
  player.value.JS_SetWindowControlCallback({
    //插件选中窗口回调
    windowEventSelect: (iWndIndex) => {
      console.log('windowSelect callback: ', iWndIndex)
      wndIndex.value = iWndIndex
    },
    // @ts-ignore 取流失败,流中断等错误都会触发该回调函数
    pluginErrorHandler: (index, iErrorCode, oError) => {
      // 取流失败
      if (iErrorCode === '0x12f910011') {
        console.error('流中断')
        // 重新自动播放
        emit('error', errorCode[iErrorCode] || '播放失败')
        error.value = true
      }
      else {
        emit('error', errorCode[iErrorCode] || '播放失败')
        error.value = true
      }
    }
  })

}
const wndIndex = ref(0)
const playerUrl = ref('')
const createPlayer = (url: string, i = wndIndex.value) => {
  playerUrl.value = url
  console.log('视频流地址:', url, props.playId)
  if (!url) return
  playerInfo.value = {
    type: 'real',
    url: url,
    i: i,
  }
  // 添加loading图片
  const id = props.playId
  const video = document.getElementById(id) as HTMLDivElement
  // 创建图片
  const img = document.createElement("img")
  img.src = loadingImg
  // 将图片放在视频之上
  const width = video.style.width
  const height = video.style.height
  img.style.width = width
  img.style.height = height
  img.style.top = '0'
  img.style.left = '0'
  img.style.position = "absolute"
  error.value = false
  video.appendChild(img)
  player.value.JS_Play(url, { playURL: url, mode: 0 }, i).then(
    () => {
      console.log('play success=============')
      // 播放成功删除图片
      img.remove()
      ElMessage.warning('播放十秒自动关闭')
      error.value = false
    },
    (err) => {
      // message.warning('播放失败!')
      console.info('JS_Play failed:', errorCode[err] || '播放失败')
      // 视频加载失败图片修改为加载失败img
      img.src = errorImg
      emit('error', errorCode[err] || '播放失败')
      error.value = true
    }
  )
}
// 分屏
const splitPlayer = (num) => {
  if (num === 1) wndIndex.value = 0
  player.value.JS_ArrangeWindow(num)
}
// 全屏
const fullScreen = (isFull) => {
  player.value.JS_FullScreenDisplay(isFull)
}
// 回放
//  回放时间格式要转为 format('YYYY-MM-DDTHH:mm:ss.SSSZ')
const replayFun = (data) => {
  playerInfo.value = {
    type: 'real',
    url: data.url,
  }
  // 添加loading图片
  const id = props.playId
  const video = document.getElementById(id) as HTMLDivElement
  // 创建图片
  const img = document.createElement("img")
  img.src = loadingImg
  error.value = false
  // 将图片放在视频之上
  const width = video.style.width
  const height = video.style.height
  img.style.width = width
  img.style.height = height
  img.style.top = '0'
  img.style.left = '0'
  img.style.position = "absolute"
  video.appendChild(img)
  player.value
    .JS_Play(data.url, { playURL: data.url, mode: 0 }, 0, data.startTime, data.endTime)
    .then(
      () => {
        console.log('playbackStart success')
        // 播放成功删除图片
        img.remove()
        error.value = false
        ElMessage.warning('播放十秒自动关闭')
      },
      (err) => {
        console.info('JS_Play failed:', errorCode[err] || '播放失败')
        // 视频加载失败图片修改为加载失败img
        img.src = errorImg
        error.value = true
        emit('error', errorCode[err] || '播放失败')
      }
    )
}
// 设置窗口大小
const resizeFun = (iWidth, iHeight) => {
  player.value.JS_Resize(iWidth, iHeight)
}
const stopAllPlay = () => {
  player.value.JS_StopRealPlayAll().then(() => {
    console.info('JS_StopRealPlayAll success')
  })
}
const playerFun = {
  createPlayer,
  splitPlayer,
  fullScreen,
  replayFun,
  resizeFun,
  stopAllPlay
}

onMounted(() => {
  initPlayer()
  // 设置播放容器的宽高并监听窗口大小变化
  window.addEventListener('resize', () => {
    player.value.JS_Resize()
  })
})
defineExpose({ playerFun })
onBeforeUnmount(() => {
  player.value.JS_StopRealPlayAll().then(() => {
    console.info('JS_StopRealPlayAll success')
  })
})
const refreshPlayer = () => {
  error.value = false
  createPlayer(playerUrl.value, 0)
}
</script>

<template>
  <div style="width: 100%;height: 100%; position: relative;">
    <div  style="width: 100%;height: 100%; position: relative;" :id="props.playId" class="w-full">
    </div>
    <div v-if="error" class="btn"><el-button type="primary" :icon="RefreshRight" @click="refreshPlayer" /></div>
  </div>
</template>

<style scoped lang="scss">
.w-full {
  position: relative;
}
.btn{
  position: absolute;
  bottom: 4px;
  right: 5px;
}
</style>