diff --git a/src/main/features/core/player/index.ts b/src/main/features/core/player/index.ts index b2d7a461..601b398e 100644 --- a/src/main/features/core/player/index.ts +++ b/src/main/features/core/player/index.ts @@ -1,5 +1,5 @@ import { ipcMain } from 'electron'; -import { getMpvInstance } from '../../../main'; +import { getMainWindow, getMpvInstance } from '../../../main'; import { PlayerData } from '/@/renderer/store'; declare module 'node-mpv'; @@ -60,21 +60,28 @@ ipcMain.on('player-set-queue', async (_event, data: PlayerData) => { } let complete = false; + let tryAttempts = 0; while (!complete) { - try { - if (data.queue.current) { - await getMpvInstance()?.load(data.queue.current.streamUrl, 'replace'); - } - - if (data.queue.next) { - await getMpvInstance()?.load(data.queue.next.streamUrl, 'append'); - } - + if (tryAttempts > 3) { + getMainWindow()?.webContents.send('renderer-player-error', 'Failed to load song'); complete = true; - } catch (err) { - console.error(err); - await wait(500); + } else { + try { + if (data.queue.current) { + await getMpvInstance()?.load(data.queue.current.streamUrl, 'replace'); + } + + if (data.queue.next) { + await getMpvInstance()?.load(data.queue.next.streamUrl, 'append'); + } + + complete = true; + } catch (err) { + console.error(err); + tryAttempts += 1; + await wait(500); + } } } }); diff --git a/src/main/main.ts b/src/main/main.ts index bbddb94b..db0b7962 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -421,6 +421,12 @@ ipcMain.on( }, ); +ipcMain.on('player-quit', async () => { + mpvInstance?.stop(); + mpvInstance?.quit(); + mpvInstance = null; +}); + // Must duplicate with the one in renderer process settings.store.ts enum BindingActions { GLOBAL_SEARCH = 'globalSearch', diff --git a/src/main/preload/mpv-player.ts b/src/main/preload/mpv-player.ts index 9e116cdc..bde8d91b 100644 --- a/src/main/preload/mpv-player.ts +++ b/src/main/preload/mpv-player.ts @@ -134,6 +134,10 @@ const rendererQuit = (cb: (event: IpcRendererEvent) => void) => { ipcRenderer.on('renderer-player-quit', cb); }; +const rendererError = (cb: (event: IpcRendererEvent, data: string) => void) => { + ipcRenderer.on('renderer-player-error', cb); +}; + export const mpvPlayer = { autoNext, currentTime, @@ -157,6 +161,7 @@ export const mpvPlayer = { export const mpvPlayerListener = { rendererAutoNext, rendererCurrentTime, + rendererError, rendererNext, rendererPause, rendererPlay, diff --git a/src/renderer/features/player/hooks/use-center-controls.ts b/src/renderer/features/player/hooks/use-center-controls.ts index ac1c1e15..9cf794a7 100644 --- a/src/renderer/features/player/hooks/use-center-controls.ts +++ b/src/renderer/features/player/hooks/use-center-controls.ts @@ -15,6 +15,7 @@ import { usePlayerType, useSettingsStore } from '/@/renderer/store/settings.stor import { useScrobble } from '/@/renderer/features/player/hooks/use-scrobble'; import debounce from 'lodash/debounce'; import { QueueSong } from '/@/renderer/api/types'; +import { toast } from '/@/renderer/components'; const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; const mpvPlayerListener = isElectron() ? window.electron.mpvPlayerListener : null; @@ -527,6 +528,15 @@ export const useCenterControls = (args: { playersRef: any }) => { mpvPlayer.quit(); }, []); + const handleError = useCallback( + (message: string) => { + toast.error({ id: 'mpv-error', message, title: 'An error occurred during playback' }); + pause(); + mpvPlayer.pause(); + }, + [pause], + ); + useEffect(() => { if (isElectron()) { mpvPlayerListener.rendererPlayPause(() => { @@ -572,6 +582,10 @@ export const useCenterControls = (args: { playersRef: any }) => { mpvPlayerListener.rendererToggleRepeat(() => { handleToggleRepeat(); }); + + mpvPlayerListener.rendererError((_event: any, message: string) => { + handleError(message); + }); } return () => { @@ -586,10 +600,12 @@ export const useCenterControls = (args: { playersRef: any }) => { ipc?.removeAllListeners('renderer-player-quit'); ipc?.removeAllListeners('renderer-player-toggle-shuffle'); ipc?.removeAllListeners('renderer-player-toggle-repeat'); + ipc?.removeAllListeners('renderer-player-error'); }; }, [ autoNext, handleAutoNext, + handleError, handleNextTrack, handlePause, handlePlay,