feat: 优化视频插件

This commit is contained in:
539943419 committed 2024-09-26 20:38:57 +08:00
1 parent 8d738ef3f9
commit 5173b28ec5
6 files changed
+122 -28

No files matched your search

+13 -16
View File
@@ -10,19 +10,17 @@
import { VirtualFile } from '@/class/VirtualDirectory' import { VirtualFile } from '@/class/VirtualDirectory'
import miaoDropHandler from '@/components/miaoDropHandler.vue' import miaoDropHandler from '@/components/miaoDropHandler.vue'
import { onBeforeUnmount, onMounted, ref } from 'vue' import { onBeforeUnmount, onMounted, ref } from 'vue'
// import useVirtualPages from '@/hooks/useVirtualPages';
import XGPlayer from 'xgplayer' import XGPlayer from 'xgplayer'
import '@/style/xgplayer.scss' import '@/style/xgplayer.scss'
import TextTrack from 'xgplayer/es/plugins/track' import TextTrack from 'xgplayer/es/plugins/track'
import 'xgplayer/es/plugins/track/index.css' import 'xgplayer/es/plugins/track/index.css'
import lockScreen from './playerPlugin/lockScreen' import lockScreen from './playerPlugin/lockScreen/lockScreen'
import xgplayerVueApp from './src/XGPlayerVuePluginRoot.vue'
import useXGPlayerVueFrame from './playerPlugin/xgplayer-vue-frame/xgplayer-vue-frame'
import axios from 'axios' import axios from 'axios'
import { uniq } from 'lodash' import { uniq } from 'lodash'
// import config from '@/config'
// const props = defineProps<{
// id: number
// }>()
const currentFiles = defineModel<VirtualFile[]>('currentFiles', { const currentFiles = defineModel<VirtualFile[]>('currentFiles', {
required: true required: true
}) })
@@ -37,17 +35,15 @@ let _player: XGPlayer
const { setVideo } = (() => { const { setVideo } = (() => {
return { return {
setVideo: async ( setVideo: async (
videoVFile: VirtualFile, videoVFiles: VirtualFile[],
textTrackFiles?: VirtualFile[] textTrackFiles?: VirtualFile[]
) => { ) => {
if(!currentFiles.value.includes(videoVFile)) {
currentFiles.value = [videoVFile]
}
videoVFile || (videoVFile = findVideo(currentFiles.value))
textTrackFiles && textTrackFiles &&
textTrackFiles.push(...findTextTrack(currentFiles.value)) textTrackFiles.push(...findTextTrack(currentFiles.value))
textTrackFiles = uniq(textTrackFiles) textTrackFiles = uniq(textTrackFiles)
currentFiles.value = [videoVFile, ...(textTrackFiles ?? [])] currentFiles.value = [...currentFiles.value, ...videoVFiles, ...(textTrackFiles ?? [])]
const videos = findVideo(currentFiles.value)
const videoVFile = videos.shift() as VirtualFile
const _list = [] const _list = []
if (textTrackFiles) { if (textTrackFiles) {
for (let i of textTrackFiles) { for (let i of textTrackFiles) {
@@ -94,13 +90,14 @@ const { setVideo } = (() => {
} }
_player && _player.destroy() _player && _player.destroy()
_player = new XGPlayer({ _player = new XGPlayer({
plugins: [TextTrack, lockScreen], plugins: [TextTrack, lockScreen, useXGPlayerVueFrame(xgplayerVueApp)],
el: xgPlayer.value, el: xgPlayer.value,
url: videoVFile.url, url: videoVFile.url,
width: '100%', width: '100%',
height: '100%', height: '100%',
volume: 1, volume: 1,
pip: true, loop: true,
// pip: true,
videoFillMode: 'contain', videoFillMode: 'contain',
autoplay: true, autoplay: true,
download: true, download: true,
@@ -113,7 +110,7 @@ const { setVideo } = (() => {
lang: 'zh-cn', lang: 'zh-cn',
playbackRate: [0.1, 0.3, 0.5, 0.75, 1, 1.5, 2, 3, 5, 10], playbackRate: [0.1, 0.3, 0.5, 0.75, 1, 1.5, 2, 3, 5, 10],
playNext: { playNext: {
urlList: [] urlList: videos.map(v=>v.url)
}, },
texttrack texttrack
}) })
@@ -292,7 +289,7 @@ const findVideo = (vFiles: VirtualFile[]) =>
} }
} }
return false return false
})[0] })
const findTextTrack = (vFiles: VirtualFile[]) => const findTextTrack = (vFiles: VirtualFile[]) =>
vFiles.filter((v) => { vFiles.filter((v) => {
@@ -1,23 +1,11 @@
import { BasePlugin } from 'xgplayer' import { BasePlugin } from 'xgplayer'
import './lockScreen.scss' import './lockScreen.scss'
interface LockPluginConfig {
lockText: string
unlockText: string
}
export default class LockPlugin extends BasePlugin { export default class LockPlugin extends BasePlugin {
static get pluginName() { static get pluginName() {
return 'lockPlugin' return 'lockPlugin'
} }
static get defaultConfig(): LockPluginConfig {
return {
lockText: '锁定',
unlockText: '解锁'
}
}
private locked: boolean private locked: boolean
private lockDiv: HTMLDivElement | null = null private lockDiv: HTMLDivElement | null = null
private overlayDiv: HTMLDivElement | null = null private overlayDiv: HTMLDivElement | null = null
@@ -0,0 +1,40 @@
<template>
<Teleport :to="player.root">
<App v-bind="pick(toRaw(props), ['player', 'root'])"></App>
</Teleport>
</template>
<script setup lang="ts">
import { onMounted, Component, toRaw } from "vue";
import Player from "xgplayer/es/player";
import { pick } from "lodash";
const props = defineProps({
player: {
type: Player,
required: true
},
root: {
type: Element,
required: true
},
App: {
type: Object as () => Component,
required: true
}
})
onMounted(() => {
console.log(props)
})
</script>
<style lang="scss" scoped>
.test {
width: 50px;
height: 50px;
background-color: aliceblue;
position: absolute;
right: 0;
}
</style>
@@ -0,0 +1,36 @@
import { App, Component, createApp } from "vue";
import { BasePlugin } from "xgplayer";
import fakeApp from "./fakeRoot.vue";
const useXGPlayerVueFrame = (App: Component) => {
return class XGPlayerVueFrame extends BasePlugin {
static get pluginName() {
return "xgplayerVueFrame";
}
private root: HTMLDivElement | null = null;
private app: App<Element> | null = null;
constructor(args: any) {
super(args);
}
afterCreate() {
console.log({fakeApp})
this.createVueFrame();
}
private createVueFrame() {
this.root = document.createElement("div");
this.app = createApp(fakeApp, { player: this.player, root: this.root, App })
this.app.mount(this.root);
// this.app.mount(this.player.root);
}
destroy() {
this.app?.unmount()
}
};
};
export default useXGPlayerVueFrame;
@@ -0,0 +1,33 @@
<template>
<!-- <div class="test"></div> -->
</template>
<script setup lang="ts">
import { onMounted } from "vue";
import Player from "xgplayer/es/player";
const props = defineProps({
player: {
type: Player,
required: true
},
root: {
type: Element,
required: true
}
})
onMounted(() => {
props
})
</script>
<style lang="scss" scoped>
.test {
width: 50px;
height: 50px;
background-color: aliceblue;
position: absolute;
right: 0;
}
</style>