2023-03-01 02:37:26 +00:00
|
|
|
import { maxVideoDuration } from "../../config.js";
|
2023-02-12 07:40:49 +00:00
|
|
|
|
|
|
|
let cachedID = {};
|
|
|
|
|
|
|
|
async function findClientID() {
|
|
|
|
try {
|
|
|
|
let sc = await fetch('https://soundcloud.com/').then((r) => { return r.text() }).catch(() => { return false });
|
|
|
|
let scVersion = String(sc.match(/<script>window\.__sc_version="[0-9]{10}"<\/script>/)[0].match(/[0-9]{10}/));
|
|
|
|
|
|
|
|
if (cachedID.version === scVersion) return cachedID.id;
|
|
|
|
|
|
|
|
let scripts = sc.matchAll(/<script.+src="(.+)">/g);
|
|
|
|
let clientid;
|
|
|
|
for (let script of scripts) {
|
|
|
|
let url = script[1];
|
|
|
|
|
|
|
|
if (url && !url.startsWith('https://a-v2.sndcdn.com')) return;
|
|
|
|
|
|
|
|
let scrf = await fetch(url).then((r) => {return r.text()}).catch(() => { return false });
|
|
|
|
let id = scrf.match(/\("client_id=[A-Za-z0-9]{32}"\)/);
|
|
|
|
|
|
|
|
if (id && typeof id[0] === 'string') {
|
|
|
|
clientid = id[0].match(/[A-Za-z0-9]{32}/)[0];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cachedID.version = scVersion;
|
|
|
|
cachedID.id = clientid;
|
|
|
|
|
|
|
|
return clientid;
|
|
|
|
} catch (e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default async function(obj) {
|
|
|
|
let html;
|
|
|
|
if (!obj.author && !obj.song && obj.shortLink) {
|
2023-08-15 09:37:59 +01:00
|
|
|
html = await fetch(`https://on.soundcloud.com/${obj.shortLink}/`).then((r) => {
|
|
|
|
return r.status === 404 ? false : r.text()
|
|
|
|
}).catch(() => { return false });
|
2023-02-12 07:40:49 +00:00
|
|
|
}
|
|
|
|
if (obj.author && obj.song) {
|
2023-08-15 09:37:59 +01:00
|
|
|
html = await fetch(
|
|
|
|
`https://soundcloud.com/${obj.author}/${obj.song}${obj.accessKey ? `/s-${obj.accessKey}` : ''}`
|
|
|
|
).then((r) => {
|
|
|
|
return r.text()
|
|
|
|
}).catch(() => { return false });
|
2023-02-12 07:40:49 +00:00
|
|
|
}
|
2023-04-24 20:01:25 +01:00
|
|
|
if (!html) return { error: 'ErrorCouldntFetch' };
|
2023-08-15 09:37:59 +01:00
|
|
|
if (!(html.includes('<script>window.__sc_hydration = ') && html.includes('{"hydratable":"sound","data":'))) {
|
2023-02-12 07:40:49 +00:00
|
|
|
return { error: ['ErrorBrokenLink', 'soundcloud'] }
|
|
|
|
}
|
|
|
|
|
2023-08-15 09:37:59 +01:00
|
|
|
let json = JSON.parse(html.split('{"hydratable":"sound","data":')[1].split('}];</script>')[0]);
|
2023-02-12 07:40:49 +00:00
|
|
|
if (!json["media"]["transcodings"]) return { error: 'ErrorEmptyDownload' };
|
|
|
|
|
|
|
|
let clientId = await findClientID();
|
|
|
|
if (!clientId) return { error: 'ErrorSoundCloudNoClientId' };
|
|
|
|
|
2023-08-15 09:37:59 +01:00
|
|
|
let fileUrlBase = json.media.transcodings.filter((v) => { if (v["format"]["mime_type"].startsWith("audio/ogg")) return true })[0]["url"],
|
2023-03-15 16:18:31 +00:00
|
|
|
fileUrl = `${fileUrlBase}${fileUrlBase.includes("?") ? "&" : "?"}client_id=${clientId}&track_authorization=${json.track_authorization}`;
|
2023-08-15 09:37:59 +01:00
|
|
|
|
2023-02-13 14:02:52 +00:00
|
|
|
if (fileUrl.substring(0, 54) !== "https://api-v2.soundcloud.com/media/soundcloud:tracks:") return { error: 'ErrorEmptyDownload' };
|
2023-02-12 07:40:49 +00:00
|
|
|
|
2023-03-01 02:37:26 +00:00
|
|
|
if (json.duration > maxVideoDuration) return { error: ['ErrorLengthAudioConvert', maxVideoDuration / 60000] };
|
2023-02-12 07:40:49 +00:00
|
|
|
|
|
|
|
let file = await fetch(fileUrl).then(async (r) => { return (await r.json()).url }).catch(() => { return false });
|
|
|
|
if (!file) return { error: 'ErrorCouldntFetch' };
|
|
|
|
|
|
|
|
return {
|
|
|
|
urls: file,
|
|
|
|
audioFilename: `soundcloud_${json.id}`,
|
|
|
|
fileMetadata: {
|
|
|
|
title: json.title,
|
|
|
|
artist: json.user.username,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|