Sandbird

Untitled

May 14th, 2025
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.02 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Spotify Downloader - Download Spotify songs, playlists, and albums
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.7
  5. // @description Downloads Spotify songs, playlists, and albums as MP3. Can also download full playlist or album as ZIP.
  6. // @author Zertalious (Zert)
  7. // @match *://open.spotify.com/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=spotify.com
  9. // @grant none
  10. // @downloadURL https://update.greasyfork.org/scripts/446143/Spotify%20Downloader%20-%20Download%20Spotify%20songs%2C%20playlists%2C%20and%20albums.user.js
  11. // @updateURL https://update.greasyfork.org/scripts/446143/Spotify%20Downloader%20-%20Download%20Spotify%20songs%2C%20playlists%2C%20and%20albums.meta.js
  12. // ==/UserScript==
  13.  
  14. const style = document.createElement( 'style' );
  15.  
  16. style.innerText = `
  17.  
  18. [role='grid'] {
  19. margin-left: 50px;
  20. }
  21.  
  22. [data-testid='tracklist-row'] {
  23. position: relative;
  24. }
  25.  
  26. [role="presentation"] > * {
  27. contain: unset;
  28. }
  29.  
  30. .btn {
  31. width: 40px;
  32. height: 40px;
  33. border-radius: 50%;
  34. border: 0;
  35. background-color: #1fdf64;
  36. background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M17 12v5H3v-5H1v5a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5z"/><path d="M10 15l5-6h-4V1H9v8H5l5 6z"/></svg>');
  37. background-position: center;
  38. background-repeat: no-repeat;
  39. cursor: pointer;
  40. }
  41.  
  42. .btn:hover {
  43. transform: scale(1.1);
  44. }
  45.  
  46. [data-testid='tracklist-row'] .btn {
  47. position: absolute;
  48. top: 50%;
  49. right: 100%;
  50. margin-top: -20px;
  51. margin-right: 10px;
  52. }
  53.  
  54. `;
  55.  
  56. document.body.appendChild( style );
  57.  
  58. function sleep( ms ) {
  59.  
  60. return new Promise( resolve => setTimeout( resolve, 0 ) );
  61.  
  62. }
  63.  
  64. function animate() {
  65.  
  66. const tracks = document.querySelectorAll( '[data-testid="tracklist-row"]' );
  67.  
  68. for ( let i = 0; i < tracks.length; i ++ ) {
  69.  
  70. const track = tracks[ i ];
  71.  
  72. if ( ! track.hasButton ) {
  73.  
  74. addButton( track ).onclick = async function () {
  75.  
  76. const btn = track.querySelector( '[data-testid="more-button"]' );
  77. btn.click();
  78.  
  79. await sleep( 1 );
  80.  
  81. const highlight = document.querySelector( '#context-menu a[href*="highlight"]' ).href.match( /highlight=(.+)/ )[ 1 ];
  82.  
  83. document.dispatchEvent( new MouseEvent( 'mousedown' ) );
  84.  
  85. const url = 'https://open.' + highlight.replace( ':', '.com/' ).replace( ':', '/' );
  86.  
  87. download( url );
  88.  
  89. }
  90.  
  91. }
  92.  
  93. }
  94.  
  95. const actionBarRow = document.querySelector( '[data-testid="action-bar-row"]:last-of-type' );
  96.  
  97. if ( actionBarRow && ! actionBarRow.hasButton ) {
  98.  
  99. addButton( actionBarRow ).onclick = function () {
  100.  
  101. download( window.location.href );
  102.  
  103. }
  104.  
  105. }
  106.  
  107. }
  108.  
  109. function download( link ) {
  110.  
  111. window.open( 'https://spotdownloader.com/?link=' + link, '_blank' );
  112.  
  113. }
  114.  
  115. function addButton( el ) {
  116.  
  117. const button = document.createElement( 'button' );
  118.  
  119. button.className = 'btn';
  120.  
  121. el.appendChild( button );
  122.  
  123. el.hasButton = true;
  124.  
  125. return button;
  126.  
  127. }
  128.  
  129. setInterval( animate, 1000 );
Advertisement
Add Comment
Please, Sign In to add comment