Skip to content

Commit

Permalink
Prevent Lyrics from opening up Spotify if it is closed
Browse files Browse the repository at this point in the history
We don't want that so we check with macOS first to see if we should even talk to Spotify (which implies starting it if it wasn't running).
  • Loading branch information
TomasHubelbauer committed Jun 11, 2024
1 parent 8d3e7f9 commit 037d64b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 18 deletions.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ The video needs to be recorded based on an automated script to be reproducible.
I will use faked synchronized lyrics for it so that I don't need to connect to
Spotify from the agent.

### Prevent the app from re-opening Spotify if not open or closed while it runs

It seems to be reviving it.

### Integrate the Electron auto-update service once GitHub Actions is set up

So I do not need to replace the app but can rely on it to auto-update on start
Expand Down Expand Up @@ -130,3 +126,4 @@ Also consider saving the changes to manually synchronized lyrics for reuse.
- Removed no longer used stuff now that the app uses the user's Home directory
- Worked around the ghosting issue and capture a repro repository for it:
https://github.com/TomasHubelbauer/electron-lingering-shadow-repro
- Fixed the Lyrics app opening up Spotify unintentionally if it was closed
12 changes: 2 additions & 10 deletions askSpotify.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import child_process from 'child_process';
import util from 'util';

const exec = util.promisify(child_process.exec);
import runAppleScript from './runAppleScript.js';

export default async function askSpotify(
/** @type {string} */
query
) {
const { stdout, stderr } = await exec(`osascript -e 'tell application "Spotify" to ${query}'`);
if (stderr) {
throw new Error(stderr);
}

return stdout.trimEnd();
return await runAppleScript(`tell application "Spotify" to ${query}`);
}
17 changes: 13 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import timers from 'timers/promises';
import fs from 'fs';
import askSpotify from './askSpotify.js';
import promptAuthorization from './promptAuthorization.js';
import runAppleScript from './runAppleScript.js';

// Set working directory for the production builds
process.chdir(electron.app.getPath('home'));
Expand Down Expand Up @@ -98,6 +99,8 @@ electron.app.on('ready', async () => {
}

if (!lyrics || ('error' in lyrics) || state !== 'playing') {
// Clear the last line in case Spotify got paused or stopped
await window.webContents.executeJavaScript(`document.body.dataset.lyric = '';`);
return;
}

Expand Down Expand Up @@ -166,9 +169,15 @@ electron.app.on('ready', async () => {

// Check artist, song and time and fetch and update lyrics on slow interval
while (true) {
// Wait for 5 seconds between Spotify checks unless it is the first loop run
if (lyrics) {
await timers.setTimeout(5000);
// Wait a bit seconds between AppleScript Spotify checks to not be spammy
await timers.setTimeout(2000);

// Determine if Spotify is running to avoid starting it unintentionally
if (!+await runAppleScript('tell application "System Events" to count (every process whose name is "Spotify")')) {
// Reset the lyris so we don't get stuck on the last line
lyrics = undefined;

continue;
}

/** @type {string} */
Expand Down Expand Up @@ -264,7 +273,7 @@ electron.app.on('ready', async () => {

try {
const _state = await askSpotify('player state');
if (_state !== 'playing' && _state !== 'paused') {
if (_state !== 'playing' && _state !== 'paused' && _state !== 'stopped') {
throw new Error(`Unexpected player state '${_state}'!`);
}

Expand Down
20 changes: 20 additions & 0 deletions runAppleScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import child_process from 'child_process';
import util from 'util';

const exec = util.promisify(child_process.exec);

export default async function runAppleScript(
/** @type {string} */
query
) {
if (query.includes('\'')) {
throw new Error('The query cannot contain single quotes');
}

const { stdout, stderr } = await exec(`osascript -e '${query}'`);
if (stderr) {
throw new Error(stderr);
}

return stdout.trimEnd();
}

0 comments on commit 037d64b

Please sign in to comment.