3 -- Copyright (C) 2011 Bastien Nocera <hadess@hadess.net>
5 -- This file is part of libquvi-scripts <http://quvi.sourceforge.net/>.
7 -- This library is free software; you can redistribute it and/or
8 -- modify it under the terms of the GNU Lesser General Public
9 -- License as published by the Free Software Foundation; either
10 -- version 2.1 of the License, or (at your option) any later version.
12 -- This library 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 GNU
15 -- Lesser General Public License for more details.
17 -- You should have received a copy of the GNU Lesser General Public
18 -- License along with this library; if not, write to the Free Software
19 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 -- For Soundcloud.toUtf8():
23 -- Copyright 2004 by Rici Lake. Permission is granted to use this code under
24 -- the same terms and conditions as found in the Lua copyright notice at
25 -- http://www.lua.org/license.html.
27 local Soundcloud
= {} -- Utility functions unique to this script
29 -- Identify the script.
31 package
.path
= self
.script_dir
.. '/?.lua'
32 local C
= require
'quvi/const'
34 r
.domain
= "soundcloud%.com"
36 r
.categories
= C
.proto_http
37 local U
= require
'quvi/util'
38 r
.handles
= U
.handles(self
.page_url
,
39 {r
.domain
}, {"/.+/.+$", "/player.swf"})
43 -- Query available formats.
44 function query_formats(self
)
45 self
.formats
= 'default'
51 self
.host_id
= "soundcloud"
53 Soundcloud
.normalize(self
)
55 local page
= quvi
.fetch(self
.page_url
)
57 local _
,_
,s
= page
:find("window%.SC%.bufferTracks%.push(%(.-%);)")
58 local metadata
= s
or error("no match: metadata")
60 local _
,_
,s
= metadata
:find('"uid":"(%w-)"')
61 self
.id
= s
or error("no match: media id")
63 local _
,_
,s
= metadata
:find('"title":"(.-)"')
64 local title
= s
or error("no match: media title")
65 -- Unescape the Unicode strings if any
66 -- the HTML will be unescaped by quvi itself
67 self
.title
= string.gsub(title
, "\\u(%x+)",
69 return Soundcloud
.toUtf8(tonumber(h
, 16))
72 local _
,_
,s
= page
:find('content="([:/%w%?%.-]-)" property="og:image"')
73 self
.thumbnail_url
= s
or ""
75 local _
,_
,s
= metadata
:find('"duration":(%d-),')
76 self
.duration
= tonumber(s
) or 0
78 local _
,_
,s
= metadata
:find('"streamUrl":"(.-)"')
79 self
.url
= { s
} or error("no match: stream URL")
88 function Soundcloud
.normalize(self
) -- "Normalize" an embedded URL
89 local url
= self
.page_url
:match('swf%?url=(.-)$')
90 if not url
then return end
92 local U
= require
'quvi/util'
93 local oe_url
= string.format(
94 'http://soundcloud.com/oembed?url=%s&format=json', U
.unescape(url
))
96 local s
= quvi
.fetch(oe_url
):match('href=\\"(.-)\\"')
97 self
.page_url
= s
or error('no match: page url')
100 -- Adapted from http://luaparse.luaforge.net/libquery.lua.html
102 -- Convert an integer to a UTF-8 sequence, without checking for
104 -- This originally had calls to floor scattered about but it is
105 -- not necessary: string.char does a "C" conversion from float to int,
106 -- which is a truncate towards zero operation; i must be non-negative,
107 -- so that is the same as floor.
108 function Soundcloud
.toUtf8(i
)
109 if i
<= 127 then return string.char(i
)
110 elseif i
<= tonumber("7FF", 16) then
111 return string.char(i
/ 64 + 192, math
.mod(i
, 64) + 128)
112 elseif i
<= tonumber("FFFF", 16) then
113 return string.char(i
/ 4096 + 224,
114 math
.mod(i
/ 64, 64) + 128,
115 math
.mod(i
, 64) + 128)
117 return string.char(i
/ 262144 + 240,
118 math
.mod(i
/ 4096, 64) + 128,
119 math
.mod(i
/ 64, 64) + 128,
120 math
.mod(i
, 64) + 128)
124 -- vim: set ts=4 sw=4 tw=72 expandtab: