[vlc-commits] soundcloud.lua: dynamically extract API magic
Pierre Ynard
git at videolan.org
Wed Apr 1 09:54:27 CEST 2020
vlc | branch: master | Pierre Ynard <linkfanel at yahoo.fr> | Wed Apr 1 09:26:49 2020 +0200| [6abb32a9ba076de8662a53889926280e6d80f5e1] | committer: Pierre Ynard
soundcloud.lua: dynamically extract API magic
It seems that the client_id API magic now gets invalidated much faster,
rendering the current model, where it is hard-coded into the script,
not viable anymore. Instead, this fetches and parses javascript assets
linked from the web page to search and extract the up-to-date magic from
them.
This is significantly slower as for now it fetches all of several
indiscriminate javascript assets, but at least it works, and should not
require that kind of maintenance anymore.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6abb32a9ba076de8662a53889926280e6d80f5e1
---
share/lua/playlist/soundcloud.lua | 48 ++++++++++++++++++++++++++++++++++-----
1 file changed, 42 insertions(+), 6 deletions(-)
diff --git a/share/lua/playlist/soundcloud.lua b/share/lua/playlist/soundcloud.lua
index caa417ade2..3860837fcf 100644
--- a/share/lua/playlist/soundcloud.lua
+++ b/share/lua/playlist/soundcloud.lua
@@ -1,7 +1,7 @@
--[[
$Id$
- Copyright © 2012, 2015, 2019 the VideoLAN team
+ Copyright © 2012, 2015, 2019-2020 the VideoLAN team
Authors: Cheng Sun <chengsun9atgmail.com>
Pierre Ynard
@@ -38,10 +38,33 @@ function fix_quotes( value )
return string.gsub( value, "\\\"", "\"" )
end
+-- Search and extract API magic parameter from web asset
+function extract_magic( url )
+ local s = vlc.stream( url )
+ if not s then
+ return nil
+ end
+
+ while true do
+ local line = s:readline()
+ if not line then break end
+
+ -- The API magic appears under a similar form several times
+ -- in one of the javascript assets
+ -- {client_id:"z21TN9SfM0GjGteSzk4ViM1KEwMRNWZF"}
+ local client_id = string.match( line, '[{,]client_id:"(%w+)"[},]' )
+ if client_id then
+ vlc.msg.dbg( "Found soundcloud API magic" )
+ return client_id
+ end
+ end
+ return nil
+end
+
-- Parse function.
function parse()
while true do
- line = vlc.readline()
+ local line = vlc.readline()
if not line then break end
-- API endpoint for audio stream URL
@@ -52,6 +75,19 @@ function parse()
stream = string.match( line, '"url":"([^"]-/stream/progressive[^"]-)"' )
end
+ -- API magic parameter
+ if not client_id then
+ local script = string.match( line, '<script( .-)>' )
+ if script then
+ local src = string.match( script, ' src="(.-)"' )
+ if src then
+ -- Assume absolute path
+ -- https://a-v2.sndcdn.com/assets/48-551fb851-3.js
+ client_id = extract_magic( src )
+ end
+ end
+ end
+
-- Metadata
if not name then
name = string.match( line, "[\"']title[\"'] *: *\"(.-[^\\])\"" )
@@ -80,10 +116,10 @@ function parse()
end
if stream then
- -- API magic
- local client_id = "uzhloVwKlWX9bzQ5F1mrqQdjYxKEqDRM"
-
- local api = vlc.stream( stream..( string.match( stream, "?" ) and "&" or "?" ).."client_id="..client_id )
+ if client_id then
+ stream = stream..( string.match( stream, "?" ) and "&" or "?" ).."client_id="..client_id
+ end
+ local api = vlc.stream( stream )
if api then
local streams = api:readline() -- data is on one line only
More information about the vlc-commits
mailing list