Skip to content

Commit

Permalink
Merge pull request qier222#1818 from Revincx/revincx-pr
Browse files Browse the repository at this point in the history
  • Loading branch information
pan93412 authored Aug 26, 2023
2 parents f2f4e2c + 486b04b commit fd40a29
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 8 deletions.
Binary file added public/img/icons/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
18 changes: 17 additions & 1 deletion src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import { EventEmitter } from 'events';
import express from 'express';
import expressProxy from 'express-http-proxy';
import Store from 'electron-store';
import { createMpris } from '@/electron/mpris';
import { createMpris, createDbus } from '@/electron/mpris';
import { spawn } from 'child_process';
const clc = require('cli-color');
const log = text => {
console.log(`${clc.blueBright('[background.js]')} ${text}`);
Expand Down Expand Up @@ -420,6 +421,21 @@ class Background {
registerGlobalShortcut(this.window, this.store);
}

// try to start osdlyrics process on start
if (this.store.get('settings.enableOsdlyricsSupport')) {
await createDbus(this.window);
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);
Expand Down
31 changes: 31 additions & 0 deletions src/electron/mpris.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import dbus from 'dbus-next';
import { ipcMain, app } from 'electron';

export function createMpris(window) {
Expand Down Expand Up @@ -28,6 +29,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,
Expand All @@ -41,6 +44,11 @@ export function createMpris(window) {

ipcMain.on('playerCurrentTrackTime', (e, position) => {
player.getPosition = () => position * 1000 * 1000;
player.seeked(position * 1000 * 1000);
});

ipcMain.on('seeked', (e, position) => {
player.seeked(position * 1000 * 1000);
});

ipcMain.on('switchRepeatMode', (e, mode) => {
Expand All @@ -61,3 +69,26 @@ export function createMpris(window) {
player.shuffle = shuffle;
});
}

export async function createDbus(window) {
const bus = dbus.sessionBus();
const Variant = dbus.Variant;

const osdService = await bus.getProxyObject(
'org.osdlyrics.Daemon',
'/org/osdlyrics/Lyrics'
);

const osdInterface = osdService.getInterface('org.osdlyrics.Lyrics');

ipcMain.on('sendLyrics', async (e, { track, lyrics }) => {
const metadata = {
title: new Variant('s', track.name),
artist: new Variant('s', track.ar.map(ar => ar.name).join(', ')),
};

await osdInterface.SetLyricContent(metadata, Buffer.from(lyrics));

window.webContents.send('saveLyricFinished');
});
}
7 changes: 5 additions & 2 deletions src/electron/tray.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* global __static */
import path from 'path';
import { app, nativeImage, Tray, Menu } from 'electron';
import { app, nativeImage, Tray, Menu, nativeTheme } from 'electron';
import { isLinux } from '@/utils/platform';

function createMenuTemplate(win) {
Expand Down Expand Up @@ -197,8 +197,11 @@ class YPMTrayWindowsImpl {
}

export function createTray(win, eventEmitter) {
// 感觉图标颜色应该不属于界面主题范畴,只需要跟随系统主题
let iconTheme = nativeTheme.shouldUseDarkColors ? 'light' : 'dark';

let icon = nativeImage
.createFromPath(path.join(__static, 'img/icons/[email protected]'))
.createFromPath(path.join(__static, `img/icons/menu-${iconTheme}@88.png`))
.resize({
height: 20,
width: 20,
Expand Down
7 changes: 7 additions & 0 deletions src/locale/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ export default {
exit: 'Exit',
minimizeToTray: 'Minimize to tray',
},
enableOsdlyricsSupport: {
title: 'desktop lyrics support',
desc1:
'Only takes effect under Linux. After enabled, it downloads the lyrics file to the local, and tries to launch OSDLyrics at startup.',
desc2:
'Please ensure that you have installed OSDLyrics before turning on this.',
},
unm: {
enable: 'Enable',
audioSource: {
Expand Down
6 changes: 6 additions & 0 deletions src/locale/lang/zh-CN.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ export default {
exit: '退出',
minimizeToTray: '最小化到托盘',
},
enableOsdlyricsSupport: {
title: '桌面歌词支持',
desc1:
'仅 Linux 下生效。启用后会将歌词文件下载到本地,并在开启播放器时尝试拉起 OSDLyrics。',
desc2: '请在开启之前确保您已经正确安装了 OSDLyrics。',
},
unm: {
enable: '启用',
audioSource: {
Expand Down
6 changes: 6 additions & 0 deletions src/locale/lang/zh-TW.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ export default {
exit: '退出',
minimizeToTray: '最小化到工作列角落',
},
enableOsdlyricsSupport: {
title: '桌面歌詞支援',
desc1:
'只在 Linux 環境下生效。啟用後會將歌詞檔案下載至本機位置,並在開啟播放器時嘗試連帶啟動 OSDLyrics。',
desc2: '請在開啟之前確保您已經正確安裝了 OSDLyrics。',
},
unm: {
enable: '啟用',
audioSource: {
Expand Down
1 change: 1 addition & 0 deletions src/store/initLocalStorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ let localStorage = {
nyancatStyle: false,
showLyricsTranslation: true,
lyricsBackground: true,
enableOsdlyricsSupport: false,
closeAppOption: 'ask',
enableDiscordRichPresence: false,
enableGlobalShortcut: true,
Expand Down
35 changes: 31 additions & 4 deletions src/utils/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -201,6 +201,9 @@ export default class {
set progress(value) {
if (this._howler) {
this._howler.seek(value);
if (isCreateMpris) {
ipcRenderer?.send('seeked', this._howler.seek());
}
}
}
get isCurrentTrackLiked() {
Expand Down Expand Up @@ -622,9 +625,30 @@ 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 lyricContent = await getLyric(track.id);

if (!lyricContent.lrc || !lyricContent.lrc.lyric) {
return ipcRenderer?.send('metadata', metadata);
}

ipcRenderer.send('sendLyrics', {
track,
lyrics: lyricContent.lrc.lyric,
});

ipcRenderer.on('saveLyricFinished', () => {
ipcRenderer?.send('metadata', metadata);
});
}
_updateMediaSessionPositionState() {
if ('mediaSession' in navigator === false) {
return;
Expand Down Expand Up @@ -822,11 +846,14 @@ export default class {
this.play();
}
}
seek(time = null) {
seek(time = null, sendMpris = true) {
if (isCreateMpris && sendMpris && time) {
ipcRenderer?.send('seeked', time);
}
if (time !== null) {
this._howler?.seek(time);
if (this._playing)
this._playDiscordPresence(this._currentTrack, this.seek());
this._playDiscordPresence(this._currentTrack, this.seek(null, false));
}
return this._howler === null ? 0 : this._howler.seek();
}
Expand Down
2 changes: 1 addition & 1 deletion src/views/lyrics.vue
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ export default {
},
setLyricsInterval() {
this.lyricsInterval = setInterval(() => {
const progress = this.player.seek() ?? 0;
const progress = this.player.seek(null, false) ?? 0;
let oldHighlightLyricIndex = this.highlightLyricIndex;
this.highlightLyricIndex = this.lyric.findIndex((l, index) => {
const nextLyric = this.lyric[index + 1];
Expand Down
39 changes: 39 additions & 0 deletions src/views/settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,33 @@
</select>
</div>
</div>
<div v-if="isElectron && isLinux" class="item">
<div class="left">
<div class="title">
{{ $t('settings.unm.enable') }}
<a target="_blank" href="https://github.com/osdlyrics/osdlyrics"
>OSDLyrics</a
>
{{ $t('settings.enableOsdlyricsSupport.title') }}
</div>
<div class="description">
{{ $t('settings.enableOsdlyricsSupport.desc1') }}
<br />
{{ $t('settings.enableOsdlyricsSupport.desc2') }}
</div>
</div>
<div class="right">
<div class="toggle">
<input
id="enable-osdlyrics-support"
v-model="enableOsdlyricsSupport"
type="checkbox"
name="enable-osdlyrics-support"
/>
<label for="enable-osdlyrics-support"></label>
</div>
</div>
</div>

<section v-if="isElectron" class="unm-configuration">
<h3>UnblockNeteaseMusic</h3>
Expand Down Expand Up @@ -975,6 +1002,17 @@ export default {
});
},
},
enableOsdlyricsSupport: {
get() {
return this.settings.enableOsdlyricsSupport;
},
set(value) {
this.$store.commit('updateSettings', {
key: 'enableOsdlyricsSupport',
value,
});
},
},
closeAppOption: {
get() {
return this.settings.closeAppOption;
Expand Down Expand Up @@ -1477,6 +1515,7 @@ h3 {
select {
min-width: 192px;
max-width: 600px;
font-weight: 600;
border: none;
padding: 8px 12px 8px 12px;
Expand Down

0 comments on commit fd40a29

Please sign in to comment.