🏠 Home 

Greasy Fork is available in English.

Bandcamp download mp3s

Shows download links for the preview files on bandcamp albums


安装此脚本?
作者推荐脚本

您可能也喜欢Bandcamp script (Deluxe Edition)


安装此脚本
// ==UserScript==
// @name         Bandcamp download mp3s
// @description  Shows download links for the preview files on bandcamp albums
// @namespace    cuzi
// @oujs:author  cuzi
// @homepageURL  https://openuserjs.org/scripts/cuzi/Bandcamp_download_mp3s
// @version      9
// @license      GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt
// @match        https://*.bandcamp.com/*
// @grant        unsafeWindow
// @grant        GM.xmlHttpRequest
// @grant        GM_download
// @connect      bandcamp.com
// @connect      bcbits.com
// @icon         https://bandcamp.com/img/favicon/apple-touch-icon.png
// ==/UserScript==
/* globals GM, unsafeWindow, GM_download */
/* jshint asi: true, esversion: 8 */
(function () {
// Base64 function from https://gist.github.com/stubbetje/229984
function base64BinaryString (s) {
const base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split('')
const l = s.length
const o = []
let char0, char1, char2, char3
let byte0, byte1, byte2
let t
for (let i = 0; i < l; i++) {
byte0 = s.charCodeAt(i++) & 0xff
byte1 = i < l ? s.charCodeAt(i++) & 0xff : 0
byte2 = i < l ? s.charCodeAt(i) & 0xff : 0
char0 = byte0 >> 2
char1 = ((byte0 & 0x3) << 4) | (byte1 >> 4)
char2 = ((byte1 & 0x0f) << 2) | (byte2 >> 6)
char3 = byte2 & 0x3f
t = i - l
if (t === 1) {
char3 = 64
} else if (t === 2) {
char3 = 64
char2 = 64
}
o.push(base64[char0], base64[char1], base64[char2], base64[char3])
}
return o.join('')
}
function fixFilename (s) {
const forbidden = '*"/\\[]:|,<>?\n\t\0'.split('')
forbidden.forEach(function (char) {
s = s.replace(char, '')
})
return s
}
const SPINNERCSS = '/* http://www.designcouch.com/home/why/2013/05/23/dead-simple-pure-css-loading-spinner/ */\n' +
'.download-col .downloaddisk:hover {\n' +
'  text-decoration:none\n' +
'}\n' +
'.downspinner {\n' +
'  margin:0px auto;\n' +
'  position:relative;\n' +
'  display:inline-block;\n' +
'  animation: spinnerrotation 3s infinite linear;\n' +
'  cursor:wait;\n' +
'}\n' +
'@keyframes spinnerrotation {\n' +
'  from {transform: rotate(0deg)}\n' +
'  to {transform: rotate(359deg)}\n' +
'}'
function addSpinner (el) {
el.style = ''
el.classList.add('downspinner')
}
function removeSpinner (el) {
el.classList.remove('downspinner')
el.style = 'background:#1cea1c;border-radius:5px;padding:1px;opacity:0.5'
}
function download (ev) {
const a = this
const url = a.href
if (GM_download) {
// Use Tampermonkey GM_download function
ev.preventDefault()
addSpinner(a)
GM_download({
url,
name: a.download,
onerror: function () {
window.alert('Could not download via GM_download')
document.location.href = url
},
ontimeout: function () {
window.alert('Could not download via GM_download. Time out.')
document.location.href = url
},
onload: function () {
window.setTimeout(() => removeSpinner(a), 500)
}
})
return
}
if (!url.startsWith('http') || navigator.userAgent.indexOf('Chrome') !== -1) {
// Just open the link normally (no prevent default)
addSpinner(a)
window.setTimeout(() => removeSpinner(a), 1000)
return
}
// Use GM.xmlHttpRequest to download and offer data uri
ev.preventDefault()
addSpinner(a)
GM.xmlHttpRequest({
method: 'GET',
overrideMimeType: 'text/plain; charset=x-user-defined',
url,
onload: function (response) {
a.href = 'data:audio/mpeg;base64,' + base64BinaryString(response.responseText)
window.setTimeout(() => a.click(), 10)
},
onerror: function (response) {
window.alert('Could not download via GM.xmlHttpRequest')
document.location.href = url
}
})
}
const style = document.createElement('style')
style.appendChild(document.createTextNode(SPINNERCSS))
document.head.appendChild(style)
window.setTimeout(function () {
const TralbumData = unsafeWindow.TralbumData
if (TralbumData && TralbumData.hasAudio && !TralbumData.freeDownloadPage && TralbumData.trackinfo) {
let hoverdiv = document.querySelectorAll('.download-col div')
if (hoverdiv.length === 0) {
hoverdiv = document.querySelectorAll('h2.trackTitle')
}
for (let i = 0; i < TralbumData.trackinfo.length; i++) {
const t = TralbumData.trackinfo[i]
for (const prop in t.file) {
const mp3 = t.file[prop].replace(/^\/\//, 'http://')
const a = document.createElement('a')
a.className = 'downloaddisk'
a.href = mp3
a.download = (t.track_num > 9 ? '' : '0') + t.track_num + '. ' + fixFilename(TralbumData.artist + ' - ' + t.title) + '.mp3'
a.title = 'Download ' + prop
a.appendChild(document.createTextNode('\uD83D\uDCBE'))
a.addEventListener('click', download)
hoverdiv[i].appendChild(a)
break
}
}
}
}, 500)
})()