forked from miao-moe/QZMusic_PC
fork(fix): Clone AMLL 并修复 BUG
- 将AMLL Clone到本以地进行修复和优化(emm虽然这很不优雅但是暂时无时间做子模块和Fork) - 修复在当前播放歌词行不可见的视口Seek会出现滚动偏移的问题
This commit is contained in:
24
amll-local/packages/playground/vue/index.html
Normal file
24
amll-local/packages/playground/vue/index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>AMLL Vue Wrapper Test</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="src/test.ts" type="module" defer></script>
|
||||
<style>
|
||||
:root {
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, "SF Pro Display", "PingFang SC", system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #222;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="height: 100vh; overflow: hidden;">
|
||||
<div id="root" style="height: 100vh; overflow: hidden;"></div>
|
||||
</body>
|
||||
</html>
|
||||
30
amll-local/packages/playground/vue/package.json
Normal file
30
amll-local/packages/playground/vue/package.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "@applemusic-like-lyrics/playground-vue",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"nx": {
|
||||
"tags": [
|
||||
"playground"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@applemusic-like-lyrics/core": "workspace:^",
|
||||
"@applemusic-like-lyrics/lyric": "workspace:^",
|
||||
"@applemusic-like-lyrics/vue": "workspace:^",
|
||||
"@pixi/app": "^7.4.3",
|
||||
"@pixi/core": "^7.4.3",
|
||||
"@pixi/display": "^7.4.3",
|
||||
"@pixi/filter-blur": "^7.4.3",
|
||||
"@pixi/filter-color-matrix": "^7.4.3",
|
||||
"@pixi/sprite": "^7.4.3",
|
||||
"@vitejs/plugin-vue": "^6.0.7",
|
||||
"@vitejs/plugin-vue-jsx": "^5.1.5",
|
||||
"@vue/tsconfig": "^0.9.0",
|
||||
"vite": "catalog:",
|
||||
"vue": "^3.5.30"
|
||||
}
|
||||
}
|
||||
125
amll-local/packages/playground/vue/src/TestApp.vue
Normal file
125
amll-local/packages/playground/vue/src/TestApp.vue
Normal file
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<BackgroundRender
|
||||
:album="state.albumUrl"
|
||||
:album-is-video="state.albumIsVideo"
|
||||
ref="bgRef"
|
||||
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
|
||||
/>
|
||||
<LyricPlayer
|
||||
:lyric-lines="lyricLines"
|
||||
:current-time="state.currentTime"
|
||||
ref="playerRef"
|
||||
@line-click="e => { if (audioRef) audioRef.currentTime = (e.line.getLine().startTime / 1000) }"
|
||||
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; mix-blend-mode: plus-lighter;"
|
||||
>
|
||||
<template #bottom-line> Test Bottom Line </template>
|
||||
</LyricPlayer>
|
||||
|
||||
<div
|
||||
style="position: absolute; right: 0; bottom: 0; background-color: #0004; margin: 1rem; padding: 1rem; border-radius: 0.5rem; color: white; display: flex; flex-direction: column; gap: 0.5rem;"
|
||||
>
|
||||
<div>AMLL Vue 绑定调试页面</div>
|
||||
<div>为了减少依赖,没有过多的调试设置。</div>
|
||||
<div>更加详尽的调试可以直接使用 Core 模块调试。</div>
|
||||
<button type="button" @click="onClickOpenAudio">加载音乐</button>
|
||||
<button type="button" @click="onClickOpenAlbumImage">
|
||||
加载专辑背景资源(图片/视频)
|
||||
</button>
|
||||
<button type="button" @click="onClickOpenTTMLLyric">加载歌词</button>
|
||||
<audio
|
||||
controls
|
||||
ref="audioRef"
|
||||
@play="onPlay"
|
||||
:src="state.audioUrl"
|
||||
preload="auto"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { LyricLine } from "@applemusic-like-lyrics/core";
|
||||
import { parseTTML } from "@applemusic-like-lyrics/lyric";
|
||||
import {
|
||||
BackgroundRender,
|
||||
type BackgroundRenderRef,
|
||||
LyricPlayer,
|
||||
type LyricPlayerRef,
|
||||
} from "@applemusic-like-lyrics/vue";
|
||||
import { onMounted, reactive, ref, shallowRef } from "vue";
|
||||
|
||||
const audioRef = ref<HTMLAudioElement>();
|
||||
const state = reactive({
|
||||
audioUrl: "",
|
||||
albumUrl: "",
|
||||
albumIsVideo: false,
|
||||
currentTime: 0,
|
||||
});
|
||||
const lyricLines = shallowRef<LyricLine[]>([]);
|
||||
|
||||
const playerRef = ref<LyricPlayerRef>();
|
||||
const bgRef = ref<BackgroundRenderRef>();
|
||||
|
||||
onMounted(() => {
|
||||
console.log(playerRef.value);
|
||||
console.log(bgRef.value);
|
||||
});
|
||||
|
||||
function onPlay() {
|
||||
const onFrame = () => {
|
||||
if (audioRef.value && !audioRef.value.paused) {
|
||||
state.currentTime = (audioRef.value.currentTime * 1000) | 0;
|
||||
requestAnimationFrame(onFrame);
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(onFrame);
|
||||
}
|
||||
|
||||
function onClickOpenAudio() {
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = "audio/*";
|
||||
input.onchange = () => {
|
||||
const file = input.files?.[0];
|
||||
if (file) {
|
||||
if (state.audioUrl.trim().length > 0) {
|
||||
URL.revokeObjectURL(state.audioUrl);
|
||||
}
|
||||
state.audioUrl = URL.createObjectURL(file);
|
||||
state.albumIsVideo = file.type.startsWith("video/");
|
||||
}
|
||||
};
|
||||
input.click();
|
||||
}
|
||||
|
||||
function onClickOpenAlbumImage() {
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = "image/*,video/*";
|
||||
input.onchange = () => {
|
||||
const file = input.files?.[0];
|
||||
if (file) {
|
||||
if (state.albumUrl.trim().length > 0) {
|
||||
URL.revokeObjectURL(state.albumUrl);
|
||||
}
|
||||
state.albumUrl = URL.createObjectURL(file);
|
||||
}
|
||||
};
|
||||
input.click();
|
||||
}
|
||||
|
||||
function onClickOpenTTMLLyric() {
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = ".ttml,text/*";
|
||||
input.onchange = async () => {
|
||||
const file = input.files?.[0];
|
||||
if (file) {
|
||||
const text = await file.text();
|
||||
const result = parseTTML(text);
|
||||
console.log("parseTTML", result);
|
||||
lyricLines.value = result.lines;
|
||||
}
|
||||
};
|
||||
input.click();
|
||||
}
|
||||
</script>
|
||||
5
amll-local/packages/playground/vue/src/test.ts
Normal file
5
amll-local/packages/playground/vue/src/test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import "@applemusic-like-lyrics/core/style.css";
|
||||
import { createApp } from "vue";
|
||||
import TestApp from "./TestApp.vue";
|
||||
|
||||
createApp(TestApp).mount("#root");
|
||||
1
amll-local/packages/playground/vue/src/vite-env.d.ts
vendored
Normal file
1
amll-local/packages/playground/vue/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
9
amll-local/packages/playground/vue/tsconfig.json
Normal file
9
amll-local/packages/playground/vue/tsconfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"isolatedDeclarations": false,
|
||||
"jsxImportSource": "vue",
|
||||
"jsx": "preserve"
|
||||
}
|
||||
}
|
||||
22
amll-local/packages/playground/vue/vite.config.ts
Normal file
22
amll-local/packages/playground/vue/vite.config.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import path from "node:path";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
"@applemusic-like-lyrics/core/style.css": path.resolve(
|
||||
__dirname,
|
||||
"../../core/src/styles/index.css",
|
||||
),
|
||||
"@applemusic-like-lyrics/vue": path.resolve(__dirname, "../../vue/src"),
|
||||
"@applemusic-like-lyrics/core": path.resolve(__dirname, "../../core/src"),
|
||||
"@applemusic-like-lyrics/lyric": path.resolve(
|
||||
__dirname,
|
||||
"../../lyric/src",
|
||||
),
|
||||
},
|
||||
},
|
||||
plugins: [vue(), vueJsx()],
|
||||
});
|
||||
Reference in New Issue
Block a user