8dfbe7e4ed166573f0d44670b7383e6084de7434
[vlc.git] / share / lua / playlist / soundcloud.lua
1 --[[
2  $Id$
3
4  Copyright © 2012, 2015 the VideoLAN team
5
6  Authors: Cheng Sun <chengsun9atgmail.com>
7           Pierre Ynard
8
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 --]]
23
24 -- Probe function.
25 function probe()
26     return ( vlc.access == "http" or vlc.access == "https" )
27         and string.match( vlc.path, "soundcloud%.com/.+/.+" )
28 end
29
30 function fix_quotes( value )
31     if string.match( value, "^\"" ) then
32         return "" -- field was really empty string
33     end
34
35     -- TODO: handle escaped backslashes and others
36     return string.gsub( value, "\\\"", "\"" )
37 end
38
39 -- Parse function.
40 function parse()
41     while true do
42         line = vlc.readline()
43         if not line then break end
44
45         -- Parameters for API call
46         if not track then
47             track = string.match( line, "soundcloud:tracks:(%d+)" )
48         end
49
50         -- For private tracks
51         if not secret then
52             secret = string.match( line, "[\"']secret_token[\"'] *: *[\"'](.-)[\"']" )
53         end
54
55         -- Metadata
56         if not name then
57             name = string.match( line, "[\"']title[\"'] *: *\"(.-[^\\])\"" )
58             if name then
59                 name = fix_quotes( name )
60             end
61         end
62
63         if not description then
64             description = string.match( line, "[\"']artwork_url[\"'] *:.-[\"']description[\"'] *: *\"(.-[^\\])\"" )
65             if description then
66                 description = fix_quotes( description )
67             end
68         end
69
70         if not artist then
71             artist = string.match( line, "[\"']username[\"'] *: *\"(.-[^\\])\"" )
72             if artist then
73                 artist = fix_quotes( artist )
74             end
75         end
76
77         if not arturl then
78             arturl = string.match( line, "[\"']artwork_url[\"'] *: *[\"'](.-)[\"']" )
79         end
80     end
81
82     if track then
83         -- API magic
84         local client_id = "02gUJC0hH2ct1EGOcYXQIzRFU91c72Ea"
85         -- app_version is not required by the API but we send it anyway
86         -- to remain unconspicuous
87         local app_version = "a089efd"
88
89         local api = vlc.stream( vlc.access.."://api.soundcloud.com/i1/tracks/"..track.."/streams?client_id="..client_id.."&app_version="..app_version..( secret and "&secret_token="..secret or "" ) )
90
91         if api then
92             local streams = api:readline() -- data is on one line only
93             -- For now only quality available is 128 kbps (http_mp3_128_url)
94             path = string.match( streams, "[\"']http_mp3_%d+_url[\"'] *: *[\"'](.-)[\"']" )
95             if path then
96                 -- FIXME: do this properly
97                 path = string.gsub( path, "\\u0026", "&" )
98             end
99         end
100     end
101
102     if not path then
103         vlc.msg.err( "Couldn't extract soundcloud audio URL, please check for updates to this script" )
104         return { }
105     end
106
107     return { { path = path, name = name, description = description, artist = artist, arturl = arturl } }
108 end