[vlc-devel] [PATCH] soundcloud.lua: Rewrite to support playlist and user tracks
Mario Rodas
rodasmario2 at gmail.com
Wed Dec 14 18:15:18 CET 2016
---
share/lua/playlist/soundcloud.lua | 116 ++++++++++++++++----------------------
1 file changed, 49 insertions(+), 67 deletions(-)
diff --git a/share/lua/playlist/soundcloud.lua b/share/lua/playlist/soundcloud.lua
index d22c45b..71df917 100644
--- a/share/lua/playlist/soundcloud.lua
+++ b/share/lua/playlist/soundcloud.lua
@@ -26,85 +26,67 @@ function probe()
local path = vlc.path
path = path:gsub("^www%.", "")
return ( vlc.access == "http" or vlc.access == "https" )
- and string.match( path, "^soundcloud%.com/.+/.+" )
+ and string.match( path, "^soundcloud%.com/.+" )
end
-function fix_quotes( value )
- if string.match( value, "^\"" ) then
- return "" -- field was really empty string
- end
+function parse_json(url)
+ vlc.msg.dbg("Trying to parse JSON from " .. url)
+ local json = require ("dkjson")
- -- TODO: handle escaped backslashes and others
- return string.gsub( value, "\\\"", "\"" )
-end
+ -- Use vlc.stream to grab a remote json file, place it in a string,
+ -- decode it and return the decoded data.
+ local stream = vlc.stream(url)
+ local string = ""
+ local line = ""
+
+ if not stream then return false end
--- Parse function.
-function parse()
while true do
- line = vlc.readline()
+ line = stream:read(65536)
if not line then break end
- -- Parameters for API call
- if not track then
- track = string.match( line, "soundcloud:tracks:(%d+)" )
- end
-
- -- For private tracks
- if not secret then
- secret = string.match( line, "[\"']secret_token[\"'] *: *[\"'](.-)[\"']" )
- end
+ string = string .. line
+ end
- -- Metadata
- if not name then
- name = string.match( line, "[\"']title[\"'] *: *\"(.-[^\\])\"" )
- if name then
- name = fix_quotes( name )
- end
- end
+ return json.decode(string)
+end
- if not description then
- description = string.match( line, "[\"']artwork_url[\"'] *:.-[\"']description[\"'] *: *\"(.-[^\\])\"" )
- if description then
- description = fix_quotes( description )
- end
- end
+-- Create a playlist item from a soundcloud track resource
+function create_track(item, client_id)
+ local url = item.downloadable and item.download_url or item.stream_url
+ return { path = url .. "?client_id=" .. client_id,
+ name = item.user.username .. " - " .. item.title,
+ title = item.title,
+ artist = item.user.username,
+ date = item.created_at,
+ genre = item.genre,
+ arturl = item.artwork_url or item.user.avatar_url,
+ rating = item.favoritings_count,
+ copyright = item.license,
+ description = item.description }
+end
- if not artist then
- artist = string.match( line, "[\"']username[\"'] *: *\"(.-[^\\])\"" )
- if artist then
- artist = fix_quotes( artist )
- end
+-- Parse function.
+function parse()
+ local client_id = "fDoItMDbsbZz8dY16ZzARCZmzgHBPotA"
+ local response = parse_json(vlc.access .. "://api.soundcloud.com/resolve?url=" .. vlc.access .. "://" .. vlc.path .. "&_status_code_map[302]=200&_status_format=json&client_id=" .. client_id)
+ local data = parse_json(response.location)
+ local playlist = {}
+ if not data.kind then
+ for _, track in ipairs(data) do
+ table.insert(playlist, create_track(track, client_id))
end
-
- if not arturl then
- arturl = string.match( line, "[\"']artwork_url[\"'] *: *[\"'](.-)[\"']" )
+ elseif data.kind == "track" then
+ table.insert(playlist, create_track(data, client_id))
+ elseif data.kind == "user" then
+ local tracks = parse_json(vlc.access .. "://api.soundcloud.com/users/" .. data.id .. "/tracks" .. "?client_id=" .. client_id)
+ for _, track in ipairs(tracks) do
+ table.insert(playlist, create_track(track, client_id))
end
- end
-
- if track then
- -- API magic
- local client_id = "fDoItMDbsbZz8dY16ZzARCZmzgHBPotA"
- -- app_version is not required by the API but we send it anyway
- -- to remain unconspicuous
- local app_version = "1480607078"
-
- 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 "" ) )
-
- if api then
- local streams = api:readline() -- data is on one line only
- -- For now only quality available is 128 kbps (http_mp3_128_url)
- path = string.match( streams, "[\"']http_mp3_%d+_url[\"'] *: *[\"'](.-)[\"']" )
- if path then
- -- FIXME: do this properly
- path = string.gsub( path, "\\u0026", "&" )
- end
+ elseif data.kind == "playlist" then
+ for _, track in ipairs(data.tracks) do
+ table.insert(playlist, create_track(track, client_id))
end
end
-
- if not path then
- vlc.msg.err( "Couldn't extract soundcloud audio URL, please check for updates to this script" )
- return { }
- end
-
- return { { path = path, name = name, description = description, artist = artist, arturl = arturl } }
+ return playlist
end
--
2.10.2
More information about the vlc-devel
mailing list