From eaa97daf65c659d901cd21139d770a44d4bcdfae Mon Sep 17 00:00:00 2001 From: Ricardo Constantino Date: Mon, 15 Jan 2018 17:56:44 +0000 Subject: ytdl_hook: pass http proxy to ffmpeg FFmpeg only suppports http proxies and ignores it if the resulting url is https. Also, no SOCKS. Use it like `--ytdl-raw-options=proxy=[http://127.0.0.1:3128]` so it doesn't confuse mpv because of the colons. You need to pass it as an option because youtube-dl doesn't give us the proxy. Or just set `http_proxy` environment variable as recommended before. Added example using -append, which doesn't need escaping. --- DOCS/man/options.rst | 8 ++++++++ player/lua/ytdl_hook.lua | 42 +++++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 57e79806c8..e44a69235b 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -590,10 +590,18 @@ Program Behavior 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. + .. admonition:: 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`` ``--load-stats-overlay=`` Enable the builtin script that shows useful playback information on a key diff --git a/player/lua/ytdl_hook.lua b/player/lua/ytdl_hook.lua index a63aedbfd4..7c537c206c 100644 --- a/player/lua/ytdl_hook.lua +++ b/player/lua/ytdl_hook.lua @@ -66,18 +66,16 @@ local function set_http_headers(http_headers) end end -local function append_rtmp_prop(props, name, value) - if not name or not value then - return props +local function append_libav_opt(props, name, value) + if not props then + props = {} end - if props and props ~= "" then - props = props.."," - else - props = "" + if name and value and not props[name] then + props[name] = value end - return props..name.."=\""..value.."\"" + return props end local function edl_escape(url) @@ -364,23 +362,31 @@ local function add_single_video(json) mp.set_property('file-local-options/video-aspect', json.stretched_ratio) end + local stream_opts = mp.get_property_native("file-local-options/stream-lavf-o", {}) + -- for rtmp if (json.protocol == "rtmp") then - local rtmp_prop = append_rtmp_prop(nil, + stream_opts = append_libav_opt(stream_opts, "rtmp_tcurl", streamurl) - rtmp_prop = append_rtmp_prop(rtmp_prop, + stream_opts = append_libav_opt(stream_opts, "rtmp_pageurl", json.page_url) - rtmp_prop = append_rtmp_prop(rtmp_prop, + stream_opts = append_libav_opt(stream_opts, "rtmp_playpath", json.play_path) - rtmp_prop = append_rtmp_prop(rtmp_prop, + stream_opts = append_libav_opt(stream_opts, "rtmp_swfverify", json.player_url) - rtmp_prop = append_rtmp_prop(rtmp_prop, + stream_opts = append_libav_opt(stream_opts, "rtmp_swfurl", json.player_url) - rtmp_prop = append_rtmp_prop(rtmp_prop, + stream_opts = append_libav_opt(stream_opts, "rtmp_app", json.app) + end - mp.set_property("file-local-options/stream-lavf-o", rtmp_prop) + -- ffmpeg ignores proxy if https is used and doesn't support SOCKS + if json.proxy and json.proxy ~= "" then + stream_opts = append_libav_opt(stream_opts, + "http_proxy", json.proxy) end + + mp.set_property_native("file-local-options/stream-lavf-o", stream_opts) end mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function () @@ -408,6 +414,7 @@ mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function () local format = mp.get_property("options/ytdl-format") local raw_options = mp.get_property_native("options/ytdl-raw-options") local allsubs = true + local proxy = nil local command = { ytdl.path, "--no-warnings", "-J", "--flat-playlist", @@ -437,6 +444,9 @@ mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function () if (param == "sub-lang") and (arg ~= "") then allsubs = false end + if (param == "proxy") and (arg ~= "") then + proxy = arg + end end if (allsubs == true) then @@ -470,6 +480,8 @@ mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function () msg.verbose("youtube-dl succeeded!") msg.debug('ytdl parsing took '..os.clock()-start_time..' seconds') + json["proxy"] = json["proxy"] or proxy + -- what did we get? if not (json["direct"] == nil) and (json["direct"] == true) then -- direct URL, nothing to do -- cgit v1.2.3