[repo] desacoplamento e maior coesão
This commit is contained in:
synt-xerror
2026-03-13 11:30:34 -03:00
parent a48b747b8e
commit b2fecab660
19 changed files with 439 additions and 393 deletions

24
src/download/audio.js Normal file
View File

@@ -0,0 +1,24 @@
import { get_video } from "./video.js";
import { spawn } from "child_process";
import os from "os";
const so = os.platform();
export async function get_audio(url, id) {
const video = await get_video(url, id);
const output = `downloads/${id}.mp3`;
const cmd = so === "win32" ? ".\\bin\\ffmpeg.exe" : "./bin/ffmpeg";
const args = ['-i', video, '-vn', '-acodec', 'libmp3lame', '-q:a', '2', output];
await runCmd(cmd, args);
return output;
}
async function runCmd(cmd, args) {
return new Promise((resolve, reject) => {
const proc = spawn(cmd, args);
proc.stdout.on("data", data => console.log("[cmd]", data.toString()));
proc.stderr.on("data", data => console.error("[cmd ERR]", data.toString()));
proc.on("close", code => code === 0 ? resolve() : reject(new Error("Processo saiu com código "+code)));
});
}

42
src/download/queue.js Normal file
View File

@@ -0,0 +1,42 @@
import { get_video } from "./video.js";
import { get_audio } from "./audio.js";
import pkg from "whatsapp-web.js";
const { MessageMedia } = pkg;
import fs from "fs";
import { botMsg } from "../utils/botMsg.js";
import { emptyFolder } from "../utils/file.js";
import client from "../client/whatsappClient.js";
let downloadQueue = [];
let processingQueue = false;
export function enqueueDownload(type, url, msg, chatId) {
downloadQueue.push({ type, url, msg, chatId });
if (!processingQueue) processQueue();
}
async function processQueue() {
processingQueue = true;
while (downloadQueue.length) {
const job = downloadQueue.shift();
try {
let path;
if (job.type === "video") path = await get_video(job.url, job.msg.id._serialized);
else path = await get_audio(job.url, job.msg.id._serialized);
const file = fs.readFileSync(path);
const media = new MessageMedia(
job.type === "video" ? "video/mp4" : "audio/mpeg",
file.toString("base64"),
path.split("/").pop()
);
await client.sendMessage(job.chatId, media);
fs.unlinkSync(path);
emptyFolder("downloads");
} catch (err) {
await client.sendMessage(job.chatId, botMsg(`❌ Erro ao baixar ${job.type}\n\`${err.message}\``));
}
}
processingQueue = false;
}

36
src/download/video.js Normal file
View File

@@ -0,0 +1,36 @@
import { spawn } from "child_process";
import os from "os";
const so = os.platform();
export async function get_video(url, id) {
const cmd = so === "win32" ? ".\\bin\\yt-dlp.exe" : "./bin/yt-dlp";
const args = [
'--extractor-args', 'youtube:player_client=android',
'-f', 'bv+ba/best',
'--print', 'after_move:filepath',
'--output', `downloads/${id}.%(ext)s`,
'--cookies', 'cookies.txt',
'--add-header', 'User-Agent:Mozilla/5.0',
'--add-header', 'Referer:https://www.youtube.com/',
'--retries', '4',
'--fragment-retries', '5',
'--socket-timeout', '15',
'--sleep-interval', '1', '--max-sleep-interval', '4',
'--allow-unplayable-formats',
url
];
return await runCmd(cmd, args);
}
async function runCmd(cmd, args) {
return new Promise((resolve, reject) => {
const proc = spawn(cmd, args);
let stdout = "";
proc.stdout.on("data", data => stdout += data.toString());
proc.stderr.on("data", data => console.error("[cmd ERR]", data.toString()));
proc.on("close", code => code === 0 ? resolve(stdout.trim()) : reject(new Error("Processo saiu com código "+code)));
});
}