Access soundcloud lib / audiomanager via JS on-page

I support the greasemonkey script, which monitors the playback of the current track, as well as progress in Soundcloud. Previously, I could just do require("lib/audiomanager") to access an object that allows me to view the state of the entire page, for example, track information.

The problem is that Soundcloud switched to using webpack for its client-side Javascript. This, as I understand it, saves all these classes as a specific number in the package. The number they store seems to change every time client JS is updated and recompiled.

The only way to access objects stored in webpack seems to be through the global webpackJsonp, as shown below. The package number just needs to be unique.

 webpackJsonp([6060], { 0: function (e, t, n) { window.aman = n(726); e.exports = function (abc) { console.log("Exports called"); }; } }); 

This code will execute and give me access to the object with this number in webpack. The object defined in the JS client web package:

 726: function (e, t, n) { (function (t) { function i(e) { var n = t(e.getContainerElement()), i = e.getState() === r.States.ERROR; n.toggleClass('blocked', i) } var r, s = n(53), o = n(14), a = 1000 / 60; e.exports = r = new s({ flashAudioPath: n(2181), flashObjectID: 'flashAudioObject', updateInterval: a, debug: !1 }), r.Errors = s.Errors, r.States = s.States, r.UPDATE_INTERVAL = a, o.once('audio:flash_block audio:flash_unblock', i) }) .call(t, n(1)) }, 

So, the solutions I can think of:

  • Find an object whose web package number does not change, which I can use to get the handle of this object
  • Iterate over each web package number and find an object that has the same set of methods as this one.

The latter seems messy, and the first seems impossible. Any ideas?

Things I tried:

  • Creating a new n (53), as well as the desired object, occurs, as it seems, for all updates. Gives me an audiomanager, but is definitely separated from the regular page audiomaster, so I don’t see what is playing.
+5
source share
2 answers

Afaik you can only access packages from another package. Soundcloud does not use ProvidePlugin, therefore, none of the libraries and modules are accessible from the global space.

Updated:

I know his ugly hack, but it works:

 webpackJsonp([6060], { 0: function (e, t, n) { var i = 0, found = false, lib; while (i < 2000 && !found) { try { lib = n(i); } catch (err) { lib = null; } if (lib && typeof lib._mute !== 'undefined') { found = true; console.log('found', lib, i); } console.log(i, lib); i++; } window.aman = lib; } }); 
+1
source

We also use the SoundCloud API in our client scenarios, so we got a bit β€œcleaner” code . Here is the main part (note that it does not contain try-catch blocks, because all modules exist):

 var playManager, libAudio, eventBus; webpackJsonp([], {0: function(a, b, require) { var modules = require.c; for (var moduleid in modules) { var el = require(moduleid); if (typeof el["playCurrent"] == "function") { playManager = el; } else if (typeof el["getSettings"] == "function") { libAudio = el; } else if (typeof el["trigger"] == "function" && typeof el["bind"] == "function" && typeof el["listenToOnce"] == "function" && typeof el["$"] != "function" && typeof el["broadcast"] == "function") { eventBus = el; } } 
+3
source

Source: https://habr.com/ru/post/1205566/


All Articles