fix(electron): resolve macOS external player app paths (#924)

* fix(electron): resolve macOS external player app paths

* fix(electron): make macos player executable mapping explicit
This commit is contained in:
4gray authored and GitHub committed 2026-05-10 23:36:35 +02:00
1 parent 1ca291d35c
commit a2ecdc358f
2 files changed
+99 -4

No files matched your search

@@ -145,6 +145,60 @@ describe('player.events Flatpak launch helpers', () => {
});
});
it('resolves custom macOS MPV app bundles to their executable', () => {
const launchContext = resolveExternalPlayerLaunchContext(
'mpv',
'/Applications/mpv copy.app',
{
platform: 'darwin',
isFlatpak: false,
}
);
expect(launchContext).toEqual({
mode: 'direct',
playerPath: '/Applications/mpv copy.app/Contents/MacOS/mpv',
command: '/Applications/mpv copy.app/Contents/MacOS/mpv',
argsPrefix: [],
});
});
it('resolves custom macOS VLC app bundles to their executable', () => {
const launchContext = resolveExternalPlayerLaunchContext(
'vlc',
'/Applications/VLC.app/',
{
platform: 'darwin',
isFlatpak: false,
}
);
expect(launchContext).toEqual({
mode: 'direct',
playerPath: '/Applications/VLC.app/Contents/MacOS/VLC',
command: '/Applications/VLC.app/Contents/MacOS/VLC',
argsPrefix: [],
});
});
it('keeps custom macOS executable player paths unchanged', () => {
const launchContext = resolveExternalPlayerLaunchContext(
'mpv',
'/Applications/mpv.app/Contents/MacOS/mpv',
{
platform: 'darwin',
isFlatpak: false,
}
);
expect(launchContext).toEqual({
mode: 'direct',
playerPath: '/Applications/mpv.app/Contents/MacOS/mpv',
command: '/Applications/mpv.app/Contents/MacOS/mpv',
argsPrefix: [],
});
});
it('disables MPV reuse and socket bridging only in Flatpak', () => {
expect(shouldReuseMpvInstance(true, true)).toBe(false);
expect(shouldUseMpvSocketBridge(true)).toBe(false);
@@ -93,6 +93,42 @@ function normalizePlayerPathForStore(value: string | null | undefined): string {
return normalizeCustomPlayerPath(value) ?? '';
}
const macOSAppBundleExecutableNames: Record<ExternalPlayerName, string> = {
mpv: 'mpv',
vlc: 'VLC',
};
function getMacOSAppBundleExecutableName(player: ExternalPlayerName): string {
return macOSAppBundleExecutableNames[player];
}
function removeTrailingPathSeparators(value: string): string {
return value.replace(/[\\/]+$/, '') || value;
}
function resolveMacOSAppBundlePlayerPath(
player: ExternalPlayerName,
playerPath: string,
platform: NodeJS.Platform
): string {
if (platform !== 'darwin') {
return playerPath;
}
const appBundlePath = removeTrailingPathSeparators(playerPath);
if (!/\.app$/i.test(appBundlePath)) {
return playerPath;
}
return path.join(
appBundlePath,
'Contents',
'MacOS',
getMacOSAppBundleExecutableName(player)
);
}
function getDefaultPlayerPath(
player: ExternalPlayerName,
options: PlayerPathOptions = {}
@@ -131,20 +167,25 @@ export function resolveExternalPlayerLaunchContext(
isFlatpak,
pathExists,
});
const resolvedPlayerPath = resolveMacOSAppBundlePlayerPath(
player,
playerPath,
platform
);
if (platform === 'linux' && isFlatpak) {
return {
mode: 'flatpak-host',
playerPath,
playerPath: resolvedPlayerPath,
command: 'flatpak-spawn',
argsPrefix: ['--host', '--watch-bus', playerPath],
argsPrefix: ['--host', '--watch-bus', resolvedPlayerPath],
};
}
return {
mode: 'direct',
playerPath,
command: playerPath,
playerPath: resolvedPlayerPath,
command: resolvedPlayerPath,
argsPrefix: [],
};
}