UNPKG

ytmusic_api_unofficial

Version:

A simple API to get music from YouTube Music

149 lines 5.93 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSignatureTimestamp = getSignatureTimestamp; exports.getDecodeScript = getDecodeScript; exports.getUrlDecode = getUrlDecode; exports.decode = decode; const error_1 = require("./error"); let decodeFile = ''; function getSignatureTimestamp() { return new Promise((resolve) => { fetchScript("SignatureTimestamp").then((res) => { resolve(eval(res)); }); }); } function getDecodeScript(force = false) { return new Promise((resolve) => { fetchScript(['ExtractDecipher', 'NTransform'], force).then((res) => { resolve(res); }); }); } function getUrlDecode(url, retry = false) { return new Promise((resolve, reject) => { getDecodeScript(retry).then((_a) => __awaiter(this, [_a], void 0, function* ([decipherScript, nTransformScript]) { checkUrlIsMusic((yield decode(url, decipherScript, nTransformScript)).url).then(resolve).catch((e) => { if (!retry) return resolve(getUrlDecode(url, true)); reject(e); }); })); }); } function checkUrlIsMusic(url) { return new Promise((resolve, reject) => { fetch(url).then((res) => __awaiter(this, void 0, void 0, function* () { if ((res.headers.get('content-type') || '').match(/audio|video/gm)) return resolve(url); else { if (res.status === 403) return reject((0, error_1.error)(2005, { url, error: 'The download link returned is not valid, please retry or report the error' })); resolve(checkUrlIsMusic(yield res.text())); } })).catch((e) => { reject((0, error_1.error)(2005, { url, error: e.message })); }); }); } function fetchScript(nameFunc = "ExtractDecipher", force = false) { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { let file = null; if (process.env.buildDevDecoderFile) { process.emitWarning('You are using a development build, the decoder will be use as local. If you want to use the internet decoder, please use a production build.'); file = process.env.buildDevDecoderFile.toString(); } if (!force && decodeFile !== '') file = decodeFile; if (!file) { yield fetch('https://raw.githubusercontent.com/Alexis06030631/yt_music_api/docs/decoder.js').then(res => { return res.text(); }).then(res => { file = res; decodeFile = res; }); } if (!file) return reject((0, error_1.error)(5000, { code: 1005, message: 'The decoder file is not available' })); let scriptsS = null; if (typeof nameFunc === 'string') { scriptsS = file.match(new RegExp(`//${nameFunc}\n((?:.|\n)*?)(?:\n\n|$)`))[1]; } if (Array.isArray(nameFunc)) { scriptsS = nameFunc.map((name) => { return file.match(new RegExp(`//${name}\n((?:.|\n)*?)(?:\n\n|$)`))[1]; }); } return resolve(scriptsS); })); } function runScript(script, ...args) { try { args.forEach((arg) => { script = script.replace(new RegExp(`${arg.name}`, 'g'), `"${arg.value.replace('"', '\\"')}"`); }); return eval(script); } catch (e) { return args[0].value; } } function exportArgsUrl(url) { const return_object = {}; const args = url.match(/(.*?)=(.*?)(?:&|$)/g); if (args) { args.forEach((arg) => { const [name, value] = arg.split('='); return_object[name] = value.replace(/&$/, ''); }); } return return_object; } function decode(format, decipherScript, nTransformScript) { try { if (!decipherScript) return; const decipher = (url) => { const args = exportArgsUrl(url); if (!args.s) return args.url; const components = new URL(decodeURIComponent(args.url)); components.searchParams.set(args.sp || "sig", runScript(decipherScript, { name: 'sig', value: decodeURIComponent(args.s) })); return components.toString(); }; const nTransform = (url) => { const components = new URL(decodeURIComponent(url)); const n = components.searchParams.get("n"); if (!n || !nTransformScript) return url; components.searchParams.set("n", runScript(nTransformScript, { name: 'ncode', value: n })); return components.toString(); }; const cipher = !format.url; const url = format.url || format.signatureCipher || format.cipher; format.url = nTransform(cipher ? decipher(url) : url); delete format.signatureCipher; delete format.cipher; return format; } catch (e) { console.error(e); return format; } } //# sourceMappingURL=decode.js.map