mirror of
https://github.com/GiriNeko/YesPlayMusic.git
synced 2025-12-16 05:08:04 +00:00
feat: use osdlyrics dbus interface to send lyric contents
This commit is contained in:
parent
845bc8a921
commit
ed1daab1f6
8 changed files with 45 additions and 55 deletions
|
|
@ -31,7 +31,7 @@ import { EventEmitter } from 'events';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import expressProxy from 'express-http-proxy';
|
import expressProxy from 'express-http-proxy';
|
||||||
import Store from 'electron-store';
|
import Store from 'electron-store';
|
||||||
import { createMpris } from '@/electron/mpris';
|
import { createMpris, createDbus } from '@/electron/mpris';
|
||||||
import { spawn } from 'child_process';
|
import { spawn } from 'child_process';
|
||||||
const clc = require('cli-color');
|
const clc = require('cli-color');
|
||||||
const log = text => {
|
const log = text => {
|
||||||
|
|
@ -423,6 +423,7 @@ class Background {
|
||||||
|
|
||||||
// try to start osdlyrics process on start
|
// try to start osdlyrics process on start
|
||||||
if (this.store.get('settings.enableOsdlyricsSupport')) {
|
if (this.store.get('settings.enableOsdlyricsSupport')) {
|
||||||
|
await createDbus(this.window);
|
||||||
log('try to start osdlyrics process');
|
log('try to start osdlyrics process');
|
||||||
const osdlyricsProcess = spawn('osdlyrics');
|
const osdlyricsProcess = spawn('osdlyrics');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ import cloneDeep from 'lodash/cloneDeep';
|
||||||
import shortcuts from '@/utils/shortcuts';
|
import shortcuts from '@/utils/shortcuts';
|
||||||
import { createMenu } from './menu';
|
import { createMenu } from './menu';
|
||||||
import { isCreateTray, isMac } from '@/utils/platform';
|
import { isCreateTray, isMac } from '@/utils/platform';
|
||||||
import { resolve } from 'path';
|
|
||||||
import { mkdir, rm, writeFile } from 'fs/promises';
|
|
||||||
|
|
||||||
const clc = require('cli-color');
|
const clc = require('cli-color');
|
||||||
const log = text => {
|
const log = text => {
|
||||||
|
|
@ -135,43 +133,6 @@ function parseSourceStringToList(executor, sourceString) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Write lyrics into local file
|
|
||||||
*
|
|
||||||
* @param {string} name
|
|
||||||
* @param {string} content
|
|
||||||
*/
|
|
||||||
async function writeLyric(name, content) {
|
|
||||||
name = name.replaceAll('/', '⁄');
|
|
||||||
|
|
||||||
const lyricsDir = resolve(process.env.HOME, '.lyrics');
|
|
||||||
const destination = resolve(lyricsDir, name + '.lrc');
|
|
||||||
|
|
||||||
try {
|
|
||||||
await writeFile(destination, content);
|
|
||||||
} catch (e) {
|
|
||||||
switch (e.code) {
|
|
||||||
// ENOENT (no such file or directory),
|
|
||||||
case 'ENOENT':
|
|
||||||
await mkdir(lyricsDir, { recursive: true });
|
|
||||||
|
|
||||||
// Try again. Should be succeed.
|
|
||||||
return await writeLyric(name, content);
|
|
||||||
// ENOTDIR (not a directory), 指 TMPDIR 有問題。
|
|
||||||
case 'ENOTDIR':
|
|
||||||
// 砍掉 TMPDIR「檔案」。
|
|
||||||
await rm(lyricsDir);
|
|
||||||
|
|
||||||
// 預期接下來的流程是 ENOENT 建立資料夾的流程。
|
|
||||||
return await writeLyric(name, content);
|
|
||||||
default:
|
|
||||||
log(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function initIpcMain(win, store, trayEventEmitter) {
|
export function initIpcMain(win, store, trayEventEmitter) {
|
||||||
// WIP: Do not enable logging as it has some issues in non-blocking I/O environment.
|
// WIP: Do not enable logging as it has some issues in non-blocking I/O environment.
|
||||||
// UNM.enableLogging(UNM.LoggingType.ConsoleEnv);
|
// UNM.enableLogging(UNM.LoggingType.ConsoleEnv);
|
||||||
|
|
@ -348,12 +309,6 @@ export function initIpcMain(win, store, trayEventEmitter) {
|
||||||
registerGlobalShortcut(win, store);
|
registerGlobalShortcut(win, store);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('saveLyric', async (_, { name, lyric }) => {
|
|
||||||
await writeLyric(name, lyric);
|
|
||||||
|
|
||||||
return win.webContents.send('saveLyricFinished');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isCreateTray) {
|
if (isCreateTray) {
|
||||||
ipcMain.on('updateTrayTooltip', (_, title) => {
|
ipcMain.on('updateTrayTooltip', (_, title) => {
|
||||||
trayEventEmitter.emit('updateTooltip', title);
|
trayEventEmitter.emit('updateTooltip', title);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import dbus from 'dbus-next';
|
||||||
import { ipcMain, app } from 'electron';
|
import { ipcMain, app } from 'electron';
|
||||||
|
|
||||||
export function createMpris(window) {
|
export function createMpris(window) {
|
||||||
|
|
@ -63,3 +64,26 @@ export function createMpris(window) {
|
||||||
player.shuffle = shuffle;
|
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');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,10 @@ export default {
|
||||||
},
|
},
|
||||||
enableOsdlyricsSupport: {
|
enableOsdlyricsSupport: {
|
||||||
title: 'desktop lyrics support',
|
title: 'desktop lyrics support',
|
||||||
desc: 'Only takes effect under Linux. After enabled, it downloads the lyrics file to the local, and tries to launch OSDLyrics at startup.',
|
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: {
|
unm: {
|
||||||
enable: 'Enable',
|
enable: 'Enable',
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,9 @@ export default {
|
||||||
},
|
},
|
||||||
enableOsdlyricsSupport: {
|
enableOsdlyricsSupport: {
|
||||||
title: '桌面歌词支持',
|
title: '桌面歌词支持',
|
||||||
desc: '仅 Linux 下生效。启用后会将歌词文件下载到本地,并在开启播放器时尝试拉起 OSDLyrics。',
|
desc1:
|
||||||
|
'仅 Linux 下生效。启用后会将歌词文件下载到本地,并在开启播放器时尝试拉起 OSDLyrics。',
|
||||||
|
desc2: '请在开启之前确保您已经正确安装了 OSDLyrics。',
|
||||||
},
|
},
|
||||||
unm: {
|
unm: {
|
||||||
enable: '启用',
|
enable: '启用',
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,9 @@ export default {
|
||||||
},
|
},
|
||||||
enableOsdlyricsSupport: {
|
enableOsdlyricsSupport: {
|
||||||
title: '桌面歌詞支援',
|
title: '桌面歌詞支援',
|
||||||
desc: '只在 Linux 環境下生效。啟用後會將歌詞檔案下載至本機位置,並在開啟播放器時嘗試連帶啟動 OSDLyrics。',
|
desc1:
|
||||||
|
'只在 Linux 環境下生效。啟用後會將歌詞檔案下載至本機位置,並在開啟播放器時嘗試連帶啟動 OSDLyrics。',
|
||||||
|
desc2: '請在開啟之前確保您已經正確安裝了 OSDLyrics。',
|
||||||
},
|
},
|
||||||
unm: {
|
unm: {
|
||||||
enable: '啟用',
|
enable: '啟用',
|
||||||
|
|
|
||||||
|
|
@ -629,16 +629,17 @@ export default class {
|
||||||
return ipcRenderer?.send('metadata', metadata);
|
return ipcRenderer?.send('metadata', metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
let lyricName = track.ar.map(ar => ar.name).join(', ') + '-' + track.name;
|
|
||||||
let lyricContent = await getLyric(track.id);
|
let lyricContent = await getLyric(track.id);
|
||||||
|
|
||||||
if (!lyricContent.lrc.lyric) {
|
if (!lyricContent.lrc || !lyricContent.lrc.lyric) {
|
||||||
return ipcRenderer?.send('metadata', metadata);
|
return ipcRenderer?.send('metadata', metadata);
|
||||||
}
|
}
|
||||||
ipcRenderer.send('saveLyric', {
|
|
||||||
name: lyricName,
|
ipcRenderer.send('sendLyrics', {
|
||||||
lyric: lyricContent.lrc.lyric,
|
track,
|
||||||
|
lyrics: lyricContent.lrc.lyric,
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('saveLyricFinished', () => {
|
ipcRenderer.on('saveLyricFinished', () => {
|
||||||
ipcRenderer?.send('metadata', metadata);
|
ipcRenderer?.send('metadata', metadata);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,9 @@
|
||||||
{{ $t('settings.enableOsdlyricsSupport.title') }}
|
{{ $t('settings.enableOsdlyricsSupport.title') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
{{ $t('settings.enableOsdlyricsSupport.desc') }}
|
{{ $t('settings.enableOsdlyricsSupport.desc1') }}
|
||||||
|
<br />
|
||||||
|
{{ $t('settings.enableOsdlyricsSupport.desc2') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue