Skip to content

Commit

Permalink
lua: add youtube-dl hook script
Browse files Browse the repository at this point in the history
This merely adds the file without using it, for the sake of retaining
authorship information.

Signed-off-by: wm4 <wm4@nowhere>
  • Loading branch information
ChrisK2 authored and wm4 committed Nov 19, 2014
1 parent 9b8a62c commit 0f7df89
Showing 1 changed file with 163 additions and 0 deletions.
163 changes: 163 additions & 0 deletions player/lua/ytdl_hook.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
local utils = require 'mp.utils'
local msg = require 'mp.msg'

local ytdl = {
path = "youtube-dl",
minver = "2014.11.09",
vercheck = nil,
}

mp.add_hook("on_load", 10, function ()

local function exec(args)
local ret = utils.subprocess({args = args})
return ret.status, ret.stdout
end

local url = mp.get_property("stream-open-filename")

if (url:find("http://") == 1) or (url:find("https://") == 1)
or (url:find("ytdl://") == 1) then

-- check version of youtube-dl if not done yet
if (ytdl.vercheck == nil) then

-- check for youtube-dl in mpv's config dir
local ytdl_mcd = mp.find_config_file("youtube-dl")
if not (ytdl_mcd == nil) then
msg.verbose("found youtube-dl at: " .. ytdl_mcd)
ytdl.path = ytdl_mcd
end

msg.debug("checking ytdl version ...")
local es, version = exec({ytdl.path, "--version"})
if (es < 0) then
msg.warn("youtube-dl not found, not executable, or broken.")
ytdl.vercheck = false
elseif (version < ytdl.minver) then
msg.verbose("found youtube-dl version: " .. version)
msg.warn("Your version of youtube-dl is too old! "
.. "You need at least version '"..ytdl.minver
.. "', try running `youtube-dl -U`.")
ytdl.vercheck = false
else
msg.verbose("found youtube-dl version: " .. version)
ytdl.vercheck = true
end
end

if not (ytdl.vercheck) then
return
end

-- strip ytdl://
if (url:find("ytdl://") == 1) then
url = url:sub(8)
end

-- subformat workaround
local subformat = "srt"
if url:find("crunchyroll.com") then
subformat = "ass"
end

local es, json = exec({
ytdl.path, "-J", "--flat-playlist", "--all-subs",
"--sub-format", subformat, "--no-playlist", "--", url
})

if (es < 0) or (json == nil) or (json == "") then
msg.warn("youtube-dl failed, trying to play URL directly ...")
return
end

local json, err = utils.parse_json(json)

if (json == nil) then
msg.error("failed to parse JSON data: " .. err)
return
end

msg.info("youtube-dl succeeded!")

-- what did we get?
if not (json["direct"] == nil) and (json["direct"] == true) then

This comment has been minimized.

Copy link
@shdown

shdown Nov 19, 2014

Contributor

This can be reduced to if json["direct"] == true then, isn't it?

-- direct URL, nothing to do
msg.verbose("Got direct URL")
return
elseif not (json["_type"] == nil) and (json["_type"] == "playlist") then

This comment has been minimized.

Copy link
@shdown

shdown Nov 19, 2014

Contributor

The same thing here…

-- a playlist

local playlist = "#EXTM3U\n"
for i, entry in pairs(json.entries) do
local site = entry.url

-- some extractors will still return the full info for
-- all clips in the playlist and the URL will point
-- directly to the file in that case, which we don't
-- want so get the webpage URL instead, which is what
-- we want
if not (entry["webpage_url"] == nil) then
site = entry["webpage_url"]
end

playlist = playlist .. "ytdl://" .. site .. "\n"
end

mp.set_property("stream-open-filename", "memory://" .. playlist)

else -- probably a video
local streamurl = ""

-- DASH?
if not (json["requested_formats"] == nil) then
msg.info("NOTE: Using DASH, expect inaccurate duration.")
-- video url
streamurl = json["requested_formats"][1].url

-- audio url
mp.set_property("file-local-options/audio-file",
json["requested_formats"][2].url)

-- workaround for slow startup (causes inaccurate duration)
mp.set_property("file-local-options/demuxer-lavf-o",
"fflags=+ignidx")

elseif not (json.url == nil) then
-- normal video
streamurl = json.url
else
msg.error("No URL found in JSON data.")
return
end

msg.debug("streamurl: " .. streamurl)

mp.set_property("stream-open-filename", streamurl)

mp.set_property("file-local-options/media-title", json.title)

-- add subtitles
if not (json.subtitles == nil) then
for lang, script in pairs(json.subtitles) do
msg.verbose("adding subtitle ["..lang.."]")

local slang = lang

This comment has been minimized.

Copy link
@shdown

shdown Nov 19, 2014

Contributor

And this can be reduced to

mp.commandv("sub_add", "memory://"..script,
    "auto", lang.." "..subformat, lang:sub(1, 2))
if (lang:len() > 3) then
slang = lang:sub(1,2)
end

mp.commandv("sub_add", "memory://"..script,
"auto", lang.." "..subformat, slang)
end
end

-- for rtmp
if not (json.play_path == nil) then
mp.set_property("file-local-options/stream-lavf-o",
"rtmp_tcurl=\""..streamurl..
"\",rtmp_playpath=\""..json.play_path.."\"")
end
end
end
end)

0 comments on commit 0f7df89

Please sign in to comment.