Stop Automatic Recommendations on Soundcloud

Stops the automatic playing of recommended tracks on Soundcloud.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name        Stop Automatic Recommendations on Soundcloud
// @namespace   soundcloud-no-autoplay
// @author      Veeno
// @contributor Kai Kuehner
// @contributor Technowise
// @contributor Andreas J. Schwarz
// @description Stops the automatic playing of recommended tracks on Soundcloud.
// @include     http://www.soundcloud.com/*
// @include     https://www.soundcloud.com/*
// @include     http://soundcloud.com/*
// @include     https://soundcloud.com/*
// @grant       none
// @version     2.1
// ==/UserScript==

(function(){
    var playingRecommended = false,

        trackInfoContainer = "div.playbackSoundBadge",
        trackArtistElementClass = "playbackSoundBadge__lightLink",
        trackArtistAttribute = "title",
        trackTitleElementClass = "playbackSoundBadge__titleLink",
        trackTitleAttribute = "title",

        recommendedContainer = "article.relatedSoundsModule",
        recommendedArtistElementClass = "soundTitle__usernameText",
        recommendedArtistAttribute = "innerHTML",
        recommendedTitleElementClass = "soundTitle__title",
        recommendedTitleAttribute = "title",

        buttonElement = "button.playControl";

    function isRecommendedTrack(){
        var trackArtist = trackInfoContainer.getElementsByClassName(trackArtistElementClass)[0],
            trackTitle = trackInfoContainer.getElementsByClassName(trackTitleElementClass)[0],
            recommendedArtist = recommendedContainer.getElementsByClassName(recommendedArtistElementClass)[0],
            recommendedTitle = recommendedContainer.getElementsByClassName(recommendedTitleElementClass)[0];
        
        if(trackArtist && trackTitle && recommendedArtist && recommendedTitle){
            return (
                trackArtist[trackArtistAttribute].trim().toLowerCase() === recommendedArtist[recommendedArtistAttribute].trim().toLowerCase() &&
                trackTitle[trackTitleAttribute].trim().toLowerCase() === recommendedTitle[recommendedTitleAttribute].trim().toLowerCase()
            );
        }
        
        return null;
    }

    var trackInfoObserver = new MutationObserver(function(){
        var currentIsRecommended = isRecommendedTrack();
        if(typeof currentIsRecommended === "boolean"){
            if(!playingRecommended && currentIsRecommended) buttonElement.click();
            playingRecommended = currentIsRecommended;
        }
    });

    function start(){
        var _trackInfoContainer = document.querySelector(trackInfoContainer),
            _recommendedContainer = document.querySelector(recommendedContainer),
            _buttonElement = document.querySelector(buttonElement);
        
        if(!_trackInfoContainer || !_recommendedContainer || !_buttonElement){
            setTimeout(start, 20);
            return;
        }
        
        trackInfoContainer = _trackInfoContainer;
        recommendedContainer = _recommendedContainer;
        buttonElement = _buttonElement;
        trackInfoObserver.observe(trackInfoContainer, {childList: true, subtree: true});
    }

    start();
})();