Commit b7ab75dd5f2cf1e9953e398647f628cf312fee61

Authored by ww
1 parent a09b9ceb

feat: add video.js package && implement videoPlay component

1 -{  
2 - "i18n-ally.localesPaths": [  
3 - "src/locales",  
4 - "src/locales/lang",  
5 - "public/resource/tinymce/langs"  
6 - ],  
7 - "commentTranslate.targetLanguage": "en",  
8 - "cSpell.words": [  
9 - "Cmds",  
10 - "unref"  
11 - ]  
12 -}  
@@ -63,6 +63,7 @@ @@ -63,6 +63,7 @@
63 "sortablejs": "^1.14.0", 63 "sortablejs": "^1.14.0",
64 "tinymce": "^5.8.2", 64 "tinymce": "^5.8.2",
65 "vditor": "^3.8.6", 65 "vditor": "^3.8.6",
  66 + "video.js": "^7.20.3",
66 "vue": "^3.2.31", 67 "vue": "^3.2.31",
67 "vue-i18n": "9.1.7", 68 "vue-i18n": "9.1.7",
68 "vue-json-pretty": "^2.0.4", 69 "vue-json-pretty": "^2.0.4",
@@ -90,6 +91,7 @@ @@ -90,6 +91,7 @@
90 "@types/qrcode": "^1.4.1", 91 "@types/qrcode": "^1.4.1",
91 "@types/qs": "^6.9.7", 92 "@types/qs": "^6.9.7",
92 "@types/sortablejs": "^1.10.7", 93 "@types/sortablejs": "^1.10.7",
  94 + "@types/video.js": "^7.3.49",
93 "@typescript-eslint/eslint-plugin": "^4.29.1", 95 "@typescript-eslint/eslint-plugin": "^4.29.1",
94 "@typescript-eslint/parser": "^4.29.1", 96 "@typescript-eslint/parser": "^4.29.1",
95 "@vitejs/plugin-legacy": "^1.5.1", 97 "@vitejs/plugin-legacy": "^1.5.1",
  1 +import { withInstall } from '/@/utils/index';
  2 +import VideoPlay from './src/VideoPlay.vue';
  3 +
  4 +export { getVideoTypeByUrl } from './src/utils';
  5 +
  6 +export const BasicVideoPlay = withInstall(VideoPlay);
  1 +<script lang="ts" setup>
  2 + import { isNumber } from 'lodash';
  3 + import videoJs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js';
  4 + import 'video.js/dist/video-js.css';
  5 + import { computed, CSSProperties, onMounted, onUnmounted, ref, unref } from 'vue';
  6 + import { useDesign } from '/@/hooks/web/useDesign';
  7 +
  8 + const { prefixCls } = useDesign('basic-video-play');
  9 +
  10 + const props = defineProps<{
  11 + options?: VideoJsPlayerOptions;
  12 + }>();
  13 +
  14 + const emit = defineEmits<{
  15 + (event: 'ready', instance?: Nullable<VideoJsPlayer>): void;
  16 + }>();
  17 +
  18 + const videoPlayEl = ref<HTMLVideoElement>();
  19 +
  20 + const videoPlayInstance = ref<Nullable<VideoJsPlayer>>();
  21 +
  22 + const getOptions = computed(() => {
  23 + const { options } = props;
  24 + const defaultOptions: VideoJsPlayerOptions = {
  25 + language: 'zh',
  26 + muted: true,
  27 + liveui: true,
  28 + controls: true,
  29 + };
  30 + return { ...defaultOptions, ...options };
  31 + });
  32 +
  33 + const getWidthHeight = computed(() => {
  34 + let { width = 300, height = 150 } = unref(getOptions);
  35 + width = isNumber(width) ? (`${width}px` as unknown as number) : width;
  36 + height = isNumber(height) ? (`${height}px` as unknown as number) : height;
  37 + return { width, height } as CSSProperties;
  38 + });
  39 +
  40 + const init = () => {
  41 + videoPlayInstance.value = videoJs(unref(videoPlayEl)!, unref(getOptions), () => {
  42 + emit('ready', unref(videoPlayInstance));
  43 + });
  44 + };
  45 +
  46 + onMounted(() => {
  47 + init();
  48 + });
  49 +
  50 + onUnmounted(() => {
  51 + unref(videoPlayInstance)?.dispose();
  52 + videoPlayInstance.value = null;
  53 + });
  54 +</script>
  55 +
  56 +<template>
  57 + <div :class="prefixCls" class="w-full h-full" :style="getWidthHeight">
  58 + <video
  59 + ref="videoPlayEl"
  60 + class="video-js vjs-big-play-centered vjs-show-big-play-button-on-pause w-full h-full"
  61 + ></video>
  62 + </div>
  63 +</template>
  64 +
  65 +<style lang="less">
  66 + @prefix-cls: ~'@{namespace}-basic-video-play';
  67 +</style>
  1 +export enum VideoPlayerType {
  2 + m3u8 = 'application/x-mpegURL',
  3 + mp4 = 'video/mp4',
  4 + webm = 'video/webm',
  5 +}
  6 +
  7 +export const getVideoTypeByUrl = (url: string) => {
  8 + const splitExtReg = /(?:.*)(?<=\.)/;
  9 +
  10 + const type = url.replace(splitExtReg, '');
  11 +
  12 + if (VideoPlayerType[type]) return VideoPlayerType[type];
  13 +
  14 + return VideoPlayerType.mp4;
  15 +};