Repository navigation
Conversation
|
Follow-up fix pushed ( mpv's The fix resolves yt-dlp with the same lookup already used for Verified from a real browser click with the userscript's |
|
Thanks, Let me test the modified code in a couple of days, when I have some free time, to see if it affects other platforms. |
macOS cannot register a bare executable as a URL scheme handler, and LaunchServices hands the URL over with the GURL Apple Event instead of the command line, so the binary could not be used there at all. A process started that way also only inherits PATH=/usr/bin:/bin:/usr/sbin:/sbin, which hides Homebrew and MacPorts installations, and it has no console to report errors to. - Run a minimal AppKit event loop (objc2) that receives the GURL event, dispatches it and exits, so every URL is handled by a fresh process and a long playback never blocks the next one - Look up mpv and yt-dlp in /opt/homebrew/bin, /usr/local/bin, /opt/local/bin, $HOME/.local/bin, $HOME/bin and inside mpv.app when they are not on $PATH - Use $HOME/.config/mpv-handler as the config directory so the layout matches Linux, with $XDG_CONFIG_HOME taking precedence - Open Terminal for mpv-handler-debug:// and show an alert on errors, because a bundle started by LaunchServices has no console - Add share/macos install/uninstall scripts that assemble, ad-hoc sign and register mpv-handler.app with LaunchServices, clearing com.apple.quarantine from the copy before anything executes it - Build a universal binary in CI and document macOS in all three READMEs
actions/upload-artifact does not preserve file modes, so the Linux and macOS binaries were packaged into the release archives as 644. share/macos/install.sh compensates by chmod-ing the bundle copy, but the archives themselves should carry the executable bit.
mpv's ytdl_hook looks yt-dlp up in its own $PATH unless --script-opts=ytdl_hook-ytdl_path is given. That option was only passed when `ytdl` was set in config.toml, so with the default config a bundle started by LaunchServices (PATH=/usr/bin:/bin:/usr/sbin:/sbin) failed extraction with "youtube-dl failed: not found or not enough permissions" and exited before a window could appear, while the very same URL played fine from a terminal, where $PATH contains the package manager dirs. Resolve yt-dlp with the same lookup used for mpv and always pass the resulting path to the player. Also prepend the extra binary directories to the child's PATH on macOS, because yt-dlp shells out to ffmpeg and ffprobe by name whenever it has to merge separate video and audio streams. Verified on macOS 15 (Apple Silicon) by triggering the handler from a browser with the userscript's console=no scheme: bilibili and YouTube both open a window and play, where before they exited silently.
share/macos/remote-install.sh downloads the latest release archive,
verifies it against the sha512sum asset shipped in the same release over
the same TLS connection, and then runs the install.sh from inside the
archive, so a whole install is one paste into a terminal:
curl -fsSL https://raw.githubusercontent.com/akiirui/mpv-handler/main/share/macos/remote-install.sh | sh
MPV_HANDLER_REPO and MPV_HANDLER_TAG select a different repository or pin
a release; any extra arguments are forwarded to install.sh, e.g.
`| sh -s -- -d /Applications`.
Drop the shell prompt from the curl | sh example so it can be pasted verbatim, and rename the section to spell out that it is a command.
A variable prefix before curl only reaches curl, not the sh reading the pipe, so document the working form: set it on the sh after the pipe.
Why
mpv-handler cannot be used on macOS at all today, for four reasons I verified empirically on macOS 15 (arm64):
.desktopfile or a registry entry: a URL scheme handler has to be an application bundle, so the bare binary cannot be registered.argv; it delivers it with theGURLApple Event (argc == 1when launched for a URL).PATH=/usr/bin:/bin:/usr/sbin:/sbin, so a Homebrew/MacPortsmpvoryt-dlpis invisible andrealpath("mpv")fails.What
src/macos.rs(new): a minimal AppKit event loop built onobjc2(define_class!+NSAppleEventManager) that receivesGURL, dispatches it through the existing plugin path and exits.terminate:is called after dispatching, so every URL is handled by a fresh process and a long playback never blocks the next one. A 30 s watchdog exits the bundle when LaunchServices starts it without a URL (e.g. a double click in the Finder).src/config.rs: on macOS,mpv/yt-dlpare additionally looked up in/opt/homebrew/bin,/usr/local/bin,/opt/local/bin,$HOME/.local/bin,$HOME/binand insidempv.appbundles; the config directory becomes$HOME/.config/mpv-handler(with$XDG_CONFIG_HOMEtaking precedence, and~/Library/Application Supportkept as a fallback when it already exists) so the layout matches Linux.src/plugins/play.rs:build_commandis split out ofexec, andexec_detachedstarts mpv without waiting, which is what the URL service needs.DYLD_*variables are removed for the same reasonLD_*already were.src/main.rs: with no arguments the binary enters the URL service only when it was started by LaunchServices (getppid() == 1); from a terminal it still prints the usage, so the CLI keeps working.mpv-handler-debug://opens Terminal and re-runs the CLI there (mirroring the Windows console window); errors of the normal scheme are shown withdisplay alert, since there is no console.share/macos/:Info.plist(one bundle claims both schemes,LSUIElement),install.sh(assembles the bundle, clearscom.apple.quarantinefrom the copy before anything executes it, ad-hoc signs it, registers it with LaunchServices, seeds the config dir, sets the default handler whendutiis present) anduninstall.sh.build-macosjob builds both targets and merges them withlipo; the release is packaged asmpv-handler-macos-universal.zip.[download-macos]link is now used and points at the universal archive.Linux and Windows behaviour is unchanged; all platform-specific code is
cfg-gated.Testing (macOS 15.8.1, Apple Silicon)
open "mpv-handler://play/<base64url>/?…"plays through Homebrew mpv with the expected--profile/format-sort/--title/--start/ cookies arguments.mpv-handler-debug://runs the CLI inside Terminal.file://) shows the alert instead of failing silently.install.sh/uninstall.shround-trip cleanly, including an archive carryingcom.apple.quarantine(no Gatekeeper "damaged" dialog).cargo test: 13 passed.cargo fmt --check: clean.cargo clippy --all-targets: the same 12 pre-existing warnings asmain, i.e. no new lint.Notes for review
objc2withdefault-features = false, which adds only seven crates toCargo.lock.getppid() == 1is what distinguishes a LaunchServices launch from a terminal one;__CFBundleIdentifierwas rejected because child processes inherit it.