diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index c216f88ede..34d29db083 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -995,9 +995,11 @@ Program Behavior no). It's disabled ("no") by default for performance reasons. ``ytdl_path=youtube-dl`` - Configure path to youtube-dl executable or a compatible fork's. - The default "youtube-dl" looks for the executable in PATH. In a Windows - environment the suffix extension ".exe" is always appended. + 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 ".exe" is always appended. .. admonition:: Why do the option names mix ``_`` and ``-``? diff --git a/player/lua/ytdl_hook.lua b/player/lua/ytdl_hook.lua index b9cb04645e..27d39afb75 100644 --- a/player/lua/ytdl_hook.lua +++ b/player/lua/ytdl_hook.lua @@ -8,11 +8,12 @@ local o = { use_manifests = false, all_formats = false, force_all_formats = true, - ytdl_path = "youtube-dl", + ytdl_path = "", } local ytdl = { - path = nil, + path = "", + paths_to_search = {"yt-dlp", "yt-dlp_x86", "youtube-dl"}, searched = false, blacklisted = {} } @@ -88,7 +89,13 @@ local function map_codec_to_mpv(codec) return nil end +local function platform_is_windows() + return package.config:sub(1,1) == "\\" +end + local function exec(args) + msg.debug("Running: " .. table.concat(args, " ")) + local ret = mp.command_native({name = "subprocess", args = args, capture_stdout = true, @@ -718,20 +725,6 @@ end function run_ytdl_hook(url) local start_time = os.clock() - -- check for youtube-dl in mpv's config dir - if not (ytdl.searched) then - local exesuf = (package.config:sub(1,1) == '\\') and '.exe' or '' - local ytdl_mcd = mp.find_config_file(o.ytdl_path .. exesuf) - if ytdl_mcd == nil then - msg.verbose("No youtube-dl found with path "..o.ytdl_path..exesuf.." in config directories") - ytdl.path = o.ytdl_path - else - msg.verbose("found youtube-dl at: " .. ytdl_mcd) - ytdl.path = ytdl_mcd - end - ytdl.searched = true - end - -- strip ytdl:// if (url:find("ytdl://") == 1) then url = url:sub(8) @@ -786,8 +779,45 @@ function run_ytdl_hook(url) end table.insert(command, "--") table.insert(command, url) - msg.debug("Running: " .. table.concat(command,' ')) - local es, json, result, aborted = exec(command) + + local es, json, result, aborted + if ytdl.searched then + es, json, result, aborted = exec(command) + else + local separator = platform_is_windows() and ";" or ":" + if o.ytdl_path:match("[^" .. separator .. "]") then + ytdl.paths_to_search = {} + for path in o.ytdl_path:gmatch("[^" .. separator .. "]+") do + table.insert(ytdl.paths_to_search, path) + end + end + + for _, path in pairs(ytdl.paths_to_search) do + -- search for youtube-dl in mpv's config dir + local exesuf = platform_is_windows() and ".exe" or "" + local ytdl_cmd = mp.find_config_file(path .. exesuf) + if ytdl_cmd then + msg.verbose("Found youtube-dl at: " .. ytdl_cmd) + ytdl.path = ytdl_cmd + command[1] = ytdl.path + es, json, result, aborted = exec(command) + break + else + msg.verbose("No youtube-dl found with path " .. path .. exesuf .. " in config directories") + command[1] = path + es, json, result, aborted = exec(command) + if result.error_string == "init" then + msg.verbose("youtube-dl with path " .. path .. exesuf .. " not found in PATH or not enough permissions") + else + msg.verbose("Found youtube-dl with path " .. path .. exesuf .. " in PATH") + ytdl.path = path + break + end + end + end + + ytdl.searched = true + end if aborted then return