mpris overhaul
This commit is contained in:
parent
835c2bddd5
commit
12fee3df36
5 changed files with 84 additions and 93 deletions
|
@ -16,10 +16,10 @@ import {utils} from './utils';
|
|||
* @see {@link https://github.com/ciderapp/Cider/wiki/Plugins|Documentation}
|
||||
*/
|
||||
export class Plugins {
|
||||
private static PluginMap: any = {};
|
||||
private basePluginsPath = path.join(__dirname, '../plugins');
|
||||
private userPluginsPath = path.join(electron.app.getPath('userData'), 'Plugins');
|
||||
private readonly pluginsList: any = {};
|
||||
private static PluginMap: any = {};
|
||||
|
||||
constructor() {
|
||||
this.pluginsList = this.getPlugins();
|
||||
|
@ -104,9 +104,9 @@ export class Plugins {
|
|||
public callPlugins(event: string, ...args: any[]) {
|
||||
for (const plugin in this.pluginsList) {
|
||||
if (this.pluginsList[plugin][event]) {
|
||||
try{
|
||||
try {
|
||||
this.pluginsList[plugin][event](...args);
|
||||
}catch(e) {
|
||||
} catch (e) {
|
||||
console.error(`[${plugin}] An error was encountered: ${e}`);
|
||||
console.error(e)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ export class utils {
|
|||
},
|
||||
previous: () => {
|
||||
bw.win.webContents.executeJavaScript("MusicKitInterop.previous()")
|
||||
},
|
||||
seek: (seconds: number) => {
|
||||
bw.win.webContents.executeJavaScript(`MusicKit.getInstance().seekToTime(${seconds})`)
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -76,8 +76,8 @@ ipcMain.on("nowPlayingItemDidChange", (_event, attributes) => {
|
|||
CiderPlug.callPlugins("onNowPlayingItemDidChange", attributes);
|
||||
});
|
||||
|
||||
ipcMain.on("nowPlayingItemDidChangeLastFM", (_event, attributes) => {
|
||||
CiderPlug.callPlugin("lastfm.js", "nowPlayingItemDidChangeLastFM", attributes);
|
||||
ipcMain.on("updatePlaybackProgress", (_event, attributes) => {
|
||||
CiderPlug.callPlugins("updatePlaybackProgress", attributes);
|
||||
})
|
||||
|
||||
app.on("before-quit", () => {
|
||||
|
|
|
@ -6,6 +6,11 @@ export default class mpris {
|
|||
* Private variables for interaction in plugins
|
||||
*/
|
||||
private static utils: any;
|
||||
/**
|
||||
* MPRIS Service
|
||||
*/
|
||||
private static player: Player.Player;
|
||||
private static globalAttributes: any = {}
|
||||
|
||||
/**
|
||||
* Base Plugin Details (Eventually implemented into a GUI in settings)
|
||||
|
@ -15,30 +20,17 @@ export default class mpris {
|
|||
public version: string = '1.0.0';
|
||||
public author: string = 'Core';
|
||||
|
||||
/**
|
||||
* MPRIS Service
|
||||
*/
|
||||
private static player: Player.Player;
|
||||
private static mprisEvents: Object = {
|
||||
"playpause": "playPause",
|
||||
"play": "play",
|
||||
"pause": "pause",
|
||||
"next": "next",
|
||||
"previous": "previous",
|
||||
}
|
||||
|
||||
/*******************************************************************************************
|
||||
* Private Methods
|
||||
* ****************************************************************************************/
|
||||
|
||||
/**
|
||||
* Runs a media event
|
||||
* @param type - pausePlay, next, previous
|
||||
* @private
|
||||
* Runs on plugin load (Currently run on application start)
|
||||
*/
|
||||
private static runMediaEvent(type: string) {
|
||||
// console.debug(`[Plugin][${this.name}] ${type}.`);
|
||||
mpris.utils.getWindow().webContents.executeJavaScript(`MusicKitInterop.${type}()`).catch(console.error)
|
||||
constructor(utils: any) {
|
||||
mpris.utils = utils
|
||||
|
||||
console.debug(`[Plugin][${mpris.name}] Loading Complete.`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,7 +46,6 @@ export default class mpris {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connects to MPRIS Service
|
||||
*/
|
||||
|
@ -63,29 +54,45 @@ export default class mpris {
|
|||
const player = Player({
|
||||
name: 'cider',
|
||||
identity: 'Cider',
|
||||
supportedUriSchemes: [],
|
||||
supportedMimeTypes: [],
|
||||
supportedInterfaces: ['player']
|
||||
});
|
||||
|
||||
console.debug(`[Plugin][${mpris.name}] Successfully connected.`);
|
||||
console.debug(`[${mpris.name}:connect] Successfully connected.`);
|
||||
|
||||
const pos_atr = {durationInMillis: 0};
|
||||
player.getPosition = function () {
|
||||
const durationInMicro = pos_atr.durationInMillis * 1000;
|
||||
const percentage = parseFloat("0") || 0;
|
||||
return durationInMicro * percentage;
|
||||
const renderer = mpris.utils.getWindow().webContents
|
||||
const loopType: { [key: string]: number; } = {
|
||||
'none': 0,
|
||||
'track': 1,
|
||||
'playlist': 2,
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(mpris.mprisEvents)) {
|
||||
player.on(key, function () {
|
||||
mpris.runMediaEvent(value)
|
||||
});
|
||||
}
|
||||
player.on('next', () => mpris.utils.playback.next())
|
||||
player.on('previous', () => mpris.utils.playback.previous())
|
||||
player.on('playpause', () => mpris.utils.playback.playPause())
|
||||
player.on('play', () => mpris.utils.playback.play())
|
||||
player.on('pause', () => mpris.utils.playback.pause())
|
||||
player.on('quit', () => mpris.utils.getApp().exit())
|
||||
player.on('position', (args: { position: any; }) => mpris.utils.playback.seek(args.position))
|
||||
player.on('loopStatus', (status: string) => renderer.executeJavaScript(`app.mk.repeatMode = ${loopType[status.toLowerCase()]}`))
|
||||
player.on('shuffle', () => renderer.executeJavaScript('app.mk.shuffleMode = (app.mk.shuffleMode === 0) ? 1 : 0'))
|
||||
|
||||
player.on('quit', function () {
|
||||
process.exit();
|
||||
});
|
||||
mpris.utils.getIPCMain().on('repeatModeDidChange', (_e: any, mode: number) => {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
player.loopStatus = Player.LOOP_STATUS_NONE;
|
||||
break;
|
||||
case 1:
|
||||
player.loopStatus = Player.LOOP_STATUS_TRACK;
|
||||
break;
|
||||
case 2:
|
||||
player.loopStatus = Player.LOOP_STATUS_PLAYLIST;
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
mpris.utils.getIPCMain().on('shuffleModeDidChange', (_e: any, mode: number) => {
|
||||
player.shuffle = mode === 1
|
||||
})
|
||||
|
||||
mpris.player = player;
|
||||
}
|
||||
|
@ -93,9 +100,9 @@ export default class mpris {
|
|||
/**
|
||||
* Update M.P.R.I.S Player Attributes
|
||||
*/
|
||||
private static updatePlayer(attributes: any) {
|
||||
private static updateMetaData(attributes: any) {
|
||||
|
||||
const MetaData = {
|
||||
mpris.player.metadata = {
|
||||
'mpris:trackid': mpris.player.objectPath(`track/${attributes.playParams.id.replace(/[.]+/g, "")}`),
|
||||
'mpris:length': attributes.durationInMillis * 1000, // In microseconds
|
||||
'mpris:artUrl': (attributes.artwork.url.replace('/{w}x{h}bb', '/512x512bb')).replace('/2000x2000bb', '/35x35bb'),
|
||||
|
@ -103,33 +110,12 @@ export default class mpris {
|
|||
'xesam:album': `${attributes.albumName}`,
|
||||
'xesam:artist': [`${attributes.artistName}`],
|
||||
'xesam:genre': attributes.genreNames
|
||||
}
|
||||
|
||||
if (mpris.player.metadata["mpris:trackid"] === MetaData["mpris:trackid"]) {
|
||||
return
|
||||
}
|
||||
|
||||
mpris.player.metadata = MetaData;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update M.P.R.I.S Player State
|
||||
* @private
|
||||
* @param attributes
|
||||
*/
|
||||
private static updatePlayerState(attributes: any) {
|
||||
switch (attributes.status) {
|
||||
case true: // Playing
|
||||
mpris.player.playbackStatus = Player.PLAYBACK_STATUS_PLAYING;
|
||||
break;
|
||||
case false: // Paused
|
||||
mpris.player.playbackStatus = Player.PLAYBACK_STATUS_PAUSED;
|
||||
break;
|
||||
default:
|
||||
mpris.player.playbackStatus = Player.PLAYBACK_STATUS_STOPPED;
|
||||
break
|
||||
}
|
||||
}
|
||||
/*******************************************************************************************
|
||||
* Public Methods
|
||||
* ****************************************************************************************/
|
||||
|
||||
/**
|
||||
* Clear state
|
||||
|
@ -143,26 +129,12 @@ export default class mpris {
|
|||
mpris.player.playbackStatus = Player.PLAYBACK_STATUS_STOPPED;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************************
|
||||
* Public Methods
|
||||
* ****************************************************************************************/
|
||||
|
||||
/**
|
||||
* Runs on plugin load (Currently run on application start)
|
||||
*/
|
||||
constructor(utils: any) {
|
||||
mpris.utils = utils
|
||||
|
||||
console.debug(`[Plugin][${mpris.name}] Loading Complete.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs on app ready
|
||||
*/
|
||||
@mpris.linuxOnly
|
||||
onReady(_: any): void {
|
||||
console.debug(`[Plugin][${mpris.name}] Ready.`);
|
||||
console.debug(`[${mpris.name}:onReady] Ready.`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,9 +159,9 @@ export default class mpris {
|
|||
* @param attributes Music Attributes (attributes.status = current state)
|
||||
*/
|
||||
@mpris.linuxOnly
|
||||
onPlaybackStateDidChange(attributes: object): void {
|
||||
// console.debug(`[Plugin][${mpris.name}] onPlaybackStateDidChange.`);
|
||||
mpris.updatePlayerState(attributes)
|
||||
onPlaybackStateDidChange(attributes: any): void {
|
||||
mpris.globalAttributes = attributes
|
||||
mpris.player.playbackStatus = attributes?.status ? Player.PLAYBACK_STATUS_PLAYING : Player.PLAYBACK_STATUS_PAUSED
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,8 +170,14 @@ export default class mpris {
|
|||
*/
|
||||
@mpris.linuxOnly
|
||||
onNowPlayingItemDidChange(attributes: object): void {
|
||||
// console.debug(`[Plugin][${mpris.name}] onMetadataDidChange.`);
|
||||
mpris.updatePlayer(attributes);
|
||||
mpris.globalAttributes = attributes
|
||||
mpris.updateMetaData(attributes);
|
||||
}
|
||||
|
||||
@mpris.linuxOnly
|
||||
updatePlaybackProgress(attributes: any): void {
|
||||
mpris.globalAttributes = attributes
|
||||
mpris.player.getPosition = () => attributes.currentPlaybackTime * 1000 * 1000;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ const MusicKitInterop = {
|
|||
/** wsapi */
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.playbackProgressDidChange, () => {
|
||||
ipcRenderer.send('wsapi-updatePlaybackState', MusicKitInterop.getAttributes());
|
||||
ipcRenderer.send('updatePlaybackProgress', MusicKitInterop.getAttributes());
|
||||
});
|
||||
/** wsapi */
|
||||
|
||||
|
@ -38,11 +39,19 @@ const MusicKitInterop = {
|
|||
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.authorizationStatusDidChange, () => {
|
||||
global.ipcRenderer.send('authorizationStatusDidChange', MusicKit.getInstance().authorizationStatus)
|
||||
})
|
||||
});
|
||||
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.mediaPlaybackError, (e) => {
|
||||
console.warn(`[cider:preload] mediaPlaybackError] ${e}`);
|
||||
})
|
||||
});
|
||||
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.shuffleModeDidChange, () => {
|
||||
global.ipcRenderer.send('shuffleModeDidChange', MusicKit.getInstance().shuffleMode)
|
||||
});
|
||||
|
||||
MusicKit.getInstance().addEventListener(MusicKit.Events.repeatModeDidChange, () => {
|
||||
global.ipcRenderer.send('repeatModeDidChange', MusicKit.getInstance().repeatMode)
|
||||
});
|
||||
},
|
||||
|
||||
sleep(ms) {
|
||||
|
@ -79,6 +88,7 @@ const MusicKitInterop = {
|
|||
? remainingTimeExport * 1000
|
||||
: 0;
|
||||
attributes.durationInMillis = attributes?.durationInMillis ?? 0;
|
||||
attributes.currentPlaybackTime = mk?.currentPlaybackTime ?? 0;
|
||||
attributes.currentPlaybackProgress = currentPlaybackProgress ?? 0;
|
||||
attributes.startTime = Date.now();
|
||||
attributes.endTime = Math.round(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue