UNPKG

yt-dlx

Version:

Effortless Audio-Video Downloader And Streamer!

236 lines 10.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = __importStar(require("fs")); const colors_1 = __importDefault(require("colors")); const path = __importStar(require("path")); const web_1 = __importDefault(require("../../../web")); const zod_1 = require("zod"); const fluent_ffmpeg_1 = __importDefault(require("fluent-ffmpeg")); const yt_dlx_encore_1 = require("yt-dlx-encore"); const Agent_1 = __importDefault(require("../../../base/Agent")); const YouTubeId_1 = __importDefault(require("../../../web/YouTubeId")); const formatTime_1 = __importDefault(require("../../../base/formatTime")); const calculateETA_1 = __importDefault(require("../../../base/calculateETA")); var ZodSchema = zod_1.z.object({ output: zod_1.z.string().optional(), useTor: zod_1.z.boolean().optional(), verbose: zod_1.z.boolean().optional(), query: zod_1.z.array(zod_1.z.string().min(2)), resolution: zod_1.z.enum([ "144p", "240p", "360p", "480p", "720p", "1080p", "1440p", "2160p", "3072p", "4320p", "6480p", "8640p", "12000p", ]), filter: zod_1.z .enum([ "invert", "rotate90", "rotate270", "grayscale", "rotate180", "flipVertical", "flipHorizontal", ]) .optional(), }); /** * Downloads videos from YouTube based on a list of video URLs with the lowest available resolution. * * @param query - An array of YouTube video URLs to process. * @param resolution - The desired resolution of the downloaded videos. * @param verbose - (optional) Whether to log verbose output or not. * @param useTor - (optional) Whether to use Tor for the download or not. * @param output - (optional) The output directory for the processed files. * @param filter - (optional) The video filter to apply. Available options: "invert", "rotate90", "rotate270", "grayscale", "rotate180", "flipVertical", "flipHorizontal". * @returns A Promise that resolves when all videos have been processed. */ async function ListVideoCustom({ query, resolution, verbose, output, useTor, filter, }) { try { ZodSchema.parse({ query, resolution, verbose, output, useTor, filter, }); var startTime; var unique = new Set(); for (var purl of query) { try { var playlistId = await (0, YouTubeId_1.default)(purl); if (!playlistId) { console.log(colors_1.default.red("@error: "), "@error: invalid playlist", purl); continue; } else { var punique = await web_1.default.playlistVideos({ playlistId, }); if (punique === undefined) { console.log(colors_1.default.red("@error:"), "unable to get response for", purl); continue; } for (var video of punique.result) unique.add(video); } } catch (error) { console.log(colors_1.default.red("@error:"), error.message); continue; } } console.log(colors_1.default.blue("@info:"), "total number of uncommon videos:", colors_1.default.blue(unique.size.toString())); for (const video of unique) { try { var engineData = await (0, Agent_1.default)({ query: video.videoLink, verbose, useTor, }); if (engineData === undefined) { console.log(colors_1.default.red("@error:"), "unable to get response!"); continue; } var title = engineData.metaData.title.replace(/[^a-zA-Z0-9_]+/g, "_"); var folder = output ? path.join(__dirname, output) : __dirname; if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true }); var filename = `yt-dlx_(VideoCustom_${resolution}_`; var ff = (0, fluent_ffmpeg_1.default)() .setFfmpegPath((await (0, yt_dlx_encore_1.encore)().then(fp => fp.ffmpeg)).toString()) .setFfprobePath((await (0, yt_dlx_encore_1.encore)().then(fp => fp.ffprobe)).toString()); var vdata = engineData.ManifestHigh.find(i => i.format.includes(resolution.replace("p", "").toString())); ff.addInput(engineData.AudioHighF.url); if (vdata) ff.addInput(vdata.url.toString()); else throw new Error(colors_1.default.red("@error: ") + "no video data found. use list_formats() maybe?"); ff.videoCodec("copy"); ff.withOutputFormat("matroska"); ff.addOption("-headers", "X-Forwarded-For: " + engineData.ipAddress); switch (filter) { case "grayscale": ff.withVideoFilter("colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3"); filename += `grayscale)_${title}.mkv`; break; case "invert": ff.withVideoFilter("negate"); filename += `invert)_${title}.mkv`; break; case "rotate90": ff.withVideoFilter("rotate=PI/2"); filename += `rotate90)_${title}.mkv`; break; case "rotate180": ff.withVideoFilter("rotate=PI"); filename += `rotate180)_${title}.mkv`; break; case "rotate270": ff.withVideoFilter("rotate=3*PI/2"); filename += `rotate270)_${title}.mkv`; break; case "flipHorizontal": ff.withVideoFilter("hflip"); filename += `flipHorizontal)_${title}.mkv`; break; case "flipVertical": ff.withVideoFilter("vflip"); filename += `flipVertical)_${title}.mkv`; break; default: filename += `)_${title}.mkv`; break; } ff.on("error", error => { throw new Error(error.message); }); ff.on("start", comd => { startTime = new Date(); if (verbose) console.info(colors_1.default.green("@comd:"), comd); }); ff.on("end", () => process.stdout.write("\n")); ff.on("progress", ({ percent, timemark }) => { var color = colors_1.default.green; if (isNaN(percent)) percent = 0; if (percent > 98) percent = 100; if (percent < 25) color = colors_1.default.red; else if (percent < 50) color = colors_1.default.yellow; var width = Math.floor(process.stdout.columns / 4); var scomp = Math.round((width * percent) / 100); var progb = color("━").repeat(scomp) + color(" ").repeat(width - scomp); process.stdout.write(`\r${color("@prog:")} ${progb}` + ` ${color("| @percent:")} ${percent.toFixed(2)}%` + ` ${color("| @timemark:")} ${timemark}` + ` ${color("| @eta:")} ${(0, formatTime_1.default)((0, calculateETA_1.default)(startTime, percent))}`); }); await new Promise((resolve, _reject) => { ff.output(path.join(folder, filename.replace("_)_", ")_"))); ff.on("end", () => resolve()); ff.on("error", error => { throw new Error(colors_1.default.red("@error: ") + error.message); }); ff.run(); }); } catch (error) { console.log(colors_1.default.red("@error:"), error); continue; } } } catch (error) { switch (true) { case error instanceof zod_1.ZodError: throw new Error(colors_1.default.red("@zod-error:") + error.errors); default: throw new Error(colors_1.default.red("@error:") + error.message); } } finally { console.log(colors_1.default.green("@info:"), "❣️ Thank you for using yt-dlx. Consider 🌟starring the GitHub repo https://github.com/yt-dlx."); } } exports.default = ListVideoCustom; //# sourceMappingURL=ListVideoCustom.js.map