VideoPlay.vue 2.04 KB
<template>
  <div class="videoPlay">
    <video
      style="object-fit: cover"
      :poster="poster"
      crossOrigin="anonymous"
      ref="videoRef"
      class="video-js vjs-default-skin vjs-big-play-centered"
      controls
    >
      <source :src="path" />
    </video>
  </div>
</template>
<script lang="ts" setup>
import { nextTick, onBeforeUnmount, onMounted, ref, watch, toRefs } from 'vue'
import videojs, { VideoJsPlayer } from 'video.js'
import type { VideoJsPlayerOptions } from 'video.js'
import 'video.js/dist/video-js.css'
import zh from 'video.js/dist/lang/zh-CN.json'

const props = withDefaults(
  defineProps<{
    path: string
    autoPlay?: boolean
    h?: number
    poster?: string
  }>(),
  { autoPlay: false }
)

const videoRef = ref()

let player: VideoJsPlayer

const initPlay = async () => {
  videojs.addLanguage('zh-CN', zh)
  await nextTick()
  const options: VideoJsPlayerOptions = {
    muted: true,
    controls: true,
    autoplay: props.autoPlay,
    src: props?.path,
    poster: props?.poster,
    language: 'zh-CN',
    techOrder: ['html5'],
    preload: 'none'
  }
  player = videojs(videoRef.value, options, () => {
    videojs.log('Video is reading')
    if (props.autoPlay) {
      player.play()
    }
    player.on('ended', () => {
      videojs.log('Play end')
    })
    player.on('error', () => {
      player.errorDisplay.close()
      videojs.log('Play parse error')
    })
  })
}

onMounted(() => {
  initPlay()
})

//直接改变路径测试
watch(
  () => props.path,
  () => {
    if (props.path && props.autoPlay) {
      player?.pause()
      player?.load()
      player?.src(props.path)
      player?.play()
    }
  },
  {
    immediate: true
  }
)

onBeforeUnmount(() => {
  player?.dispose()
})
</script>
<style>
.vjs-poster {
  background-size: cover !important;
}
</style>
<style lang="scss" scoped>
.videoPlay {
  flex: 1;
  height: v-bind('`${h}px`');
  .video-js {
    height: 100%;
    width: 100%;
  }
}
</style>