Fix youtube download + add notifications + fix sending chat condition

This commit is contained in:
FullGreaM 2025-10-25 14:21:56 +03:00
parent 5b2911feaf
commit caf5643ac2
5 changed files with 109 additions and 44 deletions

BIN
.Dockerfile.kate-swp Normal file

Binary file not shown.

View File

@ -50,6 +50,19 @@ try {
const ytLinkRegexp = /^https:\/\/www\.youtube\.com/m; const ytLinkRegexp = /^https:\/\/www\.youtube\.com/m;
async function getFileSize(pathname) {
const stream = fs.createReadStream(pathname);
let size = 0;
return await new Promise((resolve, reject) => {
stream.on("data", data => size += data.length);
stream.on("end", () => resolve(size));
stream.on("error", reject);
});
}
// Check if download process
const tgChatsDownloaded = new Object();
class TgBotSender { class TgBotSender {
constructor(parent, bot, msg, memory = {}) { constructor(parent, bot, msg, memory = {}) {
this.parent = parent; this.parent = parent;
@ -90,15 +103,25 @@ class TgBotSender {
const filename = `${(new Date()).getTime()}.${quality.exc}`; const filename = `${(new Date()).getTime()}.${quality.exc}`;
const isStream = path.join(__dirname, `tmp/${filename}`); const isStream = path.join(__dirname, `tmp/${filename}`);
let uploadFileInterval = null;
const finallyHandler = (result) => { const finallyHandler = (result) => {
if (isStream) { clearInterval(uploadFileInterval);
//delete tgChatsDownloaded[msg.chat.id];
if (isStream && isStream !== true) {
fs.rm(isStream, { recursive: true, force: true }, () => {}); fs.rm(isStream, { recursive: true, force: true }, () => {});
if (result) if (result)
fs.rm(result, { recursive: true, force: true }, () => {}); fs.rm(result, { recursive: true, force: true }, () => {});
} }
}; };
video const errHandler = (err) => {
console.error(err.stack);
//this.bot.sendMessage(msg.chat.id, "Download failed");
sent.text("Download failed");
finallyHandler();
}
await video
.download(({ percent, downloaded, fine, msg }) => { .download(({ percent, downloaded, fine, msg }) => {
//console.debug({ percent, fine, downloaded, msg }); //console.debug({ percent, fine, downloaded, msg });
const now = new Date(); const now = new Date();
@ -111,41 +134,47 @@ class TgBotSender {
}, isStream) }, isStream)
.then(async (downloaded) => { .then(async (downloaded) => {
console.debug("downloaded:", downloaded); console.debug("downloaded:", downloaded);
if (downloaded.format.type === "video") { try {
await this.bot.sendChatAction(msg.chat.id, 'upload_document'); if (downloaded.format.type === "video") {
const uploadFileInterval = setInterval(() => { const filesize = typeof isStream !== "string" ? 0 : await getFileSize(downloaded.data);
this.bot.sendChatAction(msg.chat.id, 'upload_document'); //console.debug("filesize:", filesize);
}, 4250); if (filesize < 50 * 1024 * 1024) {
await new Promise(r => setTimeout(r, 3000)); await this.bot.sendChatAction(msg.chat.id, 'upload_document');
await this.bot.sendVideo( uploadFileInterval = setInterval(() => {
msg.chat.id, this.bot.sendChatAction(msg.chat.id, 'upload_document');
downloaded.data, }, 4250);
{ caption: info.title }, await new Promise(r => setTimeout(r, 3000));
{ await this.bot.sendVideo(
filename, msg.chat.id,
contentType: isStream === true ? "application/octet-stream" : downloaded.format.mime, downloaded.data,
//contentType: downloaded.format.mime, { caption: info.title },
}, {
); filename,
clearInterval(uploadFileInterval); contentType: isStream === true ? "application/octet-stream" : downloaded.format.mime,
} else if (downloaded.format.type === "audio") { //contentType: downloaded.format.mime,
await this.bot.sendAudio( },
msg.chat.id, );
downloaded.data, } else {
{ caption: info.title }, return await sent.text(`Maximum filesize reached. Try any types (Current file: ${
{ ((filesize / (1024 * 1024))+"").split(".")[0]
filename: `downloaded.${downloaded.format.exc}`, } MB)`);
contentType: downloaded.format.mime, }
}, } else if (downloaded.format.type === "audio") {
); await this.bot.sendAudio(
msg.chat.id,
downloaded.data,
{ caption: info.title },
{
filename: `downloaded.${downloaded.format.exc}`,
contentType: downloaded.format.mime,
},
);
}
} catch (err) {
return errHandler(err);
} }
finallyHandler(downloaded.data); finallyHandler(downloaded.data);
}) }).catch(errHandler);
.catch((err) => {
console.error(err.stack);
this.bot.sendMessage(msg.chat.id, "Download failed");
finallyHandler();
});
} }
} }
@ -202,7 +231,12 @@ class TgBot {
async cbHandler(query) { async cbHandler(query) {
const key = query.from.id + ":" + query.data; const key = query.from.id + ":" + query.data;
//console.debug(query, this.videosGC.actions[key], key); //console.debug(query, this.videosGC.actions[key], key);
this.videosGC.actions[key]?.(); if (!this.videosGC.actions[key])
return this.bot.answerCallbackQuery(query.id, {
text: "Resend me video link, please",
show_alert: true
});
this.videosGC.actions[key](query.id);
} }
async send(msg, txt) { async send(msg, txt) {
@ -270,12 +304,23 @@ class TgBot {
const qualityItem = qualities[quality]; const qualityItem = qualities[quality];
const actKey = const actKey =
msg.from.id + ":" + quality + "_" + msg.message_id; msg.from.id + ":" + quality + "_" + msg.message_id;
this.videosGC.register(actKey, () => { this.videosGC.register(actKey, async (queryId) => {
//console.debug("ACT btn:", actKey); //console.debug("ACT btn:", actKey);
if (tgChatsDownloaded[msg.from.id])
return this.bot.answerCallbackQuery(queryId, {
text: 'Wait until download was not finished',
show_alert: true
});
tgChatsDownloaded[msg.from.id] = true;
sent sent
.download(video, qualityItem) .download(video, qualityItem)
.then(() => {}) .then(() => {
.catch(errHandler); delete tgChatsDownloaded[msg.from.id];
})
.catch((err) => {
errHandler(err);
delete tgChatsDownloaded[msg.from.id];
});
}, video); }, video);
/*this.videosGC.actions[actKey] = () => { /*this.videosGC.actions[actKey] = () => {
sent sent

View File

@ -223,7 +223,8 @@ class DownloadVideo {
exc: f.ext, // <- расширение exc: f.ext, // <- расширение
resolution, resolution,
filesize: f.filesize || null, filesize: f.filesize || null,
mime: mimeType, type: !mimeType ? null : type mime: mimeType, type: !mimeType ? null : type,
forceAll: () => f
}; };
}); });
if (withDefaults) { if (withDefaults) {
@ -268,29 +269,48 @@ class DownloadVideo {
[this.quality.flag] : this.quality.flag; [this.quality.flag] : this.quality.flag;
const params = [ const params = [
"--cookies", "cookies.txt", "--cookies", "cookies.txt",
"--user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
//"--extractor-args", "youtube:player-client=default,mweb;po_token=mweb.gvs+XXX",
"--extractor-args", "youtube:player_client=default,mweb",
"-f", ...flags, "-f", ...flags,
"-o", !isPath ? "-" : isStream, this.url, "-o", !isPath ? "-" : isStream, this.url,
]; ];
d("yt-dlp " + params.join(" ")); d("yt-dlp " + params.join(" "));
const child = spawn("yt-dlp", params); //console.debug({ HOME: process.env.HOME });
const child = spawn("yt-dlp", params, {
env: {
...process.env,
//HOME: process.env.HOME,
LANG: "en_US.UTF-8",
},
stdio: ["pipe","pipe","pipe"],
//stdio: ["pipe","inherit","pipe"],
//stdio: ["inherit", "inherit", "inherit"],
});
let downloaded = 0; let downloaded = 0;
let percent = 0; let percent = 0;
let sizeTg = 0; let sizeTg = 0;
let fine = false; let fine = false;
const getDwnld = () => `Real size: ${downloaded}, total: ${sizeTg}`; const getDwnld = () => `Real size: ${downloaded}, total: ${sizeTg}`;
child.stderr.on("data", (data) => { const stderrHandler = (data) => {
const str = data.toString(); const str = data.toString();
//console.debug("DEBUG >>>>>>", str);
//console.debug(str); //console.debug(str);
const match = str.match(/(\d+\.\d+)%/); const match = str.match(/(\d+\.\d+)%/);
if (match && cb) { if (match && cb) {
percent = parseFloat(match[1]); percent = parseFloat(match[1]);
cb({ percent, downloaded: !isPath ? getDwnld() : "Processing", fine }); cb({ percent, downloaded: !isPath ? getDwnld() : "Processing", fine });
} }
}); };
child.stderr.on("data", stderrHandler);
if (isPath) { if (isPath) {
child.stdout.on("data", stderrHandler);
child.on("close", (code) => { child.on("close", (code) => {
//console.debug(">>>>>>>>>>>>>FINISHED");
signal.emit("finish"); signal.emit("finish");
fine = true; fine = true;
if (code !== 0) { if (code !== 0) {

BIN
src/tmp/1761390915442.mp4 Normal file

Binary file not shown.

Binary file not shown.