fix(embedded-mpv): disable the youtube-dl hook in the frame-copy helper (#1526)

The native-view addons and the external MPV launch path already run with
`ytdl=no`, but the frame-copy helper left mpv's default, so a refused HTTP
open fell through to ytdl_hook and yt-dlp before failing. That delayed the
`error` transition the auto-reconnect policy waits for and could leave the
session error reading "youtube-dl failed: unexpected error occurred"
instead of the load error.

Set `ytdl=no` in the helper's built-in block, before the stdin
`mpv-options` loop, so a user `ytdl=yes` session option still overrides
it. Document the helper's built-in block next to the other session-option
transports and add a release note.

Verified by rebuilding the helper against Homebrew libmpv and driving the
binary by hand against a connection-refused URL: the built-in default logs
only the ffmpeg/stream errors, while a `ytdl=yes` stdin line spawns yt-dlp.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Fable 5.1 authored and GitHub committed 2026-09-04 20:00:43 +02:00
1 parent 302afb237a
commit 2f1ffe59f9
3 files changed
+27

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
---
type: fix
area: embedded-mpv
---
When a stream refuses the connection, the embedded MPV player (frame-copy
engine) no longer hands the URL to yt-dlp before giving up: the failure
shows up right away and its error no longer reads "youtube-dl failed:
unexpected error occurred", matching the native-view engines and the
external MPV player.
@@ -834,6 +834,12 @@ int main(int argc, char** argv) {
mpv_set_option_string(g_state.mpv, "idle", "yes");
mpv_set_option_string(g_state.mpv, "input-default-bindings", "no");
mpv_set_option_string(g_state.mpv, "osc", "no");
/* Keep parity with the native-view addons and the external MPV launch
* path: with mpv's youtube-dl hook enabled, a refused HTTP open falls
* through to yt-dlp and the session error reads "youtube-dl failed"
* instead of the load error. A user `ytdl=yes` session option
* (applied below, before mpv_initialize) still overrides it. */
mpv_set_option_string(g_state.mpv, "ytdl", "no");
if (!args.audioDelay.empty()) {
/* Compensates the frame-copy video-path latency to restore
* lip-sync; calibrated per platform, see the architecture doc. */
+11
View File
@@ -539,6 +539,17 @@ user line overrides both:
| Linux native-view | written to a user-only (0600) config file under `userData/embedded-mpv/options-<pid>/` and referenced as `--include=<path>` on the `mpv --wid` command line (before the per-playback options, so a playlist's user-agent/headers still win); the file is removed on dispose, the instance directory on shutdown, and another instance's leftovers only once its process is gone (two instances may share one `userData`) |
| Frame-copy helper | the first stdin line (`mpv-options`, helper started with `--mpv-options-stdin`), applied after the helper's built-in block |
The helper's own built-in block is `vo=libmpv`, the session's `hwdec`,
`keep-open=yes`, `idle=yes`, `input-default-bindings=no`, `osc=no` and
`ytdl=no`. The last one keeps parity with the native-view addons and the
external MPV launch path (`--ytdl=no` in `mpv-session.service.ts`): with
mpv's youtube-dl hook enabled, a refused HTTP open falls through to yt-dlp
before it fails, which delays the `error` transition and can leave the
session error reading `youtube-dl failed: unexpected error occurred`
instead of the load error (the helper stores every error-level libmpv log
line as the snapshot error, so whichever line lands last wins). A user
`ytdl=yes` line overrides it like every other built-in.
The list never appears on a command line: an option such as
`http-header-fields=Authorization: …` would otherwise be readable by every
local user through `ps` / `/proc/<pid>/cmdline`.