您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
*This version no longer works due to Soundcloud API changes - will update soon* - An ad-less, multilingual, clean Soundcloud downloader with robust code. Adds a 'Download' button in the toolbar of all single track views.
当前为
// ==UserScript== // @name Soundcloud Downloader Clean // @namespace https://openuserjs.org/users/webketje // @version 0.1.1 // @description *This version no longer works due to Soundcloud API changes - will update soon* - An ad-less, multilingual, clean Soundcloud downloader with robust code. Adds a 'Download' button in the toolbar of all single track views. // @author webketje // @license MIT // @icon https://a-v2.sndcdn.com/assets/images/sc-icons/favicon-2cadd14bdb.ico // @homepageURL https://gist.github.com/webketje/8cd2e6ae8a86dbe0533c5d2c612c42c6 // @supportURL https://gist.github.com/webketje/8cd2e6ae8a86dbe0533c5d2c612c42c6 // @noframes // @match https://soundcloud.com/* // @grant unsafeWindow // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/FileSaver.min.js // ==/UserScript== /* globals saveAs */ (function() { 'use strict'; var win = unsafeWindow || window; var containerSelector = '.listenEngagement__footer .sc-button-toolbar'; /** * @desc Log to console only if debug is true */ function log() { var stamp = new Date().toLocaleString(), args = [].slice.call(arguments), prefix = ['SCDLC', stamp, '-']; scdl.debug && console.log(prefix.concat(args).join(' ')); }; /** * @desc There is no other way to retrieve a Soundcloud client_id than by spying on existing requests. * We temporarily patch the XHR.send method to retrieve the url passed to it. * @param restoreIfTrue - restores the original prototype method when true is returned * @param onRestore - a function to exec when the restoreIfTrue condition is met */ function patchXHR(restoreIfTrue, onRestore) { var originalXHR = win.XMLHttpRequest.prototype.open; win.XMLHttpRequest.prototype.open = function() { originalXHR.apply(this, arguments); var restore = restoreIfTrue.apply(this, arguments); if (restore) { win.XMLHttpRequest.prototype.open = originalXHR; onRestore(restore); } }; }; var scdl = { debug: false, client_id: '', dlButtonId: 'scdlc-btn' }; scdl.getTrackName = function(trackJSON) { return [ trackJSON.user.username, trackJSON.title ].join(' - '); }; scdl.getStreamURL = function(url, onresolve, onerror) { var xhr = new XMLHttpRequest(); xhr.onload = function() { var trackJSON = JSON.parse(xhr.responseText); onresolve(trackJSON.errors || !trackJSON.stream_url ? false : { stream_url: trackJSON.stream_url + '?client_id=' + this.client_id, track_name: this.getTrackName(trackJSON) }); }.bind(this); xhr.onerror = function() { onerror(false); }; xhr.open('GET', 'https://api.soundcloud.com/resolve?url=' + encodeURIComponent(url) + '&client_id=' + this.client_id); xhr.send(); }; scdl.button = { label: { en: 'Download', es: 'Descargar', fr: 'Télécharger', nl: 'Download', de: 'Download', pl: 'Ściągnij', it: 'Scaricare', pt_BR: 'Baixar', sv: 'Ladda ner' }, download: function(e) { e.preventDefault(); saveAs(e.target.href, e.target.dataset.title); }, render: function(href, title, onClick) { var label = scdl.button.label[document.documentElement.lang]; var a = document.createElement('a'); a.className = "sc-button"; a.href = href; a.id = scdl.dlButtonId; a.textContent = label; a.dataset.title = title + '.mp3'; a.setAttribute('download', title + '.mp3'); a.target = '_blank'; a.onclick = onClick; a.style.marginLeft = '5px'; a.style.cssFloat = 'left'; return a; }, attach:function() { this.remove(); var f = document.querySelector(containerSelector); if (f) f.insertAdjacentElement('afterend', this.render.apply(this, arguments)); }, remove: function() { var btn = document.getElementById(scdl.dlButtonId); if (btn) btn.parentNode.removeChild(btn); } }; scdl.parseClientIdFromURL = function(url) { var search = /client_id=([\w\d]+)&*/; return url && url.match(search) && url.match(search)[1]; }; scdl.getClientID = function(onClientIDFound) { patchXHR(function(method, url) { return scdl.parseClientIdFromURL(url); }, onClientIDFound); }; scdl.load = function(url) { // for now only make available for single track pages if (/^(\/(you|stations|discover|stream|upload|search|settings))/.test(win.location.pathname)) { scdl.button.remove(); return; } scdl.getStreamURL(url, function onSuccess(result) { if (!result) { scdl.button.remove(); } else { log('Detected valid Soundcloud artist track URL. Requesting info...'); scdl.button.attach( result.stream_url, result.track_name, scdl.button.download ); } }, scdl.button.remove ); }; // patch front-end navigation ['pushState','replaceState','forward','back','go'].forEach(function(event) { var tmp = win.history.pushState; win.history[event] = function() { tmp.apply(win.history, arguments); scdl.load(win.location.href); } }); scdl.getClientID(function(id) { log('Found Soundcloud client id:', id, '. Initializing...'); scdl.client_id = id; scdl.load(win.location.href); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址