Skip to content

Instantly share code, notes, and snippets.

@simonwep
Last active August 10, 2024 14:30
Show Gist options
  • Save simonwep/24f8cdcd6d32d86e929004013bd660ae to your computer and use it in GitHub Desktop.
Save simonwep/24f8cdcd6d32d86e929004013bd660ae to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Spotify ad skipper
// @version 1.0
// @namespace http://tampermonkey.net/
// @description Detects and skips ads on spotify
// @match https://*.spotify.com/*
// @grant none
// @run-at document-start
// @downloadURL https://gist.githubusercontent.com/Simonwep/24f8cdcd6d32d86e929004013bd660ae/raw
// @updateURL https://gist.githubusercontent.com/Simonwep/24f8cdcd6d32d86e929004013bd660ae/raw
// ==/UserScript==
!async function () {
async function queryAsync(query) {
return new Promise(resolve => {
const interval = setInterval(() => {
const element = document.querySelector(query);
if (element) {
clearInterval(interval);
return resolve(element);
}
}, 250);
});
}
/**
* Inject a middleware function in a object or instance
* @param ctx Object or instance
* @param fn Function name
* @param middleware Middleware function
* @param transform Transform function result
*/
function inject({ctx, fn, middleware, transform}) {
const original = ctx[fn];
ctx[fn] = function () {
if (!middleware || middleware.call(this, ...arguments) !== false) {
const result = original.call(this, ...arguments);
return transform ? transform.call(this, result, ...arguments) : result;
}
};
}
const nowPlayingBar = await queryAsync('.now-playing-bar');
const playButton = await queryAsync('button[title=Play], button[title=Pause]');
let audio;
inject({
ctx: document,
fn: 'createElement',
transform(result, type) {
if (type === 'audio') {
audio = result;
}
return result;
}
});
let playInterval;
new MutationObserver(() => {
const link = document.querySelector('.now-playing > a');
if (link) {
if (!audio) {
return console.error('Audio-element not found!');
}
if (!playButton) {
return console.error('Play-button not found!');
}
// console.log('Ad found', audio, playButton, nowPlayingBar);
audio.src = '';
playButton.click();
if (!playInterval) {
playInterval = setInterval(() => {
if (!document.querySelector('.now-playing > a') && playButton.title === 'Pause') {
clearInterval(playInterval);
playInterval = null;
} else {
playButton.click();
}
}, 500);
}
}
}).observe(nowPlayingBar, {
characterData: true,
childList: true,
attributes: true,
subtree: true
});
// Hide upgrade-button and captcha-errors, we don't what to see that.
const style = document.createElement('style');
style.innerHTML = `
[aria-label="Upgrade to Premium"],
body > div:not(#main) {
display: none !important;
}
`;
document.body.appendChild(style);
}();
@Weridox
Copy link

Weridox commented May 9, 2020

@marcbelmont
Thank you for your work. I use updated script. Works fine for me.

@doconghaph
Copy link

tysm !!

@sinhpn92
Copy link

How to use this script? I did run in the console, but it isn't still working.

@MohamedElashri
Copy link

How to use this script? I did run in the console, but it isn't still working.

You should use something like violentmonkey to install this script.

@mindplay-dk
Copy link

This handy inject function, is that part of a library somewhere?

@Ju2t-us
Copy link

Ju2t-us commented Oct 10, 2022

Works perfectly! I don't have much BAT but here's a tip @simonwep

@prawndumplings
Copy link

prawndumplings commented Jun 10, 2023

Great work, thankyou.

@codenyte
Copy link

Why don't you publish this on Greasy Fork?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment