Solution to the Failure to Pass Cookies into yt-dlp When Using mpv
Issue Description
When using mpv to play videos from Bilibili, users may encounter issues where mpv fails to pass cookies to yt-dlp correctly, regardless of whether the cookies are already in Netscape format, leading to error messages like the following:
→ mpv --cookies-file="~/bilibili_cookies.txt" --ytdl-raw-options=format=100028+30280 https://www.bilibili.com/video/BV1HMH7z4ES4
[ytdl_hook] ERROR: [BiliBili] BV1HMH7z4ES4: Requested format is not available. Use --list-formats for a list of available formats
[ytdl_hook] youtube-dl failed: unexpected error occurred
Failed to recognize file format.
The format 100028+30280 is a valid format on Bilibili, but only extractable when the user is logged in, which requires the correct cookies to be passed to yt-dlp, which is the default backend for mpv to handle online video playback.
And yt-dlp works correctly when run directly from the command line with the same cookies file, as shown below:
→ yt-dlp --cookies ~/bilibili_cookies.txt -F https://www.bilibili.com/video/BV1HMH7z4ES4
[BiliBili] Extracting URL: https://www.bilibili.com/video/BV1HMH7z4ES4
[BiliBili] 1HMH7z4ES4: Downloading webpage
[BiliBili] BV1HMH7z4ES4: Extracting videos in anthology
[BiliBili] 115294152429445: Extracting chapters
[info] Available formats for BV1HMH7z4ES4:
ID EXT RESOLUTION FPS │ FILESIZE TBR PROTO │ VCODEC VBR ACODEC ABR
────────────────────────────────────────────────────────────────────────────────────────
30216 m4a audio only │ ≈ 4.75MiB 66k https │ audio only mp4a.40.2 66k
30232 m4a audio only │ ≈ 6.51MiB 90k https │ audio only mp4a.40.2 90k
30280 m4a audio only │ ≈ 12.29MiB 170k https │ audio only mp4a.40.2 170k
30016 mp4 640x360 30 │ ≈ 37.97MiB 525k https │ avc1.640033 525k video only
30011 mp4 640x360 30 │ ≈ 19.60MiB 271k https │ hev1.1.6.L120 271k video only
100022 mp4 640x360 30 │ ≈ 17.67MiB 244k https │ av01.0.00M.10 244k video only
30032 mp4 852x480 30 │ ≈ 42.78MiB 592k https │ avc1.640033 592k video only
30033 mp4 852x480 30 │ ≈ 30.14MiB 417k https │ hev1.1.6.L120 417k video only
100023 mp4 852x480 30 │ ≈ 27.26MiB 377k https │ av01.0.00M.10 377k video only
30064 mp4 1280x720 30 │ ≈ 91.79MiB 1270k https │ avc1.640033 1270k video only
30066 mp4 1280x720 30 │ ≈ 38.52MiB 533k https │ hev1.1.6.L120 533k video only
100024 mp4 1280x720 30 │ ≈ 33.92MiB 469k https │ av01.0.00M.10 469k video only
30080 mp4 1920x1080 30 │ ≈227.13MiB 3142k https │ avc1.640033 3142k video only
30077 mp4 1920x1080 30 │ ≈134.75MiB 1864k https │ hev1.1.6.L150 1864k video only
100026 mp4 1920x1080 30 │ ≈119.37MiB 1652k https │ av01.0.00M.10 1652k video only
30116 mp4 1920x1080 60 │ ≈438.46MiB 6066k https │ avc1.640033 6066k video only
30106 mp4 1920x1080 60 │ ≈297.63MiB 4118k https │ hev1.1.6.L150 4118k video only
100028 mp4 1920x1080 60 │ ≈263.72MiB 3649k https │ av01.0.00M.10 3649k video only
Solutions
The issue arises since mpv did not correctly pass the cookies file to yt-dlp. To resolve this, you can use the --ytdl-raw-options flag to explicitly specify the cookies file for yt-dlp.
Solution 1: Specify Cookies File Directly
→ mpv --ytdl-raw-options=cookies="~/bilibili_cookies.txt",format=100028+30280 https://www.bilibili.com/video/BV1HMH7z4ES4
Solution 2: Use Browser Cookies
→ mpv --ytdl-raw-options=cookies-from-browser=safari,format=100028+30280 https://www.bilibili.com/video/BV1HMH7z4ES4
Reference
-
--cookies-file=<filename> Read HTTP cookies from <filename>. The file is assumed to be in Netscape format. -
--ytdl-raw-options=<key>=<value>[,<key>=<value>[,...]] Pass arbitrary options to youtube-dl. Parameter and argument should be passed as a key-value pair. Options without argument must include =. There is no sanity checking so it's possible to break things (i.e. passing invalid parameters to youtube-dl). A proxy URL can be passed for youtube-dl to use it in parsing the website. This is useful for geo-restricted URLs. After youtube-dl parsing, some URLs also require a proxy for playback, so this can pass that proxy information to mpv. Take note that SOCKS proxies aren't supported and https URLs also bypass the proxy. This is a limitation in FFmpeg. This is a key/value list option. See List Options for details. Example • --ytdl-raw-options=username=user,password=pass • --ytdl-raw-options=force-ipv6= • --ytdl-raw-options=proxy=[http://127.0.0.1:3128] • --ytdl-raw-options-append=proxy=http://127.0.0.1:3128 -
--ytdl=<yes|no> Enable the youtube-dl hook-script. It will look at the input URL, and will play the video located on the website. This works with many streaming sites, not just the one that the script is named after. This requires a recent version of youtube-dl to be installed on the system (default: yes). If the script can't do anything with an URL, it will do nothing. This accepts a set of options, which can be passed to it with the --script-opts option (using ytdl_hook- as prefix): ... ... ytdl_path=youtube-dl Configure paths to youtube-dl's executable or a compatible fork's. The paths should be separated by : on Unix and ; on Windows. mpv looks in order for the configured paths in PATH and in mpv's config directory. The defaults are "yt-dlp", "yt-dlp_x86" and "youtube-dl". On Windows the suffix extension is not necessary, but only ".exe" is acceptable.