// ==UserScript==
// @name HTML5 thingie for Spotify Web Player
// @namespace https://greasyfork.org/users/4813-swyter
// @match https://play.spotify.com/*
// @version 2015.11.20
// @noframes
// @icon https://i.imgur.com/CecLLKu.png
// @grant none
// @run-at document-start
// @description asdf
// ==/UserScript==
/ * SWFobject.js faker, sneaky! * /
Object.defineProperty(window, 'swfobject',
{
configurable: false,
writable: false,
value:
{
getFlashPlayerVersion: function(){ console.log("-<-< getFlashPlayerVersion =>", arguments); return { major: 11, minor: 2, release: 202 }; },
hasFlashPlayerVersion: function(){ console.log("-<-< hasFlashPlayerVersion =>", arguments); return true; },
embedSWF: function(swf, parent_id, unk_a, unk_b, req_flash_ver, unk_c, properties)
{
console.log("-<-< embedSWF =>", arguments, arguments[9].toString(), this, properties);
function get_pong(ping)
{
// http://crossorigin.me/http://ping-pong.spotify.nodestuff.net/64-104-120-204-164-75-214-221-224-109-28-127-73-236-239-150-88-238-177-90
console.log("ping-pong", ping);
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://crossorigin.me/http://ping-pong.spotify.nodestuff.net/" + ping.replace(/ /g,"-"), true);
xhr.responseType = "json";
xhr.send();
// believe me, i know this sucks
while(xhr.readyState != xhr.DONE){}
console.log("pong", xhr);
return xhr.response.pong.replace(/-/g," ");
}
// http://dsu0uct5x2puz.cloudfront.net/mp3/f164a1770e3196f1ceac703389ea0bb828d26ed0?Expires=1450043810&Signature=-zgzKXjeioEVNAU~9UQJyjUl~rISxHryo06LF94Kg9JBZKc8hA3R2WnmHFCh58FbYNGBceQQdPIUZllHVQSnWmQmi3S2k5F11SvsuS1MmiYbg33TX2Ot26xIDgG6VfIQRe0coRnda99B8omcew55LElz1wp94Zaxg-DEat8Tk-k_&Key-Pair-Id=APKAIJ6GQLKYCDRS5HFA
// uri : "mp3:/mp3/6b381db769d31beb544ba67eb7cbc3ce4fc8ab4c.mp3?Expires=1450045402&Signature=dgvyYa~K2P-v6ArrdVBmRxAF44JTJhpk6PJqQXzHbMOmtcHw~eY~E1C0GgviL~O63-EhejMzCB~dLjlgaug-TQej8mCjvroY8crd776GRsBx0AJz4pnp3ZH03T3PnUecBHRwMrg28pjAbi1xWmuybyNvwWpitB9Q~hiCKxMzUhnXRjqpWJKZVrLDY7~iXB2GlptZNz8RZoapexeEkNA2kgjnYXk4JTe4CNTdRSmn~Uf9YHvxJdA4ttlRfDt353eSxCDTXKQdA7GkEBTKJfDvN6NgXyw8~Tm8tBHk9VYYn7jZMLYckwqi3OJAonof2SZZlHZoepgympEYxK8BdkvZMg__&Key-Pair-Id=APKAJXKSII4ED2EOGZZA"
// server: "http://dsu0uct5x2puz.cloudfront.net/cfx/st"
// protocol: "http"
var dummy = document.createElement("audio");
dummy.id = properties.id;
dummy.loop = false;
dummy.preload = 'auto';
dummy.volume = 1;
dummy.sp_run = function(proof){ console.log("-<-< sp_run =>", arguments); return get_pong(proof); };
dummy.sp_hasSound = function(){ return true };
dummy.sp_load = function(){ console.log("sp_load =>", arguments); }
dummy.__noSuchMethod__ = function(name,params) { console.log('==>>== > invalid function call', name, params); };
window.document[properties.id] = dummy;
parent_elem = document.getElementById(parent_id)
parent_elem.appendChild(dummy);
// tell the spotify framework that the swf embed is ready
arguments[9].apply(this, [{success: true}]);
// act as the swf bridge and tell it that the Flash-backend is ready
// JSInterface.notify(ApplicationEvents.READY,null,1);
Spotify.Instances.get(properties.instanceId).audioManager.getInterface()._triggerDeferred('FLASH_AVAILABLE', null);
Spotify.Instances.get(properties.instanceId).audioManager.getInterface()._triggerDeferred('READY', null);
console.log("AUDIOMANAGER-INTERFACE", properties.id, window.document[properties.id], Spotify.Instances.get(properties.instanceId).audioManager.getInterface(),
Spotify.Instances.get(properties.instanceId).audioManager.getInterface().hasSound())
}
}
});
function when_external_loaded()
{
// ---
window.swfobject = {};
/* wait until the page is ready for the code snippet to run */
document.addEventListener('DOMContentLoaded', function()
{
console.log("!!! DOMContentLoaded");
WebSocket.prototype.sond = WebSocket.prototype.send;
WebSocket.prototype.send = function(msg)
{
if (this.onmessage && this.sucks !== true)
{
callback = this.onmessage;
console.log("orig prev callback:", callback);
this.onmessage = function(message)
{
var json_msg = JSON.parse(message.data);
if (json_msg.id === window.last_track_msg)
console.info("<- ws recv: ", window.last_track_msg, message.data);
if (json_msg && json_msg.result && json_msg.result.uri)
open(json_msg.result.uri);
callback(message);
}
this.sucks = true;
}
var json_msg = JSON.parse(msg);
// get http link
if (json_msg && json_msg.name == 'sp/track_uri')
{
arguments[0] = msg.replace(',"rtmp"', '');
window.last_track_msg = json_msg.id;
console.info("-> ws send: ", json_msg.id, msg);
}
//dec_msg = json_msg.name === 'sp/hm_b64' ? atob(json_msg.args[0]) : null;
//console.info("-> ws send: ", msg); //json_msg, dec_msg);
//if (json_msg.name !== 'sp/log')
return WebSocket.prototype.sond.apply(this, arguments);
}
});
// ---
}
/* inject this cleaning function right in the page to avoid silly sandbox-related greasemonkey limitations */
window.document.head.appendChild(
inject_fn = document.createElement("script")
);
inject_fn.innerHTML = '(' + when_external_loaded.toString() + ')()';