summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorRicardo Constantino <wiiaboo@gmail.com>2018-01-15 21:16:36 +0000
committerKevin Mitchell <kevmitch@gmail.com>2018-02-11 23:27:36 -0800
commit664e8fe66ae8532471c2528e86812122af6a04dd (patch)
tree7cd8f04f6ddbbe4c31fe8d5486e6a315f70e6d97 /player
parent976daf194249e16ca430ab514a884b1100fa32ca (diff)
downloadmpv-664e8fe66ae8532471c2528e86812122af6a04dd.tar.bz2
mpv-664e8fe66ae8532471c2528e86812122af6a04dd.tar.xz
ytdl_hook: parse youtube playlist urls to set start index
Still needs `--ytdl-raw-option=yes-playlist=` because this only works for youtube. This was requested in a few issues: https://github.com/mpv-player/mpv/issues/1400 https://github.com/mpv-player/mpv/issues/2592 https://github.com/mpv-player/mpv/issues/3024 For #1400 to be completely implemented would need ytdl_hook to re-request the same playlist with the last video's ID for the mix to continue indefinitely which would probably too hackish to work reliably.
Diffstat (limited to 'player')
-rw-r--r--player/lua/ytdl_hook.lua58
1 files changed, 53 insertions, 5 deletions
diff --git a/player/lua/ytdl_hook.lua b/player/lua/ytdl_hook.lua
index b76297033f..59ffbd3b94 100644
--- a/player/lua/ytdl_hook.lua
+++ b/player/lua/ytdl_hook.lua
@@ -142,6 +142,45 @@ local function is_blacklisted(url)
return false
end
+local function parse_yt_playlist(url, json)
+ -- return 0-based index to use with --playlist-start
+
+ if not json.extractor or json.extractor ~= "youtube:playlist" then
+ return nil
+ end
+
+ local query = url:match("%?.+")
+ if not query then return nil end
+
+ local args = {}
+ for arg, param in query:gmatch("(%a+)=([^&?]+)") do
+ if arg and param then
+ args[arg] = param
+ end
+ end
+
+ local maybe_idx = tonumber(args["index"])
+
+ -- if index matches v param it's probably the requested item
+ if maybe_idx and #json.entries >= maybe_idx and
+ json.entries[maybe_idx].id == args["v"] then
+ msg.debug("index matches requested video")
+ return maybe_idx - 1
+ end
+
+ -- if there's no index or it doesn't match, look for video
+ for i = 1, #json.entries do
+ if json.entries[i] == args["v"] then
+ msg.debug("found requested video in index " .. (i - 1))
+ return i - 1
+ end
+ end
+
+ msg.debug("requested video not found in playlist")
+ -- if item isn't on the playlist, give up
+ return nil
+end
+
local function make_absolute_url(base_url, url)
if url:find("https?://") == 1 then return url end
@@ -417,10 +456,11 @@ mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function ()
local raw_options = mp.get_property_native("options/ytdl-raw-options")
local allsubs = true
local proxy = nil
+ local use_playlist = false
local command = {
ytdl.path, "--no-warnings", "-J", "--flat-playlist",
- "--sub-format", "ass/srt/best", "--no-playlist"
+ "--sub-format", "ass/srt/best"
}
-- Checks if video option is "no", change format accordingly,
@@ -445,15 +485,19 @@ mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function ()
end
if (param == "sub-lang") and (arg ~= "") then
allsubs = false
- end
- if (param == "proxy") and (arg ~= "") then
+ elseif (param == "proxy") and (arg ~= "") then
proxy = arg
+ elseif (param == "yes-playlist") then
+ use_playlist = true
end
end
if (allsubs == true) then
table.insert(command, "--all-subs")
end
+ if not use_playlist then
+ table.insert(command, "--no-playlist")
+ end
table.insert(command, "--")
table.insert(command, url)
msg.debug("Running: " .. table.concat(command,' '))
@@ -559,6 +603,7 @@ mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function ()
msg.verbose("Playlist with single entry detected.")
add_single_video(json.entries[1])
else
+ local playlist_index = parse_yt_playlist(url, json)
local playlist = {"#EXTM3U"}
for i, entry in pairs(json.entries) do
local site = entry.url
@@ -589,9 +634,12 @@ mp.add_hook(o.try_ytdl_first and "on_load" or "on_load_fail", 10, function ()
end
- if #playlist > 0 then
- mp.set_property("stream-open-filename", "memory://" .. table.concat(playlist, "\n"))
+ if use_playlist and
+ not option_was_set("playlist-start") and playlist_index then
+ mp.set_property_number("playlist-start", playlist_index)
end
+
+ mp.set_property("stream-open-filename", "memory://" .. table.concat(playlist, "\n"))
end
else -- probably a video