import { defineComponent, nextTick, onMounted, onUnmounted, toRefs, watch } from 'vue' import 'plyr/dist/plyr.css' import Plyr from 'plyr' import { ref } from 'vue' import styles from './video.module.less' import iconLoop from '../image/icon-loop.svg' import iconLoopActive from '../image/icon-loop-active.svg' import iconplay from '../image/icon-play.svg' import iconpause from '../image/icon-pause.svg' export default defineComponent({ name: 'video-play', props: { item: { type: Object, default: () => { return {} } }, isEmtry: { type: Boolean, default: false }, isActive: { type: Boolean, default: false } }, emits: ['loadedmetadata', 'togglePlay', 'ended', 'reset'], setup(props, { emit, expose }) { const { item, isEmtry } = toRefs(props) const videoRef = ref() const videoItem: any = ref() const controlID = 'v' + Date.now() + Math.floor(Math.random() * 100) const playBtnId = 'play' + Date.now() + Math.floor(Math.random() * 100) const loopBtnId = 'loop' + Date.now() + Math.floor(Math.random() * 100) const toggleHideControl = (isShow: false) => { videoItem.value?.toggleControls(isShow) } const togglePlay = (e: Event) => { e.stopPropagation() videoItem.value?.togglePlay() } const toggleLoop = (e: Event) => { const loopBtn = document.getElementById(loopBtnId) if (!loopBtn || !videoItem.value) return const isLoop = videoItem.value.loop if (isLoop) { loopBtn.classList.remove(styles.active) } else { loopBtn.classList.add(styles.active) } videoItem.value.loop = !videoItem.value.loop } const onDefault = () => { document.getElementById(controlID)?.addEventListener('click', (e: Event) => { e.stopPropagation() emit('reset') }) document.getElementById(playBtnId)?.addEventListener('click', togglePlay) document.getElementById(loopBtnId)?.addEventListener('click', toggleLoop) } const changePlayBtn = (code: string) => { const playBtn = document.getElementById(playBtnId) if (!playBtn) return if (code == 'play') { playBtn.classList.remove(styles.btnPause) playBtn.classList.add(styles.btnPlay) } else { playBtn.classList.remove(styles.btnPlay) playBtn.classList.add(styles.btnPause) } } const controls = `
00:00
00:00
% buffered 00:00
${item.value.name}
` onMounted(() => { videoItem.value = new Plyr(videoRef.value, { autoplay: true, controls: controls, autopause: true, // 一次只允许 ratio: '16:9', // 强制所有视频的纵横比 hideControls: false, // 在 2 秒没有鼠标或焦点移动、控制元素模糊(制表符退出)、播放开始或进入全屏时自动隐藏视频控件。只要移动鼠标、聚焦控制元素或暂停播放,控件就会立即重新出现。 clickToPlay: false, // 单击(或点击)视频容器将切换播放/暂停 fullscreen: { enabled: false, fallback: false, iosNative: false } // 不适用全屏 }) if (videoItem.value) { videoItem.value.on('play', () => { if (videoItem.value) { videoItem.value.muted = false videoItem.value.volume = 1 } // console.log('开始播放', item.value) if (!item.value.autoPlay && !item.value.isprepare && videoItem.value) { // 加载完成后,取消静音播放 videoItem.value.pause() console.log(videoItem.value?.paused, 'video status') } changePlayBtn('') emit('togglePlay', videoItem.value?.paused) }) videoItem.value.on('pause', () => { changePlayBtn('play') emit('togglePlay', videoItem.value?.paused) }) videoItem.value.on('ended', (e: Event) => { emit('ended') changePlayBtn('play') }) videoItem.value.once('loadedmetadata', (e: Event) => { changePlayBtn('play') videoItem.value.currentTime = 0 if (item.value.autoPlay && videoItem.value) { videoItem.value.play() } emit('loadedmetadata', videoItem.value) }) videoItem.value.on('timeupdate', (e: Event) => { // console.log(videoItem.value?.currentTime, '111') }) nextTick(() => { onDefault() }) } }) expose({ changePlayBtn, toggleHideControl }) watch( () => props.isActive, (val) => { if (!val) { console.log(props.isActive, 'isActive') videoItem.value?.pause() } } ) // onUnmounted(() => { // if (videoItem.value) { // videoItem.value?.pause() // videoItem.value?.destroy() // } // }) return () => (
) } })