3
* Copyright (C) 2010 Toni Gundogdu.
5
* This file is part of quvi, see http://quvi.googlecode.com/
7
* This program is free software: you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation, either version 3 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
-- If you make improvements to this script, drop a line. Thanks.
23
-- <http://quvi.googlecode.com/>
27
* This script fetches "video info" first
28
- Advantages: requires less bandwidth, works around sign-in-to-view
29
- Disadvantages: fails frequently for still unknown reason
31
- Dump server returned error to stdout as a warning
32
- Fetch and parse video page instead
33
- Advantages: works for most (unrestricted) videos
35
- Requires (a lot) more bandwidth
36
- Does not work with videos that require signing-in-to-view
39
-- These are my formats.
42
sd_270p = "18", -- 480x270
43
sd_360p = "34", -- 640x360
44
hq_480p = "35", -- 854x480
45
hd_720p = "22", -- 1280x720
46
hd_1080p = "37" -- 1920x1080
49
-- Returns script details.
50
function ident (page_url)
52
-- This is what I return.
56
t.domain = "youtube.com"
58
-- This is my formats-string.
60
for k,_ in pairs (lookup) do
61
t.formats = t.formats .."|".. k
63
t.formats = "default|best" .. t.formats
65
-- This is my response to "Will you handle this URL?"
66
-- Note that page_url may be nil.
67
if (page_url ~= nil) then
68
page_url = youtubify(page_url)
70
t.will_handle = (page_url ~= nil and page_url:find(t.domain) ~= nil)
72
-- Here are my details.
77
-- Fetches video page and parses the video URL.
78
function parse (video)
80
-- This is my "host ID".
81
video.host_id = "youtube"
84
local page_url = youtubify(video.page_url)
86
-- This is my video ID.
87
local _,_,s = page_url:find("v=([%w-_]+)")
88
video.id = s or error ("no match: video id")
91
video,t,best = get_video_info(video)
92
if (video.title == nil) then
93
video,t,best = old_faithful(page_url, video)
96
-- Construct the video URL.
99
"http://youtube.com/get_video?video_id=%s&t=%s",
100
video.id, quvi.unescape(t))
102
-- Choose correct format ID.
103
if (best == nil and video.requested_format == "best") then
104
print (" > Warning: Unable to find `best' format. Use `default'.")
109
if (video.requested_format == "best") then
110
fmt_id = best or fmt_id
112
for k,v in pairs (lookup) do
113
if (k == video.requested_format) then
120
if (fmt_id ~= nil) then
121
video_url = video_url .."&fmt=".. fmt_id
125
video.url = {video_url}
127
-- Return the updated video properties.
132
-- Youtube video page URL unwrangler.
133
function youtubify (url)
134
url = url:gsub("-nocookie", "") -- youtube-nocookie.com
135
url = url:gsub("/v/", "/watch?v=") -- embedded
139
-- The preferred method, uses less bandwidth, fails for some videos.
140
-- See also the NOTES above.
141
function get_video_info (video)
144
local config_url = string.format(
145
"http://www.youtube.com/get_video_info?&video_id=%s"
146
.. "&el=detailpage&ps=default&eurl=&gl=US&hl=en", video.id)
148
local config = quvi.unescape( quvi.fetch(config_url, "config") )
150
-- Check response. For still unknown reasons, the above
151
-- does not work for all videos that I've tried so far.
152
local _,_,s = config:find("&reason=(.-)[?:&]?$")
154
print (" > Warning: get_video_info: " .. s:gsub("+"," "))
155
print (" > Warning: Revert to fetch video page instead.")
156
return video -- This one's for the Old Faithful.
159
-- This is my video title.
160
local _,_,s = config:find("&title=(.-)&")
161
video.title = s or error ("no match: video title")
162
video.title = video.title:gsub("+"," ")
164
-- This is my t(oken) param used to construct the video URL.
165
local _,_,s = config:find("&token=(.-)&")
166
local t = s or error ("no match: token parameter")
169
local _,_,best = config:find("&fmt_map=(%d+)")
171
-- Return parsed details.
172
return video, t, best
176
-- Fetch video page from the user specified URL and parse.
177
-- See also the NOTES above.
178
function old_faithful (page_url, video)
181
local page = quvi.fetch(page_url)
183
-- This is my video title.
184
local _,_,s = page:find('<meta name="title" content="(.-)"')
185
video.title = s or error ("no match: video title")
187
-- This is my t param used to construct the video URL.
188
local _,_,s = page:find('&t=(.-)&')
189
local t = s or error ("no match: t param")
192
local _,_,best = page:find("&fmt_map=(%d+)")
194
-- Return parsed details.
195
return video, t, best