1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
-- Copyright (C) 2010 Toni Gundogdu.
--
-- This file is part of quvi <http://quvi.googlecode.com/>.
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- Formats.
local lookup = {
mobile = "17", -- 3gp
sd_270p = "18", -- 480x270
sd_360p = "34", -- 640x360
hq_480p = "35", -- 854x480
hd_720p = "22", -- 1280x720
hd_1080p = "37" -- 1920x1080
}
-- Identify the script.
function ident (page_url)
local t = {}
t.domain = "youtube.com"
t.formats = ""
for k,_ in pairs (lookup) do
t.formats = t.formats .."|".. k
end
t.formats = "default|best" .. t.formats
if (page_url ~= nil) then
page_url = youtubify(page_url)
end
t.will_handle = (page_url ~= nil and page_url:find(t.domain) ~= nil)
return t
end
function parse (video)
video.host_id = "youtube"
local page_url = youtubify(video.page_url)
local _,_,s = page_url:find("v=([%w-_]+)")
video.id = s or error ("no match: video id")
local t,best = get_video_info (video)
if (t == nil) then
t,best = old_faithful (page_url, video)
end
local video_url =
string.format(
"http://youtube.com/get_video?video_id=%s&t=%s&asv=2",
video.id, quvi.unescape(t))
if (best == nil and video.requested_format == "best") then
print (" > Warning: Unable to find `best' format. Use `default'.")
end
local fmt_id = nil
if (video.requested_format == "best") then
fmt_id = best or fmt_id
else
for k,v in pairs (lookup) do
if (k == video.requested_format) then
fmt_id = v
break
end
end
end
if (fmt_id ~= nil) then
video_url = video_url .."&fmt=".. fmt_id
end
video.url = {video_url}
return video
end
-- Youtubify the URL.
function youtubify (url)
url = url:gsub("-nocookie", "") -- youtube-nocookie.com
url = url:gsub("/v/", "/watch?v=") -- embedded
return url
end
-- Should work around at least some of the videos that require
-- signing in first. Requires less bandwidth than the "old faithful".
-- This may, however, fail with some (older?) videos.
function get_video_info (video, result)
local config_url = string.format(
"http://www.youtube.com/get_video_info?&video_id=%s"
.. "&el=detailpage&ps=default&eurl=&gl=US&hl=en", video.id)
local config = quvi.unescape( quvi.fetch(config_url, "config") )
local _,_,s = config:find("&reason=(.-)[?:&]?$")
if (s ~= nil) then
local reason = s:gsub("+"," ")
local _,_,code = config:find("&errorcode=(.-)[?:&?$]")
if (code == "150") then error (reason) end
print (" > Warning: get_video_info: " .. reason)
print (" > Warning: Fetch video page instead.")
return nil -- This one's for the Old Faithful.
end
local _,_,s = config:find("&title=(.-)&")
video.title = s or error ("no match: video title")
video.title = video.title:gsub("+"," ")
local _,_,s = config:find("&token=(.-)&")
local t = s or error ("no match: token parameter")
local _,_,best = config:find("&fmt_map=(%d+)")
return t, best
end
-- As long as video is not otherwise retricted (e.g. age check), this function
-- should work with most videos. Page fetches, however, typically require
-- a lot more bandwidth compared to the config fetch (above).
function old_faithful (page_url, video)
local page = quvi.fetch(page_url)
local _,_,s = page:find('<meta name="title" content="(.-)"')
video.title = s or error ("no match: video title")
local _,_,s = page:find('&t=(.-)&')
local t = s or error ("no match: t param")
local _,_,best = page:find("&fmt_map=(%d+)")
return t, best
end
|