Stop Automatic Recommendations on Soundcloud

Stops the automatic playing of recommended tracks on Soundcloud.

  1. // ==UserScript==
  2. // @name Stop Automatic Recommendations on Soundcloud
  3. // @namespace soundcloud-no-autoplay
  4. // @author Veeno
  5. // @contributor Kai Kuehner
  6. // @contributor Technowise
  7. // @contributor Andreas J. Schwarz
  8. // @description Stops the automatic playing of recommended tracks on Soundcloud.
  9. // @include http://www.soundcloud.com/*
  10. // @include https://www.soundcloud.com/*
  11. // @include http://soundcloud.com/*
  12. // @include https://soundcloud.com/*
  13. // @grant none
  14. // @version 2.1
  15. // ==/UserScript==
  16.  
  17. (function(){
  18. var playingRecommended = false,
  19.  
  20. trackInfoContainer = "div.playbackSoundBadge",
  21. trackArtistElementClass = "playbackSoundBadge__lightLink",
  22. trackArtistAttribute = "title",
  23. trackTitleElementClass = "playbackSoundBadge__titleLink",
  24. trackTitleAttribute = "title",
  25.  
  26. recommendedContainer = "article.relatedSoundsModule",
  27. recommendedArtistElementClass = "soundTitle__usernameText",
  28. recommendedArtistAttribute = "innerHTML",
  29. recommendedTitleElementClass = "soundTitle__title",
  30. recommendedTitleAttribute = "title",
  31.  
  32. buttonElement = "button.playControl";
  33.  
  34. function isRecommendedTrack(){
  35. var trackArtist = trackInfoContainer.getElementsByClassName(trackArtistElementClass)[0],
  36. trackTitle = trackInfoContainer.getElementsByClassName(trackTitleElementClass)[0],
  37. recommendedArtist = recommendedContainer.getElementsByClassName(recommendedArtistElementClass)[0],
  38. recommendedTitle = recommendedContainer.getElementsByClassName(recommendedTitleElementClass)[0];
  39. if(trackArtist && trackTitle && recommendedArtist && recommendedTitle){
  40. return (
  41. trackArtist[trackArtistAttribute].trim().toLowerCase() === recommendedArtist[recommendedArtistAttribute].trim().toLowerCase() &&
  42. trackTitle[trackTitleAttribute].trim().toLowerCase() === recommendedTitle[recommendedTitleAttribute].trim().toLowerCase()
  43. );
  44. }
  45. return null;
  46. }
  47.  
  48. var trackInfoObserver = new MutationObserver(function(){
  49. var currentIsRecommended = isRecommendedTrack();
  50. if(typeof currentIsRecommended === "boolean"){
  51. if(!playingRecommended && currentIsRecommended) buttonElement.click();
  52. playingRecommended = currentIsRecommended;
  53. }
  54. });
  55.  
  56. function start(){
  57. var _trackInfoContainer = document.querySelector(trackInfoContainer),
  58. _recommendedContainer = document.querySelector(recommendedContainer),
  59. _buttonElement = document.querySelector(buttonElement);
  60. if(!_trackInfoContainer || !_recommendedContainer || !_buttonElement){
  61. setTimeout(start, 20);
  62. return;
  63. }
  64. trackInfoContainer = _trackInfoContainer;
  65. recommendedContainer = _recommendedContainer;
  66. buttonElement = _buttonElement;
  67. trackInfoObserver.observe(trackInfoContainer, {childList: true, subtree: true});
  68. }
  69.  
  70. start();
  71. })();