hutatools / lib /qqm.js
fullpwerr's picture
p
3ed6900
const { exec } = require("child_process");
const path = require("path");
const fs = require("fs");
const axios = require("axios");
const COOKIES_PATH = path.join(__dirname, "./cookies/qq.txt");
const ytdlp = path.join(__dirname, "./yt-dlp")
async function getRedirectedURL(url) {
try {
const response = await axios.get(url, {
maxRedirects: 0,
validateStatus: (status) => status >= 300 && status < 400,
});
return response.headers.location || null;
} catch (error) {
console.error("Error mendapatkan URL redirect:", error.message);
return null;
}
}
function convertToSongDetailURL(url) {
try {
const urlObj = new URL(url);
const songmid = urlObj.searchParams.get("songmid");
if (songmid) {
return `https://y.qq.com/n/ryqq/songDetail/${songmid}`;
}
} catch (error) {
console.error("Error parsing URL:", error.message);
}
return null;
}
async function processQQMusicURL(url) {
try {
if (url.includes("y.qq.com/n/ryqq/songDetail/")) {
return url;
} else if (url.includes("c6.y.qq.com/base/fcgi-bin/u?")) {
const redirectedURL = await getRedirectedURL(url);
if (redirectedURL) {
return convertToSongDetailURL(redirectedURL);
}
} else if (url.includes("i.y.qq.com/v8/playsong.html")) {
return convertToSongDetailURL(url);
}
} catch (error) {
console.error("Error processing URL:", error.message);
}
return null;
}
async function getInfo(url) {
return new Promise(async(resolve, reject) => {
const thumbnail = await getQQMusicCover(url);
exec(`${ytdlp} -j --cookies ${COOKIES_PATH} "${await processQQMusicURL(url)}"`, (error, stdout, stderr) => {
if (error) {
return reject(`Error: ${stderr || error.message}`);
}
try {
const info = JSON.parse(stdout);
resolve({
status: 200,
title: info.title,
artist: info.creators[0],
duration: info.duration,
thumbnail,
music: info.formats.map(f => ({
format_id: f.format_id,
ext: f.ext,
filesize: f.size,
url: f.url
}))
});
} catch (e) {
reject({ status: 500, message: e.message});
}
});
});
}
async function getQQMusicCover(songURL) {
try {
const response = await axios.get(await getRedirectedURL(songURL));
const html = response.data;
const match = html.match(/window\.__ssrFirstPageData__\s*=\s*(\{.*?\})<\/script>/s);
if (match) {
const jsonData = JSON.parse(match[1]);
const coverURL = jsonData?.metaData?.image;
return coverURL;
} else {
throw new Error("Data JSON tidak ditemukan dalam HTML.");
}
} catch (error) {
console.error("Error mendapatkan cover:", error.message);
return null;
}
}
module.exports = getInfo