Vue3+Vite 播放m3u8视频

511 阅读1分钟
<!-- 播放组件 -->
<template>
  <div class="video-play-modal">
    <BasicModal
      v-bind="$attrs"
      :title="videoData && videoData.cameraName ? videoData.cameraName : '查看'"
      @register="registerModal"
      width="800px"
      :showOkBtn="false"
      cancel-text="关闭"
      :canFullscreen="false"
      destroy-on-close
    >
      <video-player
        v-if="videoData && videoData.playUrl"
        class="w-full"
        :class="['video-player', 'vjs-big-play-centered', { loading: !state }]"
        :sources="mediaConfig.sources"
        v-bind="config"
        @mounted="handleMounted"
      />

      <a-empty v-else />
    </BasicModal>
  </div>
</template>

<script setup lang="ts">
  import { ref, computed, shallowRef, shallowReactive } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { VideoPlayer, VideoPlayerProps, VideoPlayerState } from '@videojs-player/vue';
  import videojs from 'video.js';
  import 'video.js/dist/video-js.css';
  import video_zhCN from 'video.js/dist/lang/zh-CN.json';

  type VideoJsPlayer = ReturnType<typeof videojs>;

  const videoData = ref<Nullable<Recordable>>(null);
  const player = shallowRef<VideoJsPlayer>();
  const config = shallowReactive<VideoPlayerProps>({
    language: 'zh-CN',
    languages: {
      'zh-CN': video_zhCN,
    },
    autoplay: true,
    volume: 0.8,
    playbackRate: 1,
    playbackRates: [0.5, 0.75, 1.0, 1.25, 1.5, 2.0],
    controls: true,
    fluid: true,
    muted: false,
    loop: false,
    crossorigin: 'anonymous',
    playsinline: true,
    controlBar: {
      subsCapsButton: false,
      audioTrackButton: false,
      pictureInPictureToggle: false,
    },
  });
  const mediaConfig = computed<VideoPlayerProps>(() => ({
    sources: [
      {
        src: 'https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8', //视频源
        type: 'application/x-mpegurl', //视频类型
      },
    ],
  }));
  const state = shallowRef<VideoPlayerState>();
  const handleMounted = (payload: any) => {
    state.value = payload.state;
    player.value = payload.player;
  };
  const [registerModal] = useModalInner(async (data) => {
    videoData.value = data || null;
  });
</script>