From 5e563cd6b3c26c68a459e4755e0e4e0a4ba424b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Antunes?= Date: Sun, 21 May 2023 01:13:37 +0100 Subject: [PATCH] Fixed seekbar randomly getting stuck Fixed closing with Alt + F4 Fixed invalid sinkIds always assumed as default device --- package-lock.json | 4 ++-- package.json | 4 ++-- src/main/eventSender.ts | 3 ++- src/renderer/index.ts | 12 ++++++++++-- src/renderer/models/audioInstance.ts | 28 ++++++++++++++++++++++++---- src/res/news.html | 16 ++++++++++++++++ 6 files changed, 56 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a8cd3b..bc65113 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mega-soundboard", - "version": "0.6.2", + "version": "0.6.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mega-soundboard", - "version": "0.6.2", + "version": "0.6.3", "license": "ISC", "dependencies": { "electron-updater": "^5.2.1", diff --git a/package.json b/package.json index fbd076d..aec88eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mega-soundboard", - "version": "0.6.2", + "version": "0.6.3", "description": "Mega Soundboard", "main": "out/main/main.js", "scripts": { @@ -8,7 +8,7 @@ "start": "npm run build && electron .", "startLast": "electron .", "bundle": "npm run bundle-index && npm run bundle-preload", - "bundle-index": "browserify out/renderer/index.js -o out/renderer/bundle.js --no-bundle-external", + "bundle-index": "browserify out/renderer/index.js -o out/renderer/bundle.js --no-bundle-external --debug", "bundle-preload": "browserify out/shared/preload.js -o out/shared/preload-bundle.js --no-bundle-external", "copy": "copyfiles src/res/**/* out -u 1", "dist": "npm run build && electron-builder -p never", diff --git a/src/main/eventSender.ts b/src/main/eventSender.ts index 17572db..22e497c 100644 --- a/src/main/eventSender.ts +++ b/src/main/eventSender.ts @@ -4,6 +4,7 @@ import MS from "./ms"; export default class EventSender { static send(name: T, param?: EventsMap[T]): void { - MS.instance.windowManager.mainWindow.webContents.send(name, param); + if (!MS.instance.windowManager.mainWindow.isDestroyed()) + MS.instance.windowManager.mainWindow.webContents.send(name, param); } } diff --git a/src/renderer/index.ts b/src/renderer/index.ts index 3f0dd0a..bae3160 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -100,11 +100,19 @@ function loadDevicesPanel(devices: MediaDeviceInfo[], settings: Settings): void } function selectDevices(settings: Settings): void { - mainDeviceDropdown.selectIfFound(item => + const foundMain = mainDeviceDropdown.selectIfFound(item => item instanceof DropdownDeviceItem && item.device === settings.mainDevice); - secondaryDeviceDropdown.selectIfFound(item => + // If main device not found, load Default. + if (!foundMain) mainDeviceDropdown.selectIfFound(item => + item instanceof DropdownDeviceItem && item.device == "default"); + + const foundSecondary = secondaryDeviceDropdown.selectIfFound(item => item instanceof DropdownDeviceItem && item.device === settings.secondaryDevice); + + // If secondary device not found, load None. + if (!foundSecondary) secondaryDeviceDropdown.selectIfFound(item => + item instanceof DropdownDeviceItem && item.device === ""); } function setVolumes(settings: Settings): void { diff --git a/src/renderer/models/audioInstance.ts b/src/renderer/models/audioInstance.ts index 80fd1a6..4d63a21 100644 --- a/src/renderer/models/audioInstance.ts +++ b/src/renderer/models/audioInstance.ts @@ -21,15 +21,28 @@ export default class AudioInstance { devices: IDevice[], volumeMult: number, ): Promise { - const sinkIdPromises: Promise[] = []; const audioElements: HTMLAudioElement[] = []; const stopEvent = new Event(); const pauseEvent = new Event(); const playEvent = new Event(); const timeUpdateEvent = new Event(); + let isFirst = true; for (const device of devices) { const audio = new Audio(sound.path); + + try { + await audio.setSinkId(device.id); + } catch (error) { + if (isFirst) { // We must play to at least one device. + // If setSinkId fails, it is set to the default device. + console.log(`Invalid sinkId: '${device.id}'. Using default device.`); + } else { + console.log(`Ignoring invalid sinkId '${device.id}'.`); + continue; + } + } + audio.addEventListener("ended", () => { audioElements.splice(audioElements.indexOf(audio), 1); if (audioElements.length <= 0) { @@ -38,16 +51,23 @@ export default class AudioInstance { }); audio.volume = Math.pow((device.volume / 100) * (sound.volume / 100) * (volumeMult), 2); - const p = audio.setSinkId(device.id).catch(() => { console.error(`Error setting SinkId for ${device.id}.`); }); - sinkIdPromises.push(p); audioElements.push(audio); + isFirst = false; + } + + // Wait for metadata to load only if it's not ready. (otherwise loadedmetadata would never fire) + if (audioElements[0].readyState <= 0) { + await new Promise((resolve) => { + audioElements[0].addEventListener("loadedmetadata", () => { + resolve(); + }); + }); } audioElements[0].addEventListener("pause", () => pauseEvent.raise()); audioElements[0].addEventListener("play", () => playEvent.raise()); audioElements[0].addEventListener("timeupdate", () => timeUpdateEvent.raise()); - await Promise.all(sinkIdPromises); return new AudioInstance( sound, audioElements, volumeMult, stopEvent, pauseEvent, playEvent, timeUpdateEvent ); diff --git a/src/res/news.html b/src/res/news.html index 038e6a5..f99e7c7 100644 --- a/src/res/news.html +++ b/src/res/news.html @@ -1,3 +1,19 @@ +

Version 0.6.3

+
    +
  • + FIX + The seekbar would get stuck sometimes. +
  • +
  • + FIX + ALT + F4 would not close the app properly. +
  • +
  • + FIX + Unavailable/removed/unplugged audio devices would cause problems. +
  • +
+

Version 0.6.2