2025-02-19 01:01:43 +08:00
|
|
|
import { createDiscreteApi } from 'naive-ui';
|
2025-03-21 00:19:15 +08:00
|
|
|
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
|
2024-10-18 18:37:53 +08:00
|
|
|
|
2025-03-19 22:48:28 +08:00
|
|
|
import i18n from '@/../i18n/renderer';
|
2025-01-16 23:19:16 +08:00
|
|
|
import useIndexedDB from '@/hooks/IndexDBHook';
|
2024-12-12 22:18:52 +08:00
|
|
|
import { audioService } from '@/services/audioService';
|
2025-03-19 22:48:28 +08:00
|
|
|
import pinia, { usePlayerStore } from '@/store';
|
2025-01-16 23:19:16 +08:00
|
|
|
import type { Artist, ILyricText, SongResult } from '@/type/music';
|
2025-01-01 02:25:18 +08:00
|
|
|
import { isElectron } from '@/utils';
|
2025-01-10 22:49:55 +08:00
|
|
|
import { getTextColors } from '@/utils/linearColor';
|
2025-02-19 01:01:43 +08:00
|
|
|
|
2024-09-12 16:44:42 +08:00
|
|
|
const windowData = window as any;
|
|
|
|
|
|
2025-03-19 22:48:28 +08:00
|
|
|
const playerStore = usePlayerStore(pinia);
|
2024-10-18 18:37:53 +08:00
|
|
|
export const lrcArray = ref<ILyricText[]>([]); // 歌词数组
|
|
|
|
|
export const lrcTimeArray = ref<number[]>([]); // 歌词时间数组
|
|
|
|
|
export const nowTime = ref(0); // 当前播放时间
|
|
|
|
|
export const allTime = ref(0); // 总播放时间
|
|
|
|
|
export const nowIndex = ref(0); // 当前播放歌词
|
|
|
|
|
export const correctionTime = ref(0.4); // 歌词矫正时间Correction time
|
|
|
|
|
export const currentLrcProgress = ref(0); // 来存储当前歌词的进度
|
2025-03-19 22:48:28 +08:00
|
|
|
export const playMusic = computed(() => playerStore.playMusic as SongResult); // 当前播放歌曲
|
2024-12-12 22:18:52 +08:00
|
|
|
export const sound = ref<Howl | null>(audioService.getCurrentSound());
|
2024-12-16 22:12:28 +08:00
|
|
|
export const isLyricWindowOpen = ref(false); // 新增状态
|
2025-01-10 22:49:55 +08:00
|
|
|
export const textColors = ref<any>(getTextColors());
|
2025-01-16 23:19:16 +08:00
|
|
|
export const artistList = computed(
|
2025-03-19 22:48:28 +08:00
|
|
|
() => (playerStore.playMusic.ar || playerStore.playMusic?.song?.artists) as Artist[]
|
2025-01-16 23:19:16 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
export const musicDB = await useIndexedDB('musicDB', [
|
|
|
|
|
{ name: 'music', keyPath: 'id' },
|
|
|
|
|
{ name: 'music_lyric', keyPath: 'id' },
|
|
|
|
|
{ name: 'api_cache', keyPath: 'id' }
|
|
|
|
|
]);
|
2024-12-12 22:18:52 +08:00
|
|
|
|
|
|
|
|
document.onkeyup = (e) => {
|
2024-12-14 13:00:06 +08:00
|
|
|
// 检查事件目标是否是输入框元素
|
|
|
|
|
const target = e.target as HTMLElement;
|
|
|
|
|
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-12 22:18:52 +08:00
|
|
|
switch (e.code) {
|
|
|
|
|
case 'Space':
|
2025-03-19 22:48:28 +08:00
|
|
|
if (playerStore.play) {
|
|
|
|
|
playerStore.setPlayMusic(false);
|
2024-12-12 22:18:52 +08:00
|
|
|
audioService.getCurrentSound()?.pause();
|
|
|
|
|
} else {
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.setPlayMusic(true);
|
2024-12-12 22:18:52 +08:00
|
|
|
audioService.getCurrentSound()?.play();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-01-17 22:35:42 +08:00
|
|
|
const { message } = createDiscreteApi(['message']);
|
|
|
|
|
|
2025-03-08 18:31:46 +08:00
|
|
|
// 全局变量
|
|
|
|
|
let progressAnimationInitialized = false;
|
|
|
|
|
let globalAnimationFrameId: number | null = null;
|
|
|
|
|
|
|
|
|
|
// 全局停止函数
|
|
|
|
|
const stopProgressAnimation = () => {
|
|
|
|
|
if (globalAnimationFrameId) {
|
|
|
|
|
cancelAnimationFrame(globalAnimationFrameId);
|
|
|
|
|
globalAnimationFrameId = null;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 全局更新函数
|
|
|
|
|
const updateProgress = () => {
|
2025-03-19 22:48:28 +08:00
|
|
|
if (!playerStore.play) {
|
2025-03-08 18:31:46 +08:00
|
|
|
stopProgressAnimation();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const currentSound = sound.value;
|
|
|
|
|
if (!currentSound) {
|
|
|
|
|
console.log('进度更新:无效的 sound 对象');
|
|
|
|
|
// 不是立即返回,而是设置定时器稍后再次尝试
|
|
|
|
|
globalAnimationFrameId = setTimeout(() => {
|
|
|
|
|
requestAnimationFrame(updateProgress);
|
|
|
|
|
}, 100) as unknown as number;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof currentSound.seek !== 'function') {
|
|
|
|
|
console.log('进度更新:无效的 seek 函数');
|
|
|
|
|
// 不是立即返回,而是设置定时器稍后再次尝试
|
|
|
|
|
globalAnimationFrameId = setTimeout(() => {
|
|
|
|
|
requestAnimationFrame(updateProgress);
|
|
|
|
|
}, 100) as unknown as number;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const { start, end } = currentLrcTiming.value;
|
|
|
|
|
if (typeof start !== 'number' || typeof end !== 'number' || start === end) {
|
|
|
|
|
globalAnimationFrameId = requestAnimationFrame(updateProgress);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let currentTime;
|
|
|
|
|
try {
|
|
|
|
|
currentTime = currentSound.seek() as number;
|
|
|
|
|
|
|
|
|
|
// 保存当前播放进度到 localStorage (每秒保存一次,避免频繁写入)
|
|
|
|
|
if (Math.floor(currentTime) % 2 === 0) {
|
2025-03-19 22:48:28 +08:00
|
|
|
if (playerStore.playMusic && playerStore.playMusic.id) {
|
2025-03-08 18:31:46 +08:00
|
|
|
localStorage.setItem(
|
|
|
|
|
'playProgress',
|
|
|
|
|
JSON.stringify({
|
2025-03-19 22:48:28 +08:00
|
|
|
songId: playerStore.playMusic.id,
|
2025-03-08 18:31:46 +08:00
|
|
|
progress: currentTime
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (seekError) {
|
|
|
|
|
console.error('调用 seek() 方法出错:', seekError);
|
|
|
|
|
globalAnimationFrameId = requestAnimationFrame(updateProgress);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof currentTime !== 'number' || Number.isNaN(currentTime)) {
|
|
|
|
|
console.error('无效的当前时间:', currentTime);
|
|
|
|
|
globalAnimationFrameId = requestAnimationFrame(updateProgress);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const elapsed = currentTime - start;
|
|
|
|
|
const duration = end - start;
|
|
|
|
|
const progress = (elapsed / duration) * 100;
|
|
|
|
|
|
|
|
|
|
// 确保进度在 0-100 之间
|
|
|
|
|
currentLrcProgress.value = Math.min(Math.max(progress, 0), 100);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('更新进度出错:', error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 继续下一帧更新
|
|
|
|
|
globalAnimationFrameId = requestAnimationFrame(updateProgress);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 全局启动函数
|
|
|
|
|
const startProgressAnimation = () => {
|
|
|
|
|
stopProgressAnimation(); // 先停止之前的动画
|
|
|
|
|
updateProgress();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 全局初始化函数
|
|
|
|
|
const initProgressAnimation = () => {
|
|
|
|
|
if (progressAnimationInitialized) return;
|
|
|
|
|
|
|
|
|
|
console.log('初始化进度动画');
|
|
|
|
|
progressAnimationInitialized = true;
|
|
|
|
|
|
|
|
|
|
// 监听播放状态变化,这里使用防抖,避免频繁触发
|
|
|
|
|
let debounceTimer: any = null;
|
|
|
|
|
|
|
|
|
|
watch(
|
2025-03-19 22:48:28 +08:00
|
|
|
() => playerStore.play,
|
2025-03-08 18:31:46 +08:00
|
|
|
(newIsPlaying) => {
|
|
|
|
|
console.log('播放状态变化:', newIsPlaying);
|
|
|
|
|
|
|
|
|
|
// 清除之前的定时器
|
|
|
|
|
if (debounceTimer) {
|
|
|
|
|
clearTimeout(debounceTimer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用防抖,延迟 100ms 再执行
|
|
|
|
|
debounceTimer = setTimeout(() => {
|
|
|
|
|
if (newIsPlaying) {
|
|
|
|
|
// 确保 sound 对象有效时才启动进度更新
|
|
|
|
|
if (sound.value) {
|
|
|
|
|
console.log('sound 对象已存在,立即启动进度更新');
|
|
|
|
|
startProgressAnimation();
|
|
|
|
|
} else {
|
|
|
|
|
console.log('等待 sound 对象初始化...');
|
|
|
|
|
// 定时检查 sound 对象是否已初始化
|
|
|
|
|
const checkInterval = setInterval(() => {
|
|
|
|
|
if (sound.value) {
|
|
|
|
|
clearInterval(checkInterval);
|
|
|
|
|
console.log('sound 对象已初始化,开始进度更新');
|
|
|
|
|
startProgressAnimation();
|
|
|
|
|
}
|
|
|
|
|
}, 100);
|
|
|
|
|
// 设置超时,防止无限等待
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
clearInterval(checkInterval);
|
|
|
|
|
console.log('等待 sound 对象超时,已停止等待');
|
|
|
|
|
}, 5000);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
stopProgressAnimation();
|
|
|
|
|
}
|
|
|
|
|
}, 100);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 监听当前歌词索引变化
|
|
|
|
|
watch(nowIndex, () => {
|
|
|
|
|
currentLrcProgress.value = 0;
|
2025-03-19 22:48:28 +08:00
|
|
|
if (playerStore.play) {
|
2025-03-08 18:31:46 +08:00
|
|
|
startProgressAnimation();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 监听音频对象变化
|
|
|
|
|
watch(sound, (newSound) => {
|
|
|
|
|
console.log('sound 对象变化:', !!newSound);
|
2025-03-19 22:48:28 +08:00
|
|
|
if (newSound && playerStore.play) {
|
2025-03-08 18:31:46 +08:00
|
|
|
startProgressAnimation();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 初始化进度动画
|
|
|
|
|
initProgressAnimation();
|
|
|
|
|
|
|
|
|
|
// 简化后的 watch 函数,只保留核心逻辑
|
2024-12-12 22:18:52 +08:00
|
|
|
watch(
|
2025-03-19 22:48:28 +08:00
|
|
|
() => playerStore.playMusicUrl,
|
2025-01-16 23:19:16 +08:00
|
|
|
async (newVal) => {
|
2025-01-12 19:14:25 +08:00
|
|
|
if (newVal && playMusic.value) {
|
2025-01-16 23:19:16 +08:00
|
|
|
try {
|
2025-03-08 18:31:46 +08:00
|
|
|
// 保存当前播放状态
|
2025-03-19 22:48:28 +08:00
|
|
|
const shouldPlay = playerStore.play;
|
2025-03-08 18:31:46 +08:00
|
|
|
|
|
|
|
|
// 检查是否有保存的进度
|
|
|
|
|
let initialPosition = 0;
|
|
|
|
|
const savedProgress = JSON.parse(localStorage.getItem('playProgress') || '{}');
|
|
|
|
|
if (savedProgress.songId === playMusic.value.id) {
|
|
|
|
|
initialPosition = savedProgress.progress;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 播放新音频,传递是否应该播放的状态
|
|
|
|
|
const newSound = await audioService.play(newVal, playMusic.value, shouldPlay);
|
2025-01-16 23:19:16 +08:00
|
|
|
sound.value = newSound as Howl;
|
2025-03-08 18:31:46 +08:00
|
|
|
|
|
|
|
|
// 如果有保存的进度,设置播放位置
|
|
|
|
|
if (initialPosition > 0) {
|
|
|
|
|
newSound.seek(initialPosition);
|
|
|
|
|
// 同时更新进度条显示
|
|
|
|
|
nowTime.value = initialPosition;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-16 23:19:16 +08:00
|
|
|
setupAudioListeners();
|
2025-03-08 18:31:46 +08:00
|
|
|
|
|
|
|
|
// 确保状态与 localStorage 同步
|
2025-03-19 22:48:28 +08:00
|
|
|
localStorage.setItem('currentPlayMusic', JSON.stringify(playerStore.playMusic));
|
2025-03-08 18:31:46 +08:00
|
|
|
localStorage.setItem('currentPlayMusicUrl', newVal);
|
2025-01-16 23:19:16 +08:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error('播放音频失败:', error);
|
2025-03-19 22:48:28 +08:00
|
|
|
// store.commit('setPlayMusic', false);
|
|
|
|
|
playerStore.setPlayMusic(false);
|
|
|
|
|
message.error(i18n.global.t('player.playFailed'));
|
2025-01-16 23:19:16 +08:00
|
|
|
}
|
2024-12-12 22:18:52 +08:00
|
|
|
}
|
2025-01-01 02:25:18 +08:00
|
|
|
}
|
2024-12-12 22:18:52 +08:00
|
|
|
);
|
2024-10-18 18:37:53 +08:00
|
|
|
|
|
|
|
|
watch(
|
2025-03-19 22:48:28 +08:00
|
|
|
() => playerStore.playMusic,
|
2024-10-18 18:37:53 +08:00
|
|
|
() => {
|
2024-12-16 22:12:28 +08:00
|
|
|
nextTick(async () => {
|
2025-03-08 19:00:50 +08:00
|
|
|
console.log('歌曲切换,更新歌词数据');
|
|
|
|
|
// 更新歌词数据
|
2024-10-18 18:37:53 +08:00
|
|
|
lrcArray.value = playMusic.value.lyric?.lrcArray || [];
|
|
|
|
|
lrcTimeArray.value = playMusic.value.lyric?.lrcTimeArray || [];
|
2025-03-08 19:00:50 +08:00
|
|
|
|
2024-12-16 22:12:28 +08:00
|
|
|
// 当歌词数据更新时,如果歌词窗口打开,则发送数据
|
2025-03-08 19:00:50 +08:00
|
|
|
if (isElectron && isLyricWindowOpen.value) {
|
|
|
|
|
console.log('歌词窗口已打开,同步最新歌词数据');
|
|
|
|
|
// 不管歌词数组是否为空,都发送最新数据
|
2024-12-16 22:12:28 +08:00
|
|
|
sendLyricToWin();
|
2025-03-08 19:00:50 +08:00
|
|
|
|
|
|
|
|
// 再次延迟发送,确保歌词窗口已完全加载
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
sendLyricToWin();
|
|
|
|
|
}, 500);
|
2024-12-16 22:12:28 +08:00
|
|
|
}
|
2024-10-18 18:37:53 +08:00
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
deep: true,
|
2025-01-01 02:25:18 +08:00
|
|
|
immediate: true
|
|
|
|
|
}
|
2024-10-18 18:37:53 +08:00
|
|
|
);
|
2024-12-12 22:18:52 +08:00
|
|
|
|
2025-01-12 19:14:25 +08:00
|
|
|
const setupAudioListeners = () => {
|
2024-12-12 22:18:52 +08:00
|
|
|
let interval: any = null;
|
|
|
|
|
|
2025-01-16 23:19:16 +08:00
|
|
|
const clearInterval = () => {
|
|
|
|
|
if (interval) {
|
|
|
|
|
window.clearInterval(interval);
|
|
|
|
|
interval = null;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-01-16 00:40:44 +08:00
|
|
|
// 清理所有事件监听器
|
|
|
|
|
audioService.clearAllListeners();
|
|
|
|
|
|
2025-03-08 18:31:46 +08:00
|
|
|
// 立即更新一次时间和进度(解决初始化时进度条不显示问题)
|
|
|
|
|
const updateCurrentTimeAndDuration = () => {
|
|
|
|
|
const currentSound = audioService.getCurrentSound();
|
|
|
|
|
if (currentSound) {
|
|
|
|
|
try {
|
|
|
|
|
// 更新当前时间和总时长
|
|
|
|
|
const currentTime = currentSound.seek() as number;
|
|
|
|
|
if (typeof currentTime === 'number' && !Number.isNaN(currentTime)) {
|
|
|
|
|
nowTime.value = currentTime;
|
|
|
|
|
allTime.value = currentSound.duration() as number;
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('初始化时间和进度失败:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 立即执行一次更新
|
|
|
|
|
updateCurrentTimeAndDuration();
|
|
|
|
|
|
2024-12-12 22:18:52 +08:00
|
|
|
// 监听播放
|
2025-01-12 19:14:25 +08:00
|
|
|
audioService.on('play', () => {
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.setPlayMusic(true);
|
2025-01-16 23:19:16 +08:00
|
|
|
clearInterval();
|
|
|
|
|
interval = window.setInterval(() => {
|
|
|
|
|
try {
|
|
|
|
|
const currentSound = sound.value;
|
2025-03-08 18:31:46 +08:00
|
|
|
if (!currentSound) {
|
|
|
|
|
console.error('Invalid sound object: sound is null or undefined');
|
|
|
|
|
clearInterval();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确保 seek 方法存在且可调用
|
|
|
|
|
if (typeof currentSound.seek !== 'function') {
|
|
|
|
|
console.error('Invalid sound object: seek function not available');
|
2025-01-16 23:19:16 +08:00
|
|
|
clearInterval();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const currentTime = currentSound.seek() as number;
|
|
|
|
|
if (typeof currentTime !== 'number' || Number.isNaN(currentTime)) {
|
|
|
|
|
console.error('Invalid current time:', currentTime);
|
|
|
|
|
clearInterval();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nowTime.value = currentTime;
|
|
|
|
|
allTime.value = currentSound.duration() as number;
|
|
|
|
|
const newIndex = getLrcIndex(nowTime.value);
|
|
|
|
|
if (newIndex !== nowIndex.value) {
|
|
|
|
|
nowIndex.value = newIndex;
|
2025-03-08 18:31:46 +08:00
|
|
|
// 注意:我们不在这里设置 currentLrcProgress 为 0
|
|
|
|
|
// 因为这会与全局进度更新冲突
|
2025-01-16 23:19:16 +08:00
|
|
|
if (isElectron && isLyricWindowOpen.value) {
|
|
|
|
|
sendLyricToWin();
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-01 02:25:18 +08:00
|
|
|
if (isElectron && isLyricWindowOpen.value) {
|
2024-12-16 22:12:28 +08:00
|
|
|
sendLyricToWin();
|
|
|
|
|
}
|
2025-01-16 23:19:16 +08:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error in interval:', error);
|
|
|
|
|
clearInterval();
|
2024-12-12 22:18:52 +08:00
|
|
|
}
|
|
|
|
|
}, 50);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 监听暂停
|
2025-01-12 19:14:25 +08:00
|
|
|
audioService.on('pause', () => {
|
2025-03-08 18:31:46 +08:00
|
|
|
console.log('音频暂停事件触发');
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.setPlayMusic(false);
|
2025-01-16 23:19:16 +08:00
|
|
|
clearInterval();
|
2025-01-01 02:25:18 +08:00
|
|
|
if (isElectron && isLyricWindowOpen.value) {
|
2024-12-16 22:12:28 +08:00
|
|
|
sendLyricToWin();
|
|
|
|
|
}
|
2024-12-12 22:18:52 +08:00
|
|
|
});
|
|
|
|
|
|
2025-01-17 22:34:49 +08:00
|
|
|
const replayMusic = async () => {
|
|
|
|
|
try {
|
|
|
|
|
// 如果当前有音频实例,先停止并销毁
|
|
|
|
|
if (sound.value) {
|
|
|
|
|
sound.value.stop();
|
|
|
|
|
sound.value.unload();
|
|
|
|
|
sound.value = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重新播放当前歌曲
|
2025-03-19 22:48:28 +08:00
|
|
|
if (playerStore.playMusicUrl && playMusic.value) {
|
|
|
|
|
const newSound = await audioService.play(playerStore.playMusicUrl, playMusic.value);
|
2025-01-17 22:34:49 +08:00
|
|
|
sound.value = newSound as Howl;
|
|
|
|
|
setupAudioListeners();
|
|
|
|
|
} else {
|
|
|
|
|
console.error('No music URL or playMusic data available');
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.nextPlay();
|
2025-01-17 22:34:49 +08:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error replaying song:', error);
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.nextPlay();
|
2025-01-17 22:34:49 +08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2024-12-12 22:18:52 +08:00
|
|
|
// 监听结束
|
2025-01-12 19:14:25 +08:00
|
|
|
audioService.on('end', () => {
|
2025-03-08 18:31:46 +08:00
|
|
|
console.log('音频播放结束事件触发');
|
2025-01-16 23:19:16 +08:00
|
|
|
clearInterval();
|
2025-01-16 00:40:44 +08:00
|
|
|
|
2025-03-19 22:48:28 +08:00
|
|
|
if (playerStore.playMode === 1) {
|
2024-12-15 01:40:13 +08:00
|
|
|
// 单曲循环模式
|
2025-01-16 00:40:44 +08:00
|
|
|
if (sound.value) {
|
2025-01-17 22:34:49 +08:00
|
|
|
replayMusic();
|
2025-01-16 00:40:44 +08:00
|
|
|
}
|
2025-03-19 22:48:28 +08:00
|
|
|
} else if (playerStore.playMode === 2) {
|
2024-12-29 00:43:39 +08:00
|
|
|
// 随机播放模式
|
2025-03-19 22:48:28 +08:00
|
|
|
|
|
|
|
|
if (playerStore.playList.length <= 1) {
|
2025-01-17 22:34:49 +08:00
|
|
|
replayMusic();
|
2024-12-29 00:43:39 +08:00
|
|
|
} else {
|
|
|
|
|
let randomIndex;
|
|
|
|
|
do {
|
2025-03-19 22:48:28 +08:00
|
|
|
randomIndex = Math.floor(Math.random() * playerStore.playList.length);
|
|
|
|
|
} while (randomIndex === playerStore.playListIndex && playerStore.playList.length > 1);
|
|
|
|
|
playerStore.playListIndex = randomIndex;
|
|
|
|
|
playerStore.setPlay(playerStore.playList[randomIndex]);
|
2024-12-29 00:43:39 +08:00
|
|
|
}
|
2024-12-15 01:40:13 +08:00
|
|
|
} else {
|
|
|
|
|
// 列表循环模式
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.nextPlay();
|
2024-12-15 01:40:13 +08:00
|
|
|
}
|
2024-12-12 22:18:52 +08:00
|
|
|
});
|
2025-01-12 19:14:25 +08:00
|
|
|
|
2025-01-16 23:19:16 +08:00
|
|
|
return clearInterval;
|
2024-12-12 22:18:52 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const play = () => {
|
|
|
|
|
audioService.getCurrentSound()?.play();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const pause = () => {
|
2025-03-08 18:31:46 +08:00
|
|
|
const currentSound = audioService.getCurrentSound();
|
|
|
|
|
if (currentSound) {
|
|
|
|
|
try {
|
|
|
|
|
// 保存当前播放进度
|
|
|
|
|
const currentTime = currentSound.seek() as number;
|
2025-03-19 22:48:28 +08:00
|
|
|
if (playerStore.playMusic && playerStore.playMusic.id) {
|
2025-03-08 18:31:46 +08:00
|
|
|
localStorage.setItem(
|
|
|
|
|
'playProgress',
|
|
|
|
|
JSON.stringify({
|
2025-03-19 22:48:28 +08:00
|
|
|
songId: playerStore.playMusic.id,
|
2025-03-08 18:31:46 +08:00
|
|
|
progress: currentTime
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentSound.pause();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('暂停播放出错:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-12 22:18:52 +08:00
|
|
|
};
|
|
|
|
|
|
2023-12-17 14:48:21 +08:00
|
|
|
// 增加矫正时间
|
2024-10-18 18:37:53 +08:00
|
|
|
export const addCorrectionTime = (time: number) => (correctionTime.value += time);
|
2023-12-17 14:48:21 +08:00
|
|
|
|
|
|
|
|
// 减少矫正时间
|
2024-10-18 18:37:53 +08:00
|
|
|
export const reduceCorrectionTime = (time: number) => (correctionTime.value -= time);
|
2023-12-17 14:48:21 +08:00
|
|
|
|
2024-10-18 18:37:53 +08:00
|
|
|
// 获取当前播放歌词
|
|
|
|
|
export const isCurrentLrc = (index: number, time: number): boolean => {
|
|
|
|
|
const currentTime = lrcTimeArray.value[index];
|
|
|
|
|
const nextTime = lrcTimeArray.value[index + 1];
|
2024-05-16 18:54:30 +08:00
|
|
|
const nowTime = time + correctionTime.value;
|
|
|
|
|
const isTrue = nowTime > currentTime && nowTime < nextTime;
|
|
|
|
|
return isTrue;
|
|
|
|
|
};
|
|
|
|
|
|
2024-10-18 18:37:53 +08:00
|
|
|
// 获取当前播放歌词INDEX
|
|
|
|
|
export const getLrcIndex = (time: number): number => {
|
2024-05-16 18:54:30 +08:00
|
|
|
for (let i = 0; i < lrcTimeArray.value.length; i++) {
|
|
|
|
|
if (isCurrentLrc(i, time)) {
|
2024-10-18 18:37:53 +08:00
|
|
|
nowIndex.value = i;
|
2024-05-16 18:54:30 +08:00
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nowIndex.value;
|
|
|
|
|
};
|
2023-12-17 14:48:21 +08:00
|
|
|
|
2024-12-14 13:15:59 +08:00
|
|
|
// 获取当前播放歌词进度
|
2024-10-18 18:37:53 +08:00
|
|
|
const currentLrcTiming = computed(() => {
|
|
|
|
|
const start = lrcTimeArray.value[nowIndex.value] || 0;
|
|
|
|
|
const end = lrcTimeArray.value[nowIndex.value + 1] || start + 1;
|
|
|
|
|
return { start, end };
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 获取歌词样式
|
|
|
|
|
export const getLrcStyle = (index: number) => {
|
|
|
|
|
if (index === nowIndex.value) {
|
|
|
|
|
return {
|
|
|
|
|
backgroundImage: `linear-gradient(to right, #ffffff ${currentLrcProgress.value}%, #ffffff8a ${currentLrcProgress.value}%)`,
|
|
|
|
|
backgroundClip: 'text',
|
|
|
|
|
WebkitBackgroundClip: 'text',
|
|
|
|
|
color: 'transparent',
|
2025-01-01 02:25:18 +08:00
|
|
|
transition: 'background-image 0.1s linear'
|
2024-10-18 18:37:53 +08:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return {};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 播放进度
|
|
|
|
|
export const useLyricProgress = () => {
|
2025-03-08 18:31:46 +08:00
|
|
|
// 如果已经在全局更新进度,立即返回
|
2024-10-18 18:37:53 +08:00
|
|
|
return {
|
2025-01-01 02:25:18 +08:00
|
|
|
getLrcStyle
|
2024-10-18 18:37:53 +08:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2024-12-29 00:43:39 +08:00
|
|
|
// 设置当前播放时间
|
2024-12-12 22:18:52 +08:00
|
|
|
export const setAudioTime = (index: number) => {
|
|
|
|
|
const currentSound = sound.value;
|
|
|
|
|
if (!currentSound) return;
|
|
|
|
|
|
|
|
|
|
currentSound.seek(lrcTimeArray.value[index]);
|
|
|
|
|
currentSound.play();
|
2024-05-16 18:54:30 +08:00
|
|
|
};
|
2023-12-17 14:48:21 +08:00
|
|
|
|
2024-05-16 18:54:30 +08:00
|
|
|
// 获取当前播放的歌词
|
|
|
|
|
export const getCurrentLrc = () => {
|
|
|
|
|
const index = getLrcIndex(nowTime.value);
|
2024-10-18 18:37:53 +08:00
|
|
|
return {
|
|
|
|
|
currentLrc: lrcArray.value[index],
|
2025-01-01 02:25:18 +08:00
|
|
|
nextLrc: lrcArray.value[index + 1]
|
2024-10-18 18:37:53 +08:00
|
|
|
};
|
2024-05-16 18:54:30 +08:00
|
|
|
};
|
|
|
|
|
|
2024-12-12 22:18:52 +08:00
|
|
|
// 获取一句歌词播放时间几秒到几秒
|
2024-10-18 18:37:53 +08:00
|
|
|
export const getLrcTimeRange = (index: number) => ({
|
|
|
|
|
currentTime: lrcTimeArray.value[index],
|
2025-01-01 02:25:18 +08:00
|
|
|
nextTime: lrcTimeArray.value[index + 1]
|
2024-10-18 18:37:53 +08:00
|
|
|
});
|
2024-05-16 18:54:30 +08:00
|
|
|
|
2024-12-06 23:50:44 +08:00
|
|
|
// 监听歌词数组变化,当切换歌曲时重新初始化歌词窗口
|
|
|
|
|
watch(
|
|
|
|
|
() => lrcArray.value,
|
|
|
|
|
(newLrcArray) => {
|
2025-01-01 02:25:18 +08:00
|
|
|
if (newLrcArray.length > 0 && isElectron && isLyricWindowOpen.value) {
|
2024-12-06 23:50:44 +08:00
|
|
|
sendLyricToWin();
|
|
|
|
|
}
|
2025-01-01 02:25:18 +08:00
|
|
|
}
|
2024-12-06 23:50:44 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 发送歌词更新数据
|
2024-12-16 22:12:28 +08:00
|
|
|
export const sendLyricToWin = () => {
|
2025-01-01 02:25:18 +08:00
|
|
|
if (!isElectron || !isLyricWindowOpen.value) {
|
2025-03-08 19:00:50 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查是否有播放的歌曲
|
|
|
|
|
if (!playMusic.value || !playMusic.value.id) {
|
2024-12-16 22:12:28 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-10-18 18:37:53 +08:00
|
|
|
|
2024-05-16 18:54:30 +08:00
|
|
|
try {
|
2025-03-08 19:00:50 +08:00
|
|
|
// 记录歌词发送状态
|
|
|
|
|
if (lrcArray.value && lrcArray.value.length > 0) {
|
2024-05-16 18:54:30 +08:00
|
|
|
const nowIndex = getLrcIndex(nowTime.value);
|
2025-03-08 19:00:50 +08:00
|
|
|
// 构建完整的歌词更新数据
|
2024-12-06 23:50:44 +08:00
|
|
|
const updateData = {
|
2024-12-16 22:12:28 +08:00
|
|
|
type: 'full',
|
2024-05-16 18:54:30 +08:00
|
|
|
nowIndex,
|
|
|
|
|
nowTime: nowTime.value,
|
2025-03-08 19:00:50 +08:00
|
|
|
startCurrentTime: lrcTimeArray.value[nowIndex] || 0,
|
|
|
|
|
nextTime: lrcTimeArray.value[nowIndex + 1] || 0,
|
2025-03-19 22:48:28 +08:00
|
|
|
isPlay: playerStore.play,
|
2024-12-16 22:12:28 +08:00
|
|
|
lrcArray: lrcArray.value,
|
|
|
|
|
lrcTimeArray: lrcTimeArray.value,
|
|
|
|
|
allTime: allTime.value,
|
2025-01-01 02:25:18 +08:00
|
|
|
playMusic: playMusic.value
|
2024-05-16 18:54:30 +08:00
|
|
|
};
|
2025-03-08 19:00:50 +08:00
|
|
|
|
|
|
|
|
// 发送数据到歌词窗口
|
2025-01-01 02:25:18 +08:00
|
|
|
window.api.sendLyric(JSON.stringify(updateData));
|
2025-03-08 19:00:50 +08:00
|
|
|
} else {
|
|
|
|
|
console.log('No lyric data available, sending empty lyric message');
|
|
|
|
|
|
|
|
|
|
// 发送没有歌词的提示
|
|
|
|
|
const emptyLyricData = {
|
|
|
|
|
type: 'empty',
|
|
|
|
|
nowIndex: 0,
|
|
|
|
|
nowTime: nowTime.value,
|
|
|
|
|
startCurrentTime: 0,
|
|
|
|
|
nextTime: 0,
|
2025-03-19 22:48:28 +08:00
|
|
|
isPlay: playerStore.play,
|
2025-03-08 19:00:50 +08:00
|
|
|
lrcArray: [{ text: '当前歌曲暂无歌词', trText: '' }],
|
|
|
|
|
lrcTimeArray: [0],
|
|
|
|
|
allTime: allTime.value,
|
|
|
|
|
playMusic: playMusic.value
|
|
|
|
|
};
|
|
|
|
|
window.api.sendLyric(JSON.stringify(emptyLyricData));
|
2024-05-16 18:54:30 +08:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2024-12-06 23:50:44 +08:00
|
|
|
console.error('Error sending lyric update:', error);
|
2024-05-16 18:54:30 +08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-03-08 19:00:50 +08:00
|
|
|
// 歌词同步定时器
|
|
|
|
|
let lyricSyncInterval: any = null;
|
|
|
|
|
|
|
|
|
|
// 开始歌词同步
|
|
|
|
|
const startLyricSync = () => {
|
|
|
|
|
// 清除已有的定时器
|
|
|
|
|
if (lyricSyncInterval) {
|
|
|
|
|
clearInterval(lyricSyncInterval);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 每秒同步一次歌词数据
|
|
|
|
|
lyricSyncInterval = setInterval(() => {
|
2025-03-19 22:48:28 +08:00
|
|
|
if (isElectron && isLyricWindowOpen.value && playerStore.play && playMusic.value?.id) {
|
2025-03-08 19:00:50 +08:00
|
|
|
// 发送当前播放进度的更新
|
|
|
|
|
try {
|
|
|
|
|
const updateData = {
|
|
|
|
|
type: 'update',
|
|
|
|
|
nowIndex: getLrcIndex(nowTime.value),
|
|
|
|
|
nowTime: nowTime.value,
|
2025-03-19 22:48:28 +08:00
|
|
|
isPlay: playerStore.play
|
2025-03-08 19:00:50 +08:00
|
|
|
};
|
|
|
|
|
window.api.sendLyric(JSON.stringify(updateData));
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('发送歌词进度更新失败:', error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, 1000);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 停止歌词同步
|
|
|
|
|
const stopLyricSync = () => {
|
|
|
|
|
if (lyricSyncInterval) {
|
|
|
|
|
clearInterval(lyricSyncInterval);
|
|
|
|
|
lyricSyncInterval = null;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 修改openLyric函数,添加定时同步
|
2024-05-16 18:54:30 +08:00
|
|
|
export const openLyric = () => {
|
2025-01-01 02:25:18 +08:00
|
|
|
if (!isElectron) return;
|
2025-03-08 19:00:50 +08:00
|
|
|
|
|
|
|
|
// 检查是否有播放中的歌曲
|
|
|
|
|
if (!playMusic.value || !playMusic.value.id) {
|
|
|
|
|
console.log('没有正在播放的歌曲,无法打开歌词窗口');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-16 22:12:28 +08:00
|
|
|
console.log('Opening lyric window with current song:', playMusic.value?.name);
|
2024-12-16 22:25:38 +08:00
|
|
|
|
|
|
|
|
isLyricWindowOpen.value = !isLyricWindowOpen.value;
|
|
|
|
|
if (isLyricWindowOpen.value) {
|
2025-03-08 19:00:50 +08:00
|
|
|
// 立即打开窗口
|
|
|
|
|
window.api.openLyric();
|
|
|
|
|
|
|
|
|
|
// 确保有歌词数据,如果没有,则使用默认的"无歌词"提示
|
|
|
|
|
if (!lrcArray.value || lrcArray.value.length === 0) {
|
|
|
|
|
// 如果当前播放的歌曲有ID但没有歌词,则尝试加载歌词
|
|
|
|
|
console.log('尝试加载歌词数据...');
|
|
|
|
|
// 发送默认的"无歌词"数据
|
|
|
|
|
const emptyLyricData = {
|
|
|
|
|
type: 'empty',
|
|
|
|
|
nowIndex: 0,
|
|
|
|
|
nowTime: nowTime.value,
|
|
|
|
|
startCurrentTime: 0,
|
|
|
|
|
nextTime: 0,
|
2025-03-19 22:48:28 +08:00
|
|
|
isPlay: playerStore.play,
|
2025-03-08 19:00:50 +08:00
|
|
|
lrcArray: [{ text: '加载歌词中...', trText: '' }],
|
|
|
|
|
lrcTimeArray: [0],
|
|
|
|
|
allTime: allTime.value,
|
|
|
|
|
playMusic: playMusic.value
|
|
|
|
|
};
|
|
|
|
|
window.api.sendLyric(JSON.stringify(emptyLyricData));
|
|
|
|
|
} else {
|
|
|
|
|
// 发送完整歌词数据
|
|
|
|
|
sendLyricToWin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置定时器,确保500ms后再次发送数据,以防窗口加载延迟
|
2024-12-16 22:25:38 +08:00
|
|
|
setTimeout(() => {
|
2024-12-16 22:12:28 +08:00
|
|
|
sendLyricToWin();
|
2024-12-16 22:25:38 +08:00
|
|
|
}, 500);
|
2025-03-08 19:00:50 +08:00
|
|
|
|
|
|
|
|
// 启动歌词同步
|
|
|
|
|
startLyricSync();
|
2024-12-16 22:25:38 +08:00
|
|
|
} else {
|
|
|
|
|
closeLyric();
|
2025-03-08 19:00:50 +08:00
|
|
|
// 停止歌词同步
|
|
|
|
|
stopLyricSync();
|
2024-12-16 22:25:38 +08:00
|
|
|
}
|
2024-05-16 18:54:30 +08:00
|
|
|
};
|
2024-12-16 22:12:28 +08:00
|
|
|
|
2025-03-08 19:00:50 +08:00
|
|
|
// 修改closeLyric函数,确保停止定时同步
|
2024-12-16 22:12:28 +08:00
|
|
|
export const closeLyric = () => {
|
2025-01-01 02:25:18 +08:00
|
|
|
if (!isElectron) return;
|
2025-03-08 19:00:50 +08:00
|
|
|
isLyricWindowOpen.value = false; // 确保状态更新
|
2024-12-16 22:12:28 +08:00
|
|
|
windowData.electron.ipcRenderer.send('close-lyric');
|
2025-03-08 19:00:50 +08:00
|
|
|
|
|
|
|
|
// 停止歌词同步
|
|
|
|
|
stopLyricSync();
|
2024-12-16 22:12:28 +08:00
|
|
|
};
|
|
|
|
|
|
2025-03-08 19:00:50 +08:00
|
|
|
// 在组件挂载时设置对播放状态的监听
|
|
|
|
|
watch(
|
2025-03-19 22:48:28 +08:00
|
|
|
() => playerStore.play,
|
2025-03-08 19:00:50 +08:00
|
|
|
(isPlaying) => {
|
|
|
|
|
// 如果歌词窗口打开,根据播放状态控制同步
|
|
|
|
|
if (isElectron && isLyricWindowOpen.value) {
|
|
|
|
|
if (isPlaying) {
|
|
|
|
|
startLyricSync();
|
|
|
|
|
} else {
|
|
|
|
|
// 如果暂停播放,发送一次暂停状态的更新
|
|
|
|
|
const pauseData = {
|
|
|
|
|
type: 'update',
|
|
|
|
|
isPlay: false
|
|
|
|
|
};
|
|
|
|
|
window.api.sendLyric(JSON.stringify(pauseData));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 在组件卸载时清理资源
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
stopLyricSync();
|
|
|
|
|
});
|
|
|
|
|
|
2024-12-16 22:12:28 +08:00
|
|
|
// 添加播放控制命令监听
|
2025-01-01 02:25:18 +08:00
|
|
|
if (isElectron) {
|
|
|
|
|
windowData.electron.ipcRenderer.on('lyric-control-back', (_, command: string) => {
|
2024-12-16 22:12:28 +08:00
|
|
|
switch (command) {
|
|
|
|
|
case 'playpause':
|
2025-03-19 22:48:28 +08:00
|
|
|
if (playerStore.play) {
|
|
|
|
|
playerStore.setPlayMusic(false);
|
2024-12-16 22:12:28 +08:00
|
|
|
audioService.getCurrentSound()?.pause();
|
|
|
|
|
} else {
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.setPlayMusic(true);
|
|
|
|
|
|
2024-12-16 22:12:28 +08:00
|
|
|
audioService.getCurrentSound()?.play();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'prev':
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.prevPlay();
|
2024-12-16 22:12:28 +08:00
|
|
|
break;
|
|
|
|
|
case 'next':
|
2025-03-19 22:48:28 +08:00
|
|
|
playerStore.nextPlay();
|
2024-12-16 22:12:28 +08:00
|
|
|
break;
|
|
|
|
|
case 'close':
|
2025-03-08 19:00:50 +08:00
|
|
|
isLyricWindowOpen.value = false; // 确保状态更新
|
2024-12-16 22:12:28 +08:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
console.log('Unknown command:', command);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2025-01-12 19:14:25 +08:00
|
|
|
|
|
|
|
|
// 在组件挂载时设置监听器
|
2025-03-21 00:19:15 +08:00
|
|
|
export const initAudioListeners = async () => {
|
|
|
|
|
try {
|
|
|
|
|
// 确保有正在播放的音乐
|
|
|
|
|
if (!playerStore.playMusic || !playerStore.playMusic.id) {
|
|
|
|
|
console.log('没有正在播放的音乐,跳过音频监听器初始化');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确保有音频实例
|
|
|
|
|
const initialSound = audioService.getCurrentSound();
|
|
|
|
|
if (!initialSound) {
|
|
|
|
|
console.log('没有音频实例,等待音频加载...');
|
|
|
|
|
// 等待音频加载完成
|
|
|
|
|
await new Promise<void>((resolve) => {
|
|
|
|
|
const checkInterval = setInterval(() => {
|
|
|
|
|
const sound = audioService.getCurrentSound();
|
|
|
|
|
if (sound) {
|
|
|
|
|
clearInterval(checkInterval);
|
|
|
|
|
resolve();
|
|
|
|
|
}
|
|
|
|
|
}, 100);
|
|
|
|
|
|
|
|
|
|
// 设置超时
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
clearInterval(checkInterval);
|
|
|
|
|
console.log('等待音频加载超时');
|
|
|
|
|
resolve();
|
|
|
|
|
}, 5000);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化音频监听器
|
|
|
|
|
setupAudioListeners();
|
2025-03-08 19:00:50 +08:00
|
|
|
|
2025-03-21 00:19:15 +08:00
|
|
|
// 监听歌词窗口关闭事件
|
|
|
|
|
if (isElectron) {
|
|
|
|
|
window.api.onLyricWindowClosed(() => {
|
|
|
|
|
isLyricWindowOpen.value = false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取最新的音频实例
|
|
|
|
|
const finalSound = audioService.getCurrentSound();
|
|
|
|
|
if (finalSound) {
|
|
|
|
|
// 更新全局 sound 引用
|
|
|
|
|
sound.value = finalSound;
|
|
|
|
|
|
|
|
|
|
// 如果当前处于播放状态,启动进度更新
|
|
|
|
|
if (playerStore.play) {
|
|
|
|
|
// 如果有保存的播放进度,应用它
|
|
|
|
|
if (playerStore.savedPlayProgress !== undefined) {
|
|
|
|
|
try {
|
|
|
|
|
// 设置音频位置
|
|
|
|
|
finalSound.seek(playerStore.savedPlayProgress);
|
|
|
|
|
// 同时更新时间显示
|
|
|
|
|
nowTime.value = playerStore.savedPlayProgress;
|
|
|
|
|
console.log('恢复播放进度:', playerStore.savedPlayProgress);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('恢复播放进度失败:', e);
|
|
|
|
|
}
|
2025-03-08 18:31:46 +08:00
|
|
|
}
|
|
|
|
|
|
2025-03-21 00:19:15 +08:00
|
|
|
startProgressAnimation();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
console.warn('无法获取音频实例,跳过进度更新初始化');
|
2025-03-08 18:31:46 +08:00
|
|
|
}
|
2025-03-21 00:19:15 +08:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error('初始化音频监听器失败:', error);
|
2025-03-08 18:31:46 +08:00
|
|
|
}
|
2025-03-21 00:19:15 +08:00
|
|
|
};
|