Add mpv path reload and clear functionality
This commit is contained in:
parent
8f4ff9286a
commit
fb08502e51
4 changed files with 94 additions and 18 deletions
|
@ -84,6 +84,7 @@
|
|||
"random": "random",
|
||||
"rating": "rating",
|
||||
"refresh": "refresh",
|
||||
"reload": "reload",
|
||||
"reset": "reset",
|
||||
"resetToDefault": "reset to default",
|
||||
"restartRequired": "restart required",
|
||||
|
@ -506,9 +507,9 @@
|
|||
"minimumScrobbleSeconds": "minimum scrobble (seconds)",
|
||||
"minimumScrobbleSeconds_description": "the minimum duration in seconds of the song that must be played before it is scrobbled",
|
||||
"mpvExecutablePath": "mpv executable path",
|
||||
"mpvExecutablePath_description": "sets the path to the mpv executable",
|
||||
"mpvExecutablePath_help": "one per line",
|
||||
"mpvExecutablePath_description": "sets the path to the mpv executable. if left empty, the default path will be used",
|
||||
"mpvExtraParameters": "mpv parameters",
|
||||
"mpvExtraParameters_help": "one per line",
|
||||
"passwordStore": "passwords/secret store",
|
||||
"passwordStore_description": "what password/secret store to use. change this if you are having issues storing passwords.",
|
||||
"playbackStyle": "playback style",
|
||||
|
|
|
@ -81,10 +81,11 @@ const DEFAULT_MPV_PARAMETERS = (extraParameters?: string[]) => {
|
|||
};
|
||||
|
||||
const createMpv = async (data: {
|
||||
binaryPath?: string;
|
||||
extraParameters?: string[];
|
||||
properties?: Record<string, any>;
|
||||
}): Promise<MpvAPI> => {
|
||||
const { extraParameters, properties } = data;
|
||||
const { extraParameters, properties, binaryPath } = data;
|
||||
|
||||
const params = uniq([...DEFAULT_MPV_PARAMETERS(extraParameters), ...(extraParameters || [])]);
|
||||
|
||||
|
@ -94,7 +95,7 @@ const createMpv = async (data: {
|
|||
{
|
||||
audio_only: true,
|
||||
auto_restart: false,
|
||||
binary: MPV_BINARY_PATH || undefined,
|
||||
binary: binaryPath || MPV_BINARY_PATH || undefined,
|
||||
socket: isWindows() ? `\\\\.\\pipe\\mpvserver${extra}` : `/tmp/node-mpv${extra}.sock`,
|
||||
time_update: 1,
|
||||
},
|
||||
|
@ -168,15 +169,20 @@ ipcMain.on('player-set-properties', async (_event, data: Record<string, any>) =>
|
|||
ipcMain.handle(
|
||||
'player-restart',
|
||||
async (_event, data: { extraParameters?: string[]; properties?: Record<string, any> }) => {
|
||||
mpvInstance?.quit();
|
||||
try {
|
||||
mpvLog({
|
||||
action: `Attempting to initialize mpv with parameters: ${JSON.stringify(data)}`,
|
||||
});
|
||||
|
||||
// Clean up previous mpv instance
|
||||
getMpvInstance()?.stop();
|
||||
getMpvInstance()?.quit();
|
||||
mpvInstance = null;
|
||||
|
||||
mpvInstance = await createMpv(data);
|
||||
mpvLog({ action: 'Restarted mpv', toast: 'success' });
|
||||
} catch (err: NodeMpvError | any) {
|
||||
mpvLog({ action: 'Failed to initialize mpv' }, err);
|
||||
mpvLog({ action: 'Failed to restart mpv' }, err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -197,8 +203,8 @@ ipcMain.handle(
|
|||
|
||||
ipcMain.on('player-quit', async () => {
|
||||
try {
|
||||
mpvInstance?.stop();
|
||||
mpvInstance?.quit();
|
||||
getMpvInstance()?.stop();
|
||||
getMpvInstance()?.quit();
|
||||
mpvInstance = null;
|
||||
} catch (err: NodeMpvError | any) {
|
||||
mpvLog({ action: 'Failed to quit mpv' }, err);
|
||||
|
@ -382,7 +388,12 @@ ipcMain.on('player-mute', async (_event, mute: boolean) => {
|
|||
});
|
||||
|
||||
ipcMain.handle('player-get-time', async (): Promise<number | undefined> => {
|
||||
try {
|
||||
return getMpvInstance()?.getTimePosition();
|
||||
} catch (err: NodeMpvError | any) {
|
||||
mpvLog({ action: `Failed to get current time` }, err);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
app.on('before-quit', () => {
|
||||
|
|
|
@ -5,7 +5,11 @@ const initialize = (data: { extraParameters?: string[]; properties?: Record<stri
|
|||
return ipcRenderer.invoke('player-initialize', data);
|
||||
};
|
||||
|
||||
const restart = (data: { extraParameters?: string[]; properties?: Record<string, any> }) => {
|
||||
const restart = (data: {
|
||||
binaryPath?: string;
|
||||
extraParameters?: string[];
|
||||
properties?: Record<string, any>;
|
||||
}) => {
|
||||
return ipcRenderer.invoke('player-restart', data);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Divider, Stack } from '@mantine/core';
|
||||
import { Divider, Group, Stack } from '@mantine/core';
|
||||
import isElectron from 'is-electron';
|
||||
import { FileInput, Textarea, Text, Select, NumberInput, Switch } from '/@/renderer/components';
|
||||
import {
|
||||
FileInput,
|
||||
Textarea,
|
||||
Text,
|
||||
Select,
|
||||
NumberInput,
|
||||
Switch,
|
||||
Button,
|
||||
} from '/@/renderer/components';
|
||||
import {
|
||||
SettingsSection,
|
||||
SettingOption,
|
||||
|
@ -9,10 +17,13 @@ import {
|
|||
import {
|
||||
SettingsState,
|
||||
usePlaybackSettings,
|
||||
useSettingsStore,
|
||||
useSettingsStoreActions,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { PlaybackType } from '/@/renderer/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RiCloseLine, RiRestartLine } from 'react-icons/ri';
|
||||
import { usePlayerControls, usePlayerStore, useQueueControls } from '/@/renderer/store';
|
||||
|
||||
const localSettings = isElectron() ? window.electron.localSettings : null;
|
||||
const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null;
|
||||
|
@ -64,11 +75,20 @@ export const MpvSettings = () => {
|
|||
const { t } = useTranslation();
|
||||
const settings = usePlaybackSettings();
|
||||
const { setSettings } = useSettingsStoreActions();
|
||||
const { pause } = usePlayerControls();
|
||||
const { clearQueue } = useQueueControls();
|
||||
|
||||
const [mpvPath, setMpvPath] = useState('');
|
||||
|
||||
const handleSetMpvPath = (e: File) => {
|
||||
const handleSetMpvPath = (e: File | null) => {
|
||||
if (e === null) {
|
||||
localSettings?.set('mpv_path', undefined);
|
||||
setMpvPath('');
|
||||
return;
|
||||
}
|
||||
|
||||
localSettings?.set('mpv_path', e.path);
|
||||
setMpvPath(e.path);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -100,6 +120,22 @@ export const MpvSettings = () => {
|
|||
mpvPlayer?.setProperties(mpvSetting);
|
||||
};
|
||||
|
||||
const handleReloadMpv = () => {
|
||||
pause();
|
||||
clearQueue();
|
||||
|
||||
const extraParameters = useSettingsStore.getState().playback.mpvExtraParameters;
|
||||
const properties: Record<string, any> = {
|
||||
speed: usePlayerStore.getState().current.speed,
|
||||
...getMpvProperties(useSettingsStore.getState().playback.mpvProperties),
|
||||
};
|
||||
mpvPlayer?.restart({
|
||||
binaryPath: mpvPath || undefined,
|
||||
extraParameters,
|
||||
properties,
|
||||
});
|
||||
};
|
||||
|
||||
const handleSetExtraParameters = (data: string[]) => {
|
||||
setSettings({
|
||||
playback: {
|
||||
|
@ -112,11 +148,35 @@ export const MpvSettings = () => {
|
|||
const options: SettingOption[] = [
|
||||
{
|
||||
control: (
|
||||
<Group spacing="sm">
|
||||
<Button
|
||||
tooltip={{
|
||||
label: t('common.reload', { postProcess: 'titleCase' }),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="subtle"
|
||||
onClick={handleReloadMpv}
|
||||
>
|
||||
<RiRestartLine />
|
||||
</Button>
|
||||
<FileInput
|
||||
placeholder={mpvPath}
|
||||
width={225}
|
||||
width={200}
|
||||
onChange={handleSetMpvPath}
|
||||
/>
|
||||
{mpvPath && (
|
||||
<Button
|
||||
tooltip={{
|
||||
label: t('common.clear', { postProcess: 'titleCase' }),
|
||||
openDelay: 0,
|
||||
}}
|
||||
variant="default"
|
||||
onClick={() => handleSetMpvPath(null)}
|
||||
>
|
||||
<RiCloseLine />
|
||||
</Button>
|
||||
)}
|
||||
</Group>
|
||||
),
|
||||
description: t('setting.mpvExecutablePath', {
|
||||
context: 'description',
|
||||
|
|
Reference in a new issue