mpris overhaul

This commit is contained in:
Core 2022-07-12 21:26:05 +01:00
parent 835c2bddd5
commit 12fee3df36
No known key found for this signature in database
GPG key ID: FE9BF1B547F8F3C6
5 changed files with 84 additions and 93 deletions

View file

@ -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();

View file

@ -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})`)
}
}
/**

View file

@ -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", () => {

View file

@ -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;
}
}

View file

@ -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(