From 8106f0ac2ee637e2d72c651812372872779a696b Mon Sep 17 00:00:00 2001 From: vapormusic Date: Mon, 27 Dec 2021 17:05:12 +0700 Subject: [PATCH] some testing stuffs --- src/main/cider-base.js | 11 ++++ src/main/discordrpc.js | 124 +++++++++++++++++++++++++++++++++++ src/preload/cider-preload.js | 88 +++++++++++++++++++++++++ src/renderer/index.js | 4 +- 4 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 src/main/discordrpc.js diff --git a/src/main/cider-base.js b/src/main/cider-base.js index db49969f..37950369 100644 --- a/src/main/cider-base.js +++ b/src/main/cider-base.js @@ -8,6 +8,7 @@ const os = require('os'); const Store = require("electron-store"); const store = new Store(); const yt = require('youtube-search-without-api-key'); +const discord = require('./discordrpc'); // Analytics for debugging. const ElectronSentry = require("@sentry/electron"); @@ -200,6 +201,16 @@ const CiderBase = { }) win.webContents.setZoomFactor(screen.getPrimaryDisplay().scaleFactor) + + // Discord + discord.connect('911790844204437504'); + ipcMain.on('playbackStateDidChange', (_event, a) => { + discord.updateActivity(a) + }); + ipcMain.on('nowPlayingItemDidChange', (_event, a) => { + discord.updateActivity(a) + }); + return win }, diff --git a/src/main/discordrpc.js b/src/main/discordrpc.js new file mode 100644 index 00000000..f346d9f5 --- /dev/null +++ b/src/main/discordrpc.js @@ -0,0 +1,124 @@ +const {app} = require('electron'), + DiscordRPC = require('discord-rpc') + +module.exports = { + connect: function (clientId) { + app.discord = {isConnected: false}; + if (!app.cfg.get('general.discord_rpc')) return; + + DiscordRPC.register(clientId) // Apparently needed for ask to join, join, spectate etc. + const client = new DiscordRPC.Client({ transport: "ipc" }); + app.discord = Object.assign(client,{error: false, activityCache: null, isConnected: false}); + + // Login to Discord + app.discord.login({ clientId }) + .then(() => { + app.discord.isConnected = true; + }) + .catch((e) => console.error(`[DiscordRPC][connect] ${e}`)); + + app.discord.on('ready', () => { + console.log(`[DiscordRPC][connect] Successfully Connected to Discord. Authed for user: ${client.user.username} (${client.user.id})`); + + if (app.discord.activityCache) { + client.setActivity(app.discord.activityCache).catch((e) => console.error(e)); + app.discord.activityCache = null; + } + }) + + // Handles Errors + app.discord.on('error', err => { + console.error(`[DiscordRPC] ${err}`); + this.disconnect() + app.discord.isConnected = false; + }); + }, + + disconnect: function () { + if (!app.cfg.get('general.discord_rpc') || !app.discord.isConnected) return; + + try { + app.discord.destroy().then(() => { + app.discord.isConnected = false; + console.log('[DiscordRPC][disconnect] Disconnected from discord.') + }).catch((e) => console.error(`[DiscordRPC][disconnect] ${e}`)); + } catch (err) { + console.error(err) + } + }, + + updateActivity: function (attributes) { + if (!app.cfg.get('general.discord_rpc')) return; + + if (!app.discord.isConnected) { + this.connect() + } + + if (!app.discord.isConnected) return; + + // console.log('[DiscordRPC][updateActivity] Updating Discord Activity.') + + const listenURL = `https://applemusicelectron.com/p?id=${attributes.playParams.id}` + //console.log(attributes) + let ActivityObject = { + details: attributes.name, + state: `by ${attributes.artistName}`, + startTimestamp: attributes.startTime, + endTimestamp: attributes.endTime, + largeImageKey: (attributes.artwork.url.replace('{w}', '512').replace('{h}', '512') ) ?? 'cider', + largeImageText: attributes.albumName, + smallImageKey: (attributes.status ? 'play' : 'pause'), + smallImageText: (attributes.status ? 'Playing': 'Paused'), + instance: true, + buttons: [ + {label: "Listen on Cider", url: listenURL}, + ] + }; + if (ActivityObject.largeImageKey == "" || ActivityObject.largeImageKey == null) {ActivityObject.largeImageKey = "cider"} + //console.log(`[LinkHandler] Listening URL has been set to: ${listenURL}`); + + // if (app.cfg.get('general.discordClearActivityOnPause')) { + // delete ActivityObject.smallImageKey + // delete ActivityObject.smallImageText + // } + + // Check all the values work + if (!((new Date(attributes.endTime)).getTime() > 0)) { + delete ActivityObject.startTimestamp + delete ActivityObject.endTimestamp + } + if (!attributes.artistName) { + delete ActivityObject.state + } + if (!ActivityObject.largeImageText || ActivityObject.largeImageText.length < 2) { + delete ActivityObject.largeImageText + } + if (ActivityObject.details.length > 128) { + AcitivityObject.details = ActivityObject.details.substring(0, 125) + '...' + } + + // Clear if if needed + if (!attributes.status) { + //if (app.cfg.get('general.discordClearActivityOnPause')) { + // app.discord.clearActivity().catch((e) => console.error(`[DiscordRPC][clearActivity] ${e}`)); + // ActivityObject = null + // } else + // { + delete ActivityObject.startTimestamp + delete ActivityObject.endTimestamp + ActivityObject.smallImageKey = 'pause' + ActivityObject.smallImageText = 'Paused' + //} + } + + if (ActivityObject) { + try { + // console.log(`[DiscordRPC][setActivity] Setting activity to ${JSON.stringify(ActivityObject)}`); + app.discord.setActivity(ActivityObject) + } catch (err) { + console.error(`[DiscordRPC][setActivity] ${err}`) + } + + } + }, +} \ No newline at end of file diff --git a/src/preload/cider-preload.js b/src/preload/cider-preload.js index b8089fc4..c0246916 100644 --- a/src/preload/cider-preload.js +++ b/src/preload/cider-preload.js @@ -2,7 +2,95 @@ const electron = require('electron') console.log('Loaded Preload') +let cache = {playParams: {id: 0}, status: null, remainingTime: 0}, + playbackCache = {status: null, time: Date.now()}; + +const MusicKitInterop = { + init: function () { + MusicKit.getInstance().addEventListener(MusicKit.Events.playbackStateDidChange, () => { + if (MusicKitInterop.filterTrack(MusicKitInterop.getAttributes(), true, false)) { + console.log("ayy"); + global.ipcRenderer.send('playbackStateDidChange', MusicKitInterop.getAttributes()) + // if (typeof _plugins != "undefined") { + // _plugins.execute("OnPlaybackStateChanged", {Attributes: MusicKitInterop.getAttributes()}) + // } + } + }); + + MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, () => { + if (MusicKitInterop.filterTrack(MusicKitInterop.getAttributes(), false, true)) { + global.ipcRenderer.send('nowPlayingItemDidChange', MusicKitInterop.getAttributes()); + } + }); + + MusicKit.getInstance().addEventListener(MusicKit.Events.authorizationStatusDidChange, () => { + global.ipcRenderer.send('authorizationStatusDidChange', MusicKit.getInstance().authorizationStatus) + }) + + MusicKit.getInstance().addEventListener(MusicKit.Events.mediaPlaybackError, (e) => { + console.warn(`[mediaPlaybackError] ${e}`); + }) + }, + + getAttributes: function () { + const nowPlayingItem = MusicKit.getInstance().nowPlayingItem; + const isPlayingExport = MusicKit.getInstance().isPlaying; + const remainingTimeExport = MusicKit.getInstance().currentPlaybackTimeRemaining; + const attributes = (nowPlayingItem != null ? nowPlayingItem.attributes : {}); + + attributes.status = isPlayingExport ? isPlayingExport : false; + attributes.name = attributes.name ? attributes.name : 'No Title Found'; + attributes.artwork = attributes.artwork ? attributes.artwork : {url: ''}; + attributes.artwork.url = attributes.artwork.url ? attributes.artwork.url : ''; + attributes.playParams = attributes.playParams ? attributes.playParams : {id: 'no-id-found'}; + attributes.playParams.id = attributes.playParams.id ? attributes.playParams.id : 'no-id-found'; + attributes.albumName = attributes.albumName ? attributes.albumName : ''; + attributes.artistName = attributes.artistName ? attributes.artistName : ''; + attributes.genreNames = attributes.genreNames ? attributes.genreNames : []; + attributes.remainingTime = remainingTimeExport ? (remainingTimeExport * 1000) : 0; + attributes.durationInMillis = attributes.durationInMillis ? attributes.durationInMillis : 0; + attributes.startTime = Date.now(); + attributes.endTime = Math.round((attributes.playParams.id === cache.playParams.id ? (Date.now() + attributes.remainingTime) : (attributes.startTime + attributes.durationInMillis))); + attributes.endTime = attributes.endTime ? attributes.endTime : Date.now(); + return attributes + }, + + filterTrack: function (a, playbackCheck, mediaCheck) { + if (a.title === "No Title Found" || a.playParams.id === "no-id-found") { + return; + } else if (mediaCheck && a.playParams.id === cache.playParams.id) { + return; + } else if (playbackCheck && a.status === playbackCache.status) { + return; + } else if (playbackCheck && !a.status && a.remainingTime === playbackCache.time) { /* Pretty much have to do this to prevent multiple runs when a song starts playing */ + return; + } + cache = a; + if (playbackCheck) playbackCache = {status: a.status, time: a.remainingTime}; + return true; + }, + + pausePlay: function () { + if (MusicKit.getInstance().isPlaying) { + MusicKit.getInstance().pause(); + } else if (MusicKit.getInstance().nowPlayingItem != null) { + MusicKit.getInstance().play().then(r => console.log(`[MusicKitInterop] Playing ${r}`)); + } + }, + + nextTrack: function () { + MusicKit.getInstance().skipToNextItem().then(r => console.log(`[MusicKitInterop] Skipping to Next ${r}`)); + }, + + previousTrack: function () { + MusicKit.getInstance().skipToPreviousItem().then(r => console.log(`[MusicKitInterop] Skipping to Previous ${r}`)); + } + +} + + process.once('loaded', () => { console.log("Setting ipcRenderer") global.ipcRenderer = electron.ipcRenderer; + global.MusicKitInterop = MusicKitInterop; }); \ No newline at end of file diff --git a/src/renderer/index.js b/src/renderer/index.js index b7becc6a..0acd7e46 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -359,7 +359,7 @@ const app = new Vue({ } } } - + MusicKitInterop.init() // Set the volume this.mk.volume = this.cfg.general.volume // ipcRenderer.invoke('getStoreValue', 'general.volume').then((value) => { @@ -2578,3 +2578,5 @@ webGPU().then() let screenWidth = screen.width; let screenHeight = screen.height; + +