Files
xk-admin/apps/web-antd/src/components/video-player/XgVideoPlayer.vue

134 lines
2.4 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue';
import Player from 'xgplayer';
import 'xgplayer/dist/index.min.css';
interface Props {
src: string;
autoplay?: boolean;
controls?: boolean;
thumbnail?: boolean;
width?: number | string;
height?: number | string;
poster?: string;
}
const props = withDefaults(defineProps<Props>(), {
autoplay: false,
controls: true,
thumbnail: false,
width: '100%',
height: '100%',
poster: undefined,
});
const emit = defineEmits<{
ready: [player: Player];
error: [error: any];
ended: [];
}>();
const containerRef = ref<HTMLDivElement>();
const player = shallowRef<Player | null>(null);
function createPlayer() {
if (!containerRef.value || !props.src) return;
player.value?.destroy();
player.value = null;
const ignores = props.thumbnail
? [
'cssfullscreen',
'screenshot',
'pip',
'miniscreen',
'keyboard',
'download',
'playbackrate',
'time',
'definition',
'fullscreen',
'loading',
'mobile',
'pc',
'play',
'poster',
'progress',
'replay',
'start',
'volume',
]
: [];
const p = new Player({
el: containerRef.value,
url: props.src,
autoplay: props.autoplay,
controls: props.thumbnail ? false : props.controls,
closeVideoClick: props.thumbnail,
closeVideoDblclick: props.thumbnail,
ignores,
fluid: true,
fitVideoSize: 'fixWidth',
videoInit: true,
poster: props.poster,
playsinline: true,
enableContextmenu: !props.thumbnail,
});
p.on('ready', () => {
emit('ready', p);
});
p.on('error', (e: any) => {
emit('error', e);
});
p.on('ended', () => {
emit('ended');
});
player.value = p;
}
onMounted(() => {
createPlayer();
});
onBeforeUnmount(() => {
player.value?.destroy();
player.value = null;
});
watch(
() => props.src,
() => {
createPlayer();
},
);
defineExpose({
getPlayer: () => player.value,
play: () => player.value?.play(),
pause: () => player.value?.pause(),
destroy: () => {
player.value?.destroy();
player.value = null;
},
});
</script>
<template>
<div ref="containerRef" class="xg-video-player"></div>
</template>
<style scoped>
.xg-video-player {
width: v-bind(width);
height: v-bind(height);
}
</style>