Skip to content

Instantly share code, notes, and snippets.

@deluvas
Last active January 1, 2018 00:31
Show Gist options
  • Save deluvas/998b96d84664ab7a850ae143f08da37d to your computer and use it in GitHub Desktop.
Save deluvas/998b96d84664ab7a850ae143f08da37d to your computer and use it in GitHub Desktop.
Making the world a better place by disabling SoundCloud autoplay
// ==UserScript==
// @name mysoundcloud
// @namespace https://github.com/deluvas
// @version 0.1.2
// @description A collection of tweaks to improve the SoundCloud user experience
// @author deluvas
// @match *://soundcloud.com/*
// @grant none
// @run-at document-start
// ==/UserScript==
// TODO: do not allow last item in playlist to continue
(function () {
/**
* CUSTOMIZE THE SCRIPT BY MODIFYING THESE SETTINGS
*/
let settings = {
disable_autoplay: true
}
function disableAutoplay() {
let progressBar = document.querySelector( "div.playbackTimeline__progressWrapper" );
let pauseControl = document.querySelector( "button.playControls__play" );
let repeatControl = document.querySelector( "button.repeatControl" );
let prevControl = document.querySelector( "button.playControls__prev" );
let nextControl = document.querySelector( "button.playControls__next" );
if ( progressBar == null || pauseControl == null ) {
console.warn( "Progress bar and/or controls not found" )
return;
}
isInPlaylist = () => {
let songBadge = document.querySelector( "div.playControls__soundBadge a.playbackSoundBadge__avatar");
if ( songBadge == null ) {
debug.warn( "Couldn't figure out if song is in playlist or not!" );
return false;
}
let href = songBadge.getAttribute( "href" );
if ( href.match( /\?in=(.+)\/sets\// ) ) {
return true;
}
return false;
}
getRepeatMode = () => {
let classes = repeatControl.className;
if ( classes.indexOf( "m-none" ) >= 0 ) {
return 0;
} else if ( classes.indexOf( "m-all" ) >= 0 ) {
return 2;
} else {
return 1; // repeat once
}
}
resetSongSeek = () => {
nextControl.click();
prevControl.click();
}
// The progress bar contains 2 attributes which show the songs maximum time
// and current time in seconds. the current time is updated every 1s so one can
// check when the song is near its end
let observer = new MutationObserver( ( mutations ) => {
for ( let mutation of mutations ) {
if ( mutation.type === "attributes" && mutation.attributeName == "aria-valuenow" ) {
let currentValue = parseFloat( progressBar.getAttribute( "aria-valuenow" ) );
let maxValue = parseFloat( progressBar.getAttribute( "aria-valuemax" ) );
if ( currentValue >= maxValue - 1.250 ) { // end - 1.250s (progress is updated every 1s)
if ( isInPlaylist() ) {
console.debug( "Allowing autoplay since song is in playlist" )
}
else {
resetSongSeek();
if ( getRepeatMode() === 0 ) {
pauseControl.click();
console.debug( "Stopping autoplay. Pausing song." );
} else {
console.debug( "Repeating song" );
}
break;
}
}
break;
}
}
} );
observer.observe( progressBar, { attributes: true } );
}
if ( settings.disable_autoplay ) {
setTimeout( disableAutoplay, 750 );
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment