diff --git a/src/background.js b/src/background.js index 1a98c6b..9d0b42a 100644 --- a/src/background.js +++ b/src/background.js @@ -32,6 +32,7 @@ import express from 'express'; import expressProxy from 'express-http-proxy'; import Store from 'electron-store'; import { createMpris } from '@/electron/mpris'; +import { spawn } from 'child_process'; const clc = require('cli-color'); const log = text => { console.log(`${clc.blueBright('[background.js]')} ${text}`); @@ -420,6 +421,20 @@ class Background { registerGlobalShortcut(this.window, this.store); } + // try to start osdlyrics process on start + if (this.store.get('settings.enableOsdlyricsSupport')) { + log('try to start osdlyrics process'); + const osdlyricsProcess = spawn('osdlyrics'); + + osdlyricsProcess.on('error', err => { + log(`failed to start osdlyrics: ${err.message}`); + }); + + osdlyricsProcess.on('exit', (code, signal) => { + log(`osdlyrics process exited with code ${code}, signal ${signal}`); + }); + } + // create mpris if (isCreateMpris) { createMpris(this.window); diff --git a/src/electron/ipcMain.js b/src/electron/ipcMain.js index 4310342..ecac0f3 100644 --- a/src/electron/ipcMain.js +++ b/src/electron/ipcMain.js @@ -5,6 +5,8 @@ import cloneDeep from 'lodash/cloneDeep'; import shortcuts from '@/utils/shortcuts'; import { createMenu } from './menu'; import { isCreateTray, isMac } from '@/utils/platform'; +import { resolve } from 'path'; +import { existsSync, mkdirSync, writeFileSync } from 'fs'; const clc = require('cli-color'); const log = text => { @@ -309,6 +311,15 @@ export function initIpcMain(win, store, trayEventEmitter) { registerGlobalShortcut(win, store); }); + ipcMain.on('saveLyric', (event, { name, lyric }) => { + let lyricsDirPath = resolve(process.env.HOME, '.lyrics'); + if (!existsSync(lyricsDirPath)) mkdirSync(lyricsDirPath); + if (!existsSync(resolve(lyricsDirPath, name + '.lrc'))) { + writeFileSync(resolve(lyricsDirPath, name + '.lrc'), lyric); + } + win.webContents.send('saveLyricFinished'); + }); + if (isCreateTray) { ipcMain.on('updateTrayTooltip', (_, title) => { trayEventEmitter.emit('updateTooltip', title); diff --git a/src/electron/mpris.js b/src/electron/mpris.js index 2ea5073..d1c400d 100644 --- a/src/electron/mpris.js +++ b/src/electron/mpris.js @@ -28,6 +28,8 @@ export function createMpris(window) { }); ipcMain.on('metadata', (e, metadata) => { + // 更新 Mpris 状态前将位置设为0, 否则 OSDLyrics 获取到的进度是上首音乐切换时的进度 + player.getPosition = () => 0; player.metadata = { 'mpris:trackid': player.objectPath('track/' + metadata.trackId), 'mpris:artUrl': metadata.artwork[0].src, diff --git a/src/locale/lang/en.js b/src/locale/lang/en.js index fb57890..63c006f 100644 --- a/src/locale/lang/en.js +++ b/src/locale/lang/en.js @@ -180,6 +180,10 @@ export default { exit: 'Exit', minimizeToTray: 'Minimize to tray', }, + enableOsdlyricsSupport: { + title: 'desktop lyrics support', + desc: 'Only takes effect under Linux. After enable, I will download the lyrics file to the local, and try to launch OSDLyrics at startup', + }, unm: { enable: 'Enable', audioSource: { diff --git a/src/locale/lang/zh-CN.js b/src/locale/lang/zh-CN.js index 3a01a29..ecb9fb2 100644 --- a/src/locale/lang/zh-CN.js +++ b/src/locale/lang/zh-CN.js @@ -181,6 +181,10 @@ export default { exit: '退出', minimizeToTray: '最小化到托盘', }, + enableOsdlyricsSupport: { + title: '桌面歌词支持', + desc: '仅 Linux 下生效,开启后将会下载歌词文件到本地,并会尝试在启动时拉起 OSDLyrics。', + }, unm: { enable: '启用', audioSource: { diff --git a/src/locale/lang/zh-TW.js b/src/locale/lang/zh-TW.js index 04b74f2..0a2e9ee 100644 --- a/src/locale/lang/zh-TW.js +++ b/src/locale/lang/zh-TW.js @@ -178,6 +178,10 @@ export default { exit: '退出', minimizeToTray: '最小化到工作列角落', }, + enableOsdlyricsSupport: { + title: '桌面歌詞支持', + desc: '僅 Linux 下生效,開啟後將會下載歌詞文件到本地,並會嘗試在啟動時拉起 OSDLyrics', + }, unm: { enable: '啟用', audioSource: { diff --git a/src/store/initLocalStorage.js b/src/store/initLocalStorage.js index d5b3005..ce0e802 100644 --- a/src/store/initLocalStorage.js +++ b/src/store/initLocalStorage.js @@ -23,6 +23,7 @@ let localStorage = { nyancatStyle: false, showLyricsTranslation: true, lyricsBackground: true, + enableOsdlyricsSupport: false, closeAppOption: 'ask', enableDiscordRichPresence: false, enableGlobalShortcut: true, diff --git a/src/utils/Player.js b/src/utils/Player.js index 21c90f6..668176a 100644 --- a/src/utils/Player.js +++ b/src/utils/Player.js @@ -3,7 +3,7 @@ import { getArtist } from '@/api/artist'; import { trackScrobble, trackUpdateNowPlaying } from '@/api/lastfm'; import { fmTrash, personalFM } from '@/api/others'; import { getPlaylistDetail, intelligencePlaylist } from '@/api/playlist'; -import { getMP3, getTrackDetail, scrobble } from '@/api/track'; +import { getLyric, getMP3, getTrackDetail, scrobble } from '@/api/track'; import store from '@/store'; import { isAccountLoggedIn } from '@/utils/auth'; import { cacheTrackSource, getTrackSource } from '@/utils/db'; @@ -616,9 +616,29 @@ export default class { navigator.mediaSession.metadata = new window.MediaMetadata(metadata); if (isCreateMpris) { - ipcRenderer?.send('metadata', metadata); + this._updateMprisState(track, metadata); } } + // OSDLyrics 会检测 Mpris 状态并寻找对应歌词文件,所以要在更新 Mpris 状态之前保证歌词下载完成 + async _updateMprisState(track, metadata) { + if (!store.state.settings.enableOsdlyricsSupport) { + return ipcRenderer?.send('metadata', metadata); + } + + let lyricName = track.ar.map(ar => ar.name).join(', ') + '-' + track.name; + let lyricContent = await getLyric(track.id); + + if (!lyricContent.lrc.lyric) { + return ipcRenderer?.send('metadata', metadata); + } + ipcRenderer.send('saveLyric', { + name: lyricName, + lyric: lyricContent.lrc.lyric, + }); + ipcRenderer.on('saveLyricFinished', () => { + ipcRenderer?.send('metadata', metadata); + }); + } _updateMediaSessionPositionState() { if ('mediaSession' in navigator === false) { return; diff --git a/src/views/settings.vue b/src/views/settings.vue index c25d441..c40fe54 100644 --- a/src/views/settings.vue +++ b/src/views/settings.vue @@ -239,6 +239,31 @@ +
+
+
+ {{ $t('settings.unm.enable') }} + OSDLyrics + {{ $t('settings.enableOsdlyricsSupport.title') }} +
+
+ {{ $t('settings.enableOsdlyricsSupport.desc') }} +
+
+
+
+ + +
+
+

UnblockNeteaseMusic

@@ -963,6 +988,17 @@ export default { }); }, }, + enableOsdlyricsSupport: { + get() { + return this.settings.enableOsdlyricsSupport; + }, + set(value) { + this.$store.commit('updateSettings', { + key: 'enableOsdlyricsSupport', + value, + }); + }, + }, closeAppOption: { get() { return this.settings.closeAppOption;