diff --git a/app.js b/app.js index c2c1839..69be6f5 100644 --- a/app.js +++ b/app.js @@ -66,7 +66,7 @@ function createWindow() { store.set('set', setJson); } - loadLyricWindow(ipcMain); + loadLyricWindow(ipcMain, mainWin); } // 限制只能启动一个应用 diff --git a/electron/lyric.js b/electron/lyric.js index 0815cc9..ba03366 100644 --- a/electron/lyric.js +++ b/electron/lyric.js @@ -1,11 +1,11 @@ -const { BrowserWindow, screen } = require('electron'); +const { BrowserWindow, screen, ipcRenderer } = require('electron'); const path = require('path'); const config = require('./config'); let lyricWindow = null; -let isDragging = false; const createWin = () => { + console.log('Creating lyric window'); lyricWindow = new BrowserWindow({ width: 800, height: 200, @@ -21,16 +21,26 @@ const createWin = () => { webSecurity: false, }, }); + + // 监听窗口关闭事件 + lyricWindow.on('closed', () => { + console.log('Lyric window closed'); + lyricWindow = null; + }); }; -const loadLyricWindow = (ipcMain) => { +const loadLyricWindow = (ipcMain, mainWin) => { ipcMain.on('open-lyric', () => { + console.log('Received open-lyric request'); if (lyricWindow) { + console.log('Lyric window exists, focusing'); if (lyricWindow.isMinimized()) lyricWindow.restore(); lyricWindow.focus(); lyricWindow.show(); return; } + + console.log('Creating new lyric window'); createWin(); if (process.env.NODE_ENV === 'development') { lyricWindow.webContents.openDevTools({ mode: 'detach' }); @@ -41,26 +51,39 @@ const loadLyricWindow = (ipcMain) => { } lyricWindow.setMinimumSize(600, 200); - - // 隐藏任务栏 lyricWindow.setSkipTaskbar(true); - lyricWindow.show(); + lyricWindow.once('ready-to-show', () => { + console.log('Lyric window ready to show'); + lyricWindow.show(); + }); }); ipcMain.on('send-lyric', (e, data) => { - if (lyricWindow) { - lyricWindow.webContents.send('receive-lyric', data); + if (lyricWindow && !lyricWindow.isDestroyed()) { + try { + lyricWindow.webContents.send('receive-lyric', data); + } catch (error) { + console.error('Error processing lyric data:', error); + } + } else { + console.log('Cannot send lyric: window not available or destroyed'); } }); ipcMain.on('top-lyric', (e, data) => { - lyricWindow.setAlwaysOnTop(data); + if (lyricWindow && !lyricWindow.isDestroyed()) { + lyricWindow.setAlwaysOnTop(data); + } }); ipcMain.on('close-lyric', () => { - lyricWindow.close(); - lyricWindow = null; + if (lyricWindow && !lyricWindow.isDestroyed()) { + lyricWindow.webContents.send('lyric-window-close'); + mainWin.webContents.send('lyric-control-back', 'close'); + lyricWindow.close(); + lyricWindow = null; + } }); ipcMain.on('mouseenter-lyric', () => { @@ -71,11 +94,6 @@ const loadLyricWindow = (ipcMain) => { lyricWindow.setIgnoreMouseEvents(false); }); - // 开始拖动 - ipcMain.on('lyric-drag-start', () => { - isDragging = true; - }); - // 处理拖动移动 ipcMain.on('lyric-drag-move', (e, { deltaX, deltaY }) => { if (!lyricWindow) return; @@ -91,11 +109,6 @@ const loadLyricWindow = (ipcMain) => { lyricWindow.setPosition(newX, newY); }); - // 结束拖动 - ipcMain.on('lyric-drag-end', () => { - isDragging = false; - }); - // 添加鼠标穿透事件处理 ipcMain.on('set-ignore-mouse', (e, shouldIgnore) => { if (!lyricWindow) return; @@ -108,6 +121,12 @@ const loadLyricWindow = (ipcMain) => { lyricWindow.setIgnoreMouseEvents(false); } }); + + // 添加播放控制处理 + ipcMain.on('control-back', (e, command) => { + console.log('Received control-back request:', command); + mainWin.webContents.send('lyric-control-back', command); + }); }; module.exports = { diff --git a/src/hooks/MusicHook.ts b/src/hooks/MusicHook.ts index 652719a..d775756 100644 --- a/src/hooks/MusicHook.ts +++ b/src/hooks/MusicHook.ts @@ -17,6 +17,7 @@ export const correctionTime = ref(0.4); // 歌词矫正时间Correction time export const currentLrcProgress = ref(0); // 来存储当前歌词的进度 export const playMusic = computed(() => store.state.playMusic as SongResult); // 当前播放歌曲 export const sound = ref(audioService.getCurrentSound()); +export const isLyricWindowOpen = ref(false); // 新增状态 document.onkeyup = (e) => { // 检查事件目标是否是输入框元素 @@ -53,13 +54,18 @@ watch( watch( () => store.state.playMusic, () => { - nextTick(() => { + nextTick(async () => { lrcArray.value = playMusic.value.lyric?.lrcArray || []; lrcTimeArray.value = playMusic.value.lyric?.lrcTimeArray || []; + // 当歌词数据更新时,如果歌词窗口打开,则发送数据 + if (isElectron.value && isLyricWindowOpen.value && lrcArray.value.length > 0) { + sendLyricToWin(); + } }); }, { deep: true, + immediate: true, }, ); @@ -76,8 +82,13 @@ export const audioServiceOn = (audio: typeof audioService) => { if (newIndex !== nowIndex.value) { nowIndex.value = newIndex; currentLrcProgress.value = 0; + // 当歌词索引更新时,发送歌词数据 + if (isElectron.value && isLyricWindowOpen.value) { + sendLyricToWin(); + } } - if (isElectron.value) { + // 定期发送歌词数据更新 + if (isElectron.value && isLyricWindowOpen.value) { sendLyricToWin(); } }, 50); @@ -87,11 +98,14 @@ export const audioServiceOn = (audio: typeof audioService) => { audio.onPause(() => { store.commit('setPlayMusic', false); clearInterval(interval); + // 暂停时也发送一次状态更新 + if (isElectron.value && isLyricWindowOpen.value) { + sendLyricToWin(); + } }); // 监听结束 audio.onEnd(() => { - handleEnded(); if (store.state.playMode === 1) { // 单曲循环模式 audio.getCurrentSound()?.play(); @@ -213,7 +227,7 @@ export const useLyricProgress = () => { }; }; -// 设置当前播放时间 +// 设置���前播放时间 export const setAudioTime = (index: number) => { const currentSound = sound.value; if (!currentSound) return; @@ -241,72 +255,33 @@ export const getLrcTimeRange = (index: number) => ({ watch( () => lrcArray.value, (newLrcArray) => { - if (newLrcArray.length > 0 && isElectron.value) { - // 重新初始化歌词数据 - initLyricWindow(); - // 发送当前状态 + if (newLrcArray.length > 0 && isElectron.value && isLyricWindowOpen.value) { sendLyricToWin(); } }, ); -// 监听播放状态变化 -watch(isPlaying, (newIsPlaying) => { - if (isElectron.value) { - sendLyricToWin(newIsPlaying); - } -}); - -// 处理歌曲结束 -export const handleEnded = () => { - if (isElectron.value) { - setTimeout(() => { - initLyricWindow(); - sendLyricToWin(); - }, 100); - } -}; - -// 初始化歌词数据 -export const initLyricWindow = () => { - if (!isElectron.value) return; - try { - if (lrcArray.value.length > 0) { - console.log('Initializing lyric window with data:', { - lrcArray: lrcArray.value, - lrcTimeArray: lrcTimeArray.value, - allTime: allTime.value, - }); - - const staticData = { - type: 'init', - lrcArray: lrcArray.value, - lrcTimeArray: lrcTimeArray.value, - allTime: allTime.value, - }; - windowData.electronAPI.sendLyric(JSON.stringify(staticData)); - } else { - console.log('No lyrics available for initialization'); - } - } catch (error) { - console.error('Error initializing lyric window:', error); - } -}; - // 发送歌词更新数据 -export const sendLyricToWin = (isPlay: boolean = true) => { - if (!isElectron.value) return; +export const sendLyricToWin = () => { + if (!isElectron.value || !isLyricWindowOpen.value) { + console.log('Cannot send lyric: electron or lyric window not available'); + return; + } try { if (lrcArray.value.length > 0) { const nowIndex = getLrcIndex(nowTime.value); const updateData = { - type: 'update', + type: 'full', nowIndex, nowTime: nowTime.value, startCurrentTime: lrcTimeArray.value[nowIndex], nextTime: lrcTimeArray.value[nowIndex + 1], - isPlay, + isPlay: isPlaying.value, + lrcArray: lrcArray.value, + lrcTimeArray: lrcTimeArray.value, + allTime: allTime.value, + playMusic: playMusic.value, }; windowData.electronAPI.sendLyric(JSON.stringify(updateData)); } @@ -317,13 +292,55 @@ export const sendLyricToWin = (isPlay: boolean = true) => { export const openLyric = () => { if (!isElectron.value) return; - console.log('Opening lyric window'); + console.log('Opening lyric window with current song:', playMusic.value?.name); windowData.electronAPI.openLyric(); + isLyricWindowOpen.value = true; // 延迟一下初始化,确保窗口已经创建 setTimeout(() => { - console.log('Initializing lyric window after delay'); - initLyricWindow(); - sendLyricToWin(); + if (isLyricWindowOpen.value) { + console.log('Initializing lyric window with data:', { + hasLyrics: lrcArray.value.length > 0, + songName: playMusic.value?.name, + }); + sendLyricToWin(); + } }, 500); }; + +// 添加关闭歌词窗口的方法 +export const closeLyric = () => { + if (!isElectron.value) return; + isLyricWindowOpen.value = false; + windowData.electron.ipcRenderer.send('close-lyric'); +}; + +// 添加播放控制命令监听 +if (isElectron.value) { + windowData.electron.ipcRenderer.on('lyric-control-back', (command: string) => { + console.log('Received playback control command:', command); + switch (command) { + case 'playpause': + if (store.state.play) { + store.commit('setPlayMusic', false); + audioService.getCurrentSound()?.pause(); + } else { + store.commit('setPlayMusic', true); + audioService.getCurrentSound()?.play(); + } + break; + case 'prev': + store.commit('prevPlay'); + break; + case 'next': + store.commit('nextPlay'); + break; + case 'close': + closeLyric(); + break; + default: + console.log('Unknown command:', command); + break; + } + }); +} diff --git a/src/layout/components/PlayBar.vue b/src/layout/components/PlayBar.vue index e90973c..196fe89 100644 --- a/src/layout/components/PlayBar.vue +++ b/src/layout/components/PlayBar.vue @@ -69,7 +69,11 @@ 歌词 @@ -113,7 +117,7 @@ import { useTemplateRef } from 'vue'; import { useStore } from 'vuex'; import SongItem from '@/components/common/SongItem.vue'; -import { allTime, isElectron, nowTime, openLyric, sound } from '@/hooks/MusicHook'; +import { allTime, isElectron, isLyricWindowOpen, nowTime, openLyric, sound } from '@/hooks/MusicHook'; import type { SongResult } from '@/type/music'; import { getImgUrl, secondToMinute, setAnimationClass } from '@/utils'; @@ -253,6 +257,10 @@ const toggleFavorite = async (e: Event) => { store.commit('addToFavorite', playMusic.value.id); } }; + +const openLyricWindow = () => { + openLyric(); +};