From b4d0d8214111fd101bcbcbdc11fed3d080ff9e97 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Fri, 22 May 2026 18:10:37 -0400 Subject: [PATCH] fix(launcher): fix VLC stopping 10-15 seconds after open on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: run_cmd uses exec() which blocks until the child exits. The direct VLC binary forks its GUI process and exits — exec returns and the post_script begins. The old post_script polled for VLC focus (up to 10s) then sent Cmd+F, which fired mid-playback and stopped the video. Fix 1 — nohup + &: detaches VLC from exec immediately so run_cmd returns in ~0ms. This decouples the launcher flow from VLC's lifecycle. Fix 2 — --fullscreen flag: VLC opens fullscreen directly via CLI option. Eliminates the Cmd+F keystroke that was the proximate cause of the stop. Fix 3 — > /dev/null 2>&1: silences VLC's verbose logging to prevent exec's 1MB stdout buffer from overflowing and killing the process. post_script simplified to a single `tell application "VLC" activate` to bring VLC to the foreground after the 3s startup delay. Co-Authored-By: Claude Sonnet 4.6 --- .../ae_launcher__default_launch_profiles.ts | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/lib/ae_events/ae_launcher__default_launch_profiles.ts b/src/lib/ae_events/ae_launcher__default_launch_profiles.ts index 0b8a2f8c..02c80e86 100644 --- a/src/lib/ae_events/ae_launcher__default_launch_profiles.ts +++ b/src/lib/ae_events/ae_launcher__default_launch_profiles.ts @@ -55,33 +55,35 @@ export interface LaunchProfile { /** * macOS VLC profile — uses direct binary path for max reliability. * Bypasses `open -a` argument-handling quirks that could lose file path or re-use existing process. + * + * WHY nohup + &: + * run_cmd uses exec() which blocks until the child process exits (or the 30s timeout fires). + * The direct VLC binary forks a GUI process then exits — exec returns early and the code + * proceeds to the post_script. The old post_script polled for VLC focus (up to 10s) then + * sent Cmd+F, which was firing exactly 10–15 seconds into playback and stopping the video. + * nohup + & detaches VLC immediately so exec returns in ~0ms, decoupling run_cmd from + * VLC's lifecycle entirely. + * + * WHY --fullscreen: + * Starting VLC fullscreen via flag avoids the need to send Cmd+F via AppleScript. The old + * keystroke approach was the proximate cause of the video stopping — Cmd+F may have hit the + * wrong VLC window, triggered a menu action, or paused playback during the fullscreen + * transition. Using the flag is simpler and more reliable. + * + * WHY > /dev/null 2>&1: + * VLC logs verbosely to stdout/stderr. exec() buffers output (1MB default). Without + * redirection the buffer could overflow and kill VLC mid-playback. */ function make_vlc_mirror_mac_profile(): LaunchProfile { return { app: 'VLC (macOS)', display_mode: 'mirror', - // Direct binary path ensures VLC receives media file + flags reliably. - // `--no-play-and-exit` prevents closing on end, `--play-and-pause` holds final frame. - open_cmd: '/Applications/VLC.app/Contents/MacOS/VLC --no-play-and-exit --play-and-pause "{{path}}"', - post_delay_ms: 2000, - // Poll until VLC is frontmost before sending Cmd+F. Re-activate on every iteration — - // a single activate at the top is blocked by macOS focus-stealing prevention when VLC - // is spawned as a child of Electron (which stays frontmost). Retrying activate each loop - // keeps nudging macOS until it yields focus. Max wait: 20 × 0.5s = 10s after initial delay. - post_script: `repeat 20 times - tell application "VLC" - activate - end tell - delay 0.5 - tell application "System Events" - if frontmost of process "VLC" is true then exit repeat - end tell -end repeat -delay 0.3 -tell application "System Events" - tell process "VLC" - keystroke "f" using command down - end tell + open_cmd: 'nohup /Applications/VLC.app/Contents/MacOS/VLC --no-play-and-exit --play-and-pause --fullscreen "{{path}}" > /dev/null 2>&1 &', + post_delay_ms: 3000, + // Activate VLC after it has had time to open. Fullscreen is already set by the flag + // above — this just ensures VLC is the frontmost app and the presenter sees it. + post_script: `tell application "VLC" + activate end tell` }; }