您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a shuffle play button to "Likes" and playlists
// ==UserScript== // @name soundcloud shuffle likes // @version 1.7 // @description Adds a shuffle play button to "Likes" and playlists // @author bhackel // @match https://soundcloud.com/* // @grant none // @run-at document-end // @license MIT // @noframes // @namespace https://gf.qytechs.cn/en/users/324178-bhackel // ==/UserScript== (function() { 'use strict'; /* Injects Button into the page once it has loaded, then tries to re-add it if it disappears due to page change */ function insertButtonLoop() { let url = window.location.href; url = url.split('?')[0]; let btnShuffle = document.querySelector('.bhackel-shuffle-likes'); // Check if button does not exist already, and that user is on likes or a playlist if (!btnShuffle && (url.includes("/likes") || url.includes("/sets/") || url.includes("/discover/"))) { btnShuffle = document.createElement('Button'); btnShuffle.innerHTML = 'Shuffle Play'; btnShuffle.onclick = function(){ setupLoad(this); }; btnShuffle.scrolling = false; btnShuffle.interval = 0; // Case for likes if (url.includes("you/likes")) { btnShuffle.className = 'bhackel-shuffle-likes sc-button sc-button-large'; btnShuffle.pageType = "Likes"; // Check if top bar has loaded let collectionTop = document.querySelector('.collectionSection__top'); if (collectionTop) { // Insert the button above the grid of tracks collectionTop.insertBefore(btnShuffle, collectionTop.children[2]); } else { setTimeout(insertButtonLoop, 1000); } } // Case for generic user likes else if (url.includes("/likes") && !url.includes("you/likes")) { btnShuffle.className = 'bhackel-shuffle-likes sc-button sc-button-medium'; btnShuffle.pageType = "GenericLikes"; // Check if top bar has loaded let titleBar = document.querySelector(".userNetworkTabs"); if (titleBar) { // Insert the button above the list of tracks titleBar.appendChild(btnShuffle); } else { setTimeout(insertButtonLoop, 1000); } } // Case for a playlist else if (url.includes("/sets/") && !url.includes("/discover/")) { btnShuffle.className = 'bhackel-shuffle-likes sc-button sc-button-medium'; btnShuffle.pageType = "Playlist"; // Check if action bar has loaded let soundActions = document.querySelector('.soundActions'); if (soundActions) { // Insert the button after other action buttons soundActions.children[0].appendChild(btnShuffle); } else { setTimeout(insertButtonLoop, 1000); } } // Case for discover playlists else if (url.includes("/discover/sets/")) { btnShuffle.className = 'bhackel-shuffle-likes sc-button sc-button-medium'; btnShuffle.pageType = "Discover"; // Check if action bar has loaded let playlistControls = document.querySelector('.systemPlaylistDetails__controls'); if (playlistControls) { // Insert the button after other action buttons playlistControls.appendChild(btnShuffle); } else { setTimeout(insertButtonLoop, 1000); } } } // Perform another check in 3 seconds, in the case button has been removed setTimeout(insertButtonLoop, 3000); } /* Changes the text of the button, resets the queue to have the user's likes, then starts the scrolling loop. Or it stops the loop from running. */ function setupLoad(btn) { // Check whether the loop is running or not if (btn.scrolling === false) { btn.innerHTML = 'Click to Stop Loading'; btn.scrolling = true; // The list of tracks visible on screen, which changes for a playlist or likes let tracks; if (btn.pageType === "Likes") { tracks = document.querySelector('.lazyLoadingList__list'); } else if (btn.pageType === "GenericLikes") { tracks = document.querySelector('.lazyLoadingList__list'); } else if (btn.pageType === "Playlist") { tracks = document.querySelector('.trackList__list'); } else if (btn.pageType === "Discover") { tracks = document.querySelector('.systemPlaylistTrackList__list'); } if (tracks.childElementCount > 2) { // Reset the queue to the beginning of the list of tracks let firstTrack = tracks.children[0]; let secondTrack = tracks.children[1]; let firstPlayButton = firstTrack.querySelector(".playButton"); let secondPlayButton = secondTrack.querySelector(".playButton"); // Reset by playing 2, playing 1, then pausing playback secondPlayButton.click(); setTimeout(function(){ firstPlayButton.click(); }, 150); setTimeout(function(){ let playButton = document.querySelector('.playControl'); if (playButton.classList.contains('playing')) { playButton.click(); } }, 500); // Add the first track to the queue so it gets shuffled tracks.getElementsByClassName("sc-button-more")[0].click() document.getElementsByClassName("moreActions__button addToNextUp")[0].click() // Open the queue to load it toggleQueue('open'); // Setup the scrolling loop - Needs time before running so the queue loads btn.timeout = setTimeout(function(){ btn.interval = setInterval(function() { scrollQueue(btn); }, 500); }, 3000); } else { // The list has two or less tracks - cannot shuffle play btn.innerHTML = 'Error: Too Few Tracks'; } } else { clearInterval(btn.interval); clearTimeout(btn.timeout); btn.interval = 0; btn.scrolling = false; btn.innerHTML = 'Shuffle Play'; } } /* Scrolls the queue down, ensuring that the queue is open by opening it */ function scrollQueue(btn) { let queue = document.querySelector('.queue'); // Check if the queue is open if (queue.classList.contains('m-visible')) { // Scroll the queue to the bottom, loading new tracks below let scrollableQueue = document.querySelector('.queue__scrollableInner'); let queueContainer = document.querySelector('.queue__itemsHeight'); let scrollToHeight = parseInt(queueContainer.style.height); scrollableQueue.scroll(0,scrollToHeight); // Check if all tracks are loaded, then play let autoplayDiv = document.querySelector('.queue__fallback'); if (autoplayDiv) { clearInterval(btn.interval); btn.scrolling = false; btn.interval = 0; play(btn); } } else { // Open the queue if it is closed toggleQueue('open'); } } /* Shuffles the queue, skips the first track, then plays it */ function play(btn) { btn.innerHTML = 'Shuffle Play'; let playButton = document.querySelector('.playControl'); let shuffleButton = document.querySelector('.shuffleControl'); let skipButton = document.querySelector(".skipControl__next"); // Re-Shuffle tracks if shuffle is enabled, and enable shuffle if it is disabled if (shuffleButton.classList.contains('m-shuffling')) { shuffleButton.click(); shuffleButton.click(); } else if (!shuffleButton.classList.contains('m-shuffling')) { shuffleButton.click(); } // Skip the duplicate first track that was added previously // This also begins playback skipButton.click(); // Close the queue if it is open toggleQueue('close'); // Add focus back to the play/pause button so keybinds work playButton.focus() } /* Opens or closes the song queue */ function toggleQueue(changeToState) { let queue = document.querySelector('.queue'); let isQueueOpen = queue.classList.contains('m-visible'); // Toggle queue if the queue is open and it should be closed, or if it's closed and should be open if ((isQueueOpen && changeToState === 'close') || (!isQueueOpen && changeToState === 'open')) { let queueTrigger = document.querySelector('.playbackSoundBadge__queueCircle'); queueTrigger.click(); } } insertButtonLoop(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址