feat: 用aplayer随便做了一个音乐插件
This commit is contained in:
1 parent
5173b28ec5
commit
4b5b7956c7
8 files changed
+186
-47
No files matched your search
@@ -0,0 +1,33 @@
|
||||
import { registerComponentOption } from '@/class/PluginCenter'
|
||||
import { PluginExportType } from '@/types/type'
|
||||
import Disc from '@vicons/ionicons5/es/Disc'
|
||||
|
||||
|
||||
const pluginConfig: registerComponentOption = {
|
||||
key: 'miaoMusicPlayer',
|
||||
name: '音乐',
|
||||
icon: Disc,
|
||||
getComponent: async () =>
|
||||
(await import('./miaoMusicPlayerDemo.vue')).default,
|
||||
filter: (vDirs, vFiles) => {
|
||||
if (vDirs.length !== 0) {
|
||||
return false
|
||||
}
|
||||
if (vFiles.length === 0) {
|
||||
return false
|
||||
}
|
||||
for (let i of vFiles) {
|
||||
for (let s of ['mp3']) {
|
||||
if (i.name.endsWith(s)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return vFiles[0].name.endsWith('?')
|
||||
},
|
||||
disable: false
|
||||
}
|
||||
|
||||
export default pluginConfig
|
||||
|
||||
export const type = PluginExportType.component
|
||||
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<miao-drop-handler @on-virtual-files="handleDropVFiles">
|
||||
<div class="miaoMusic-container">
|
||||
<div ref="aplayer" />
|
||||
</div>
|
||||
</miao-drop-handler>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import miaoDropHandler from '@/components/miaoDropHandler.vue'
|
||||
import { VirtualFile } from '@/class/VirtualDirectory';
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
||||
import 'APlayer/dist/APlayer.min.css';
|
||||
// @ts-ignore
|
||||
import APlayer from 'APlayer';
|
||||
import config from '@/config';
|
||||
|
||||
|
||||
const currentFiles = defineModel<VirtualFile[]>('currentFiles', {
|
||||
required: true
|
||||
});
|
||||
|
||||
const MusicList = computed(() => currentFiles.value.map(v => ({
|
||||
url: `${config.baseUrl}${v.url}`,
|
||||
name: v.name,
|
||||
artist: '???',
|
||||
})));
|
||||
|
||||
const handleDropVFiles = (files: VirtualFile[]) => {
|
||||
currentFiles.value = [...currentFiles.value, ...files];
|
||||
};
|
||||
|
||||
const aplayer = ref<any>(null);
|
||||
|
||||
let ap: any
|
||||
|
||||
onMounted(() => {
|
||||
currentFiles.value = [...currentFiles.value.reverse()]
|
||||
const aplayerOption = {
|
||||
container: aplayer.value,
|
||||
audio: MusicList.value,
|
||||
autoplay: true,
|
||||
}
|
||||
ap = new APlayer(aplayerOption);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
ap.destroy()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.miaoMusic-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.aplayer {
|
||||
height: calc(100% - 10px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// .aplayer-list {
|
||||
// max-height: none !important;
|
||||
// height: fit-content;
|
||||
// min-height: 0;
|
||||
// ol {
|
||||
// max-height: none !important;
|
||||
// height: fit-content;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="miaoCrypto-container"></div>
|
||||
<div class="template-container"></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -12,7 +12,7 @@
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.miaoCrypto-container {
|
||||
.template-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -14,36 +14,70 @@ import XGPlayer from 'xgplayer'
|
||||
import '@/style/xgplayer.scss'
|
||||
import TextTrack from 'xgplayer/es/plugins/track'
|
||||
import 'xgplayer/es/plugins/track/index.css'
|
||||
import axios from 'axios'
|
||||
import { uniq } from 'lodash'
|
||||
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 { uniq } from 'lodash'
|
||||
|
||||
|
||||
const currentFiles = defineModel<VirtualFile[]>('currentFiles', {
|
||||
required: true
|
||||
})
|
||||
|
||||
// const views = useVirtualPages()
|
||||
// const view = views.getView(props.id)
|
||||
|
||||
// const videoPath = ref<string>('');
|
||||
const xgPlayer = ref()
|
||||
|
||||
let _player: XGPlayer
|
||||
const { setVideo } = (() => {
|
||||
const initPlayer = (videos: VirtualFile[], texttrack: {
|
||||
list: {
|
||||
id: number; url: string
|
||||
text: string
|
||||
}[]
|
||||
}) => {
|
||||
const videoVFile = videos.shift() as VirtualFile
|
||||
_player && _player.destroy()
|
||||
_player = new XGPlayer({
|
||||
plugins: [
|
||||
TextTrack,
|
||||
lockScreen,
|
||||
useXGPlayerVueFrame(xgplayerVueApp),
|
||||
],
|
||||
el: xgPlayer.value,
|
||||
url: videoVFile.url,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
volume: 1,
|
||||
// loop: true,
|
||||
// pip: true,
|
||||
videoFillMode: 'contain',
|
||||
autoplay: true,
|
||||
download: true,
|
||||
screenShot: {
|
||||
saveImg: true,
|
||||
quality: 1,
|
||||
type: 'image/png',
|
||||
format: '.png'
|
||||
},
|
||||
lang: 'zh-cn',
|
||||
playbackRate: [0.1, 0.3, 0.5, 0.75, 1, 1.5, 2, 3, 5, 10],
|
||||
playNext: {
|
||||
urlList: videos.map(v => v.url)
|
||||
},
|
||||
texttrack,
|
||||
ignores: [videos.length === 0 ? 'playNext' : undefined].filter(v => v) as string[]
|
||||
})
|
||||
}
|
||||
return {
|
||||
setVideo: async (
|
||||
videoVFiles: VirtualFile[],
|
||||
textTrackFiles?: VirtualFile[]
|
||||
) => {
|
||||
// 天哪什么精神状态会写出这种代码
|
||||
textTrackFiles &&
|
||||
textTrackFiles.push(...findTextTrack(currentFiles.value))
|
||||
textTrackFiles = uniq(textTrackFiles)
|
||||
currentFiles.value = [...currentFiles.value, ...videoVFiles, ...(textTrackFiles ?? [])]
|
||||
const videos = findVideo(currentFiles.value)
|
||||
const videoVFile = videos.shift() as VirtualFile
|
||||
currentFiles.value = uniq([...currentFiles.value, ...videoVFiles, ...(textTrackFiles ?? [])])
|
||||
const videos = findVideo(uniq([...currentFiles.value, ...videoVFiles]))
|
||||
const _list = []
|
||||
if (textTrackFiles) {
|
||||
for (let i of textTrackFiles) {
|
||||
@@ -88,32 +122,7 @@ const { setVideo } = (() => {
|
||||
const texttrack = {
|
||||
list: _list
|
||||
}
|
||||
_player && _player.destroy()
|
||||
_player = new XGPlayer({
|
||||
plugins: [TextTrack, lockScreen, useXGPlayerVueFrame(xgplayerVueApp)],
|
||||
el: xgPlayer.value,
|
||||
url: videoVFile.url,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
volume: 1,
|
||||
loop: true,
|
||||
// pip: true,
|
||||
videoFillMode: 'contain',
|
||||
autoplay: true,
|
||||
download: true,
|
||||
screenShot: {
|
||||
saveImg: true,
|
||||
quality: 1,
|
||||
type: 'image/png',
|
||||
format: '.png'
|
||||
},
|
||||
lang: 'zh-cn',
|
||||
playbackRate: [0.1, 0.3, 0.5, 0.75, 1, 1.5, 2, 3, 5, 10],
|
||||
playNext: {
|
||||
urlList: videos.map(v=>v.url)
|
||||
},
|
||||
texttrack
|
||||
})
|
||||
initPlayer([...videos], texttrack)
|
||||
}
|
||||
}
|
||||
})()
|
||||
@@ -135,7 +144,7 @@ const { setUrl, destroyUrl } = (() => {
|
||||
})()
|
||||
|
||||
const handleDropVFiles = (files: VirtualFile[]) => {
|
||||
setVideo(findVideo(files), findTextTrack(files))
|
||||
setVideo(findVideo(files.reverse()), findTextTrack(files))
|
||||
}
|
||||
|
||||
function srtToVtt(srt: string) {
|
||||
@@ -282,14 +291,14 @@ function ssaToVtt(ssaContent: string): string {
|
||||
}
|
||||
|
||||
const findVideo = (vFiles: VirtualFile[]) =>
|
||||
vFiles.filter((v) => {
|
||||
uniq(vFiles.filter((v) => {
|
||||
for (let s of ['mp4', 'mp3']) {
|
||||
if (v.name.endsWith(s)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
}))
|
||||
|
||||
const findTextTrack = (vFiles: VirtualFile[]) =>
|
||||
vFiles.filter((v) => {
|
||||
@@ -303,6 +312,7 @@ const findTextTrack = (vFiles: VirtualFile[]) =>
|
||||
|
||||
onMounted(() => {
|
||||
if (currentFiles.value.length) {
|
||||
currentFiles.value.reverse()
|
||||
setVideo(
|
||||
findVideo(currentFiles.value),
|
||||
findTextTrack(currentFiles.value)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, Component, toRaw } from "vue";
|
||||
import { Component, toRaw } from "vue";
|
||||
import Player from "xgplayer/es/player";
|
||||
import { pick } from "lodash";
|
||||
const props = defineProps({
|
||||
@@ -23,10 +23,6 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
console.log(props)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -16,7 +16,6 @@ const useXGPlayerVueFrame = (App: Component) => {
|
||||
}
|
||||
|
||||
afterCreate() {
|
||||
console.log({fakeApp})
|
||||
this.createVueFrame();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user