yt-dlx
Version:
Effortless Audio-Video Downloader And Streamer!
173 lines • 7.79 kB
JavaScript
;
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 zod_1 = require("zod");
const fluent_ffmpeg_1 = __importDefault(require("fluent-ffmpeg"));
const Agent_1 = __importDefault(require("../../base/Agent"));
const events_1 = require("events");
const locator_1 = require("../../base/locator");
var ZodSchema = zod_1.z.object({
query: zod_1.z.string().min(2),
output: zod_1.z.string().optional(),
useTor: zod_1.z.boolean().optional(),
stream: zod_1.z.boolean().optional(),
verbose: zod_1.z.boolean().optional(),
metadata: zod_1.z.boolean().optional(),
filter: zod_1.z
.enum([
"invert",
"rotate90",
"rotate270",
"grayscale",
"rotate180",
"flipVertical",
"flipHorizontal",
])
.optional(),
});
/**
* Downloads audio and video from a YouTube video URL with the highest available resolution.
*
* @param query - The YouTube video URL or ID or name.
* @param stream - (optional) Whether to stream the output or not.
* @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 file.
* @param metadata - (optional) If true, the function returns the extracted metadata and filename without processing the audio. This can be useful for debugging or obtaining metadata without downloading the audio.
* @param filter - (optional) The video filter to apply. Available options: "invert", "rotate90", "rotate270", "grayscale", "rotate180", "flipVertical", "flipHorizontal".
*
* @returns An EventEmitter instance to handle events.
*/
function AudioVideoHighest({ query, stream, verbose, metadata, output, useTor, filter, }) {
var emitter = new events_1.EventEmitter();
(async () => {
try {
ZodSchema.parse({
query,
stream,
verbose,
metadata,
output,
useTor,
filter,
});
var engineData = await (0, Agent_1.default)({
query,
verbose,
useTor,
});
if (!engineData) {
throw new Error(`${colors_1.default.red("@error:")} unable to get response!`);
}
var title = engineData.metaData.title.replace(/[^a-zA-Z0-9_]+/g, "_");
var folder = output ? output : __dirname;
if (!fs.existsSync(folder))
fs.mkdirSync(folder, { recursive: true });
var ff = (0, fluent_ffmpeg_1.default)()
.setFfmpegPath((await (0, locator_1.locator)().then(fp => fp.ffmpeg)).toString())
.setFfprobePath((await (0, locator_1.locator)().then(fp => fp.ffprobe)).toString())
.addInput(engineData.AudioHighF.url)
.addInput(engineData.ManifestHigh[engineData.ManifestHigh.length - 1].url)
.withOutputFormat("matroska")
.outputOptions("-c copy")
.addOption("-headers", `X-Forwarded-For: ${engineData.ipAddress}`);
var filenameBase = `yt-dlx_(AudioVideoHighest_`;
let filename = `${filenameBase}${filter ? filter + ")_" : ")_"}${title}.mkv`;
var filterMap = {
grayscale: ["colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3"],
invert: ["negate"],
rotate90: ["rotate=PI/2"],
rotate180: ["rotate=PI"],
rotate270: ["rotate=3*PI/2"],
flipHorizontal: ["hflip"],
flipVertical: ["vflip"],
};
if (filter && filterMap[filter])
ff.withVideoFilter(filterMap[filter]);
ff.addOption("-headers", `X-Forwarded-For: ${engineData.ipAddress}`);
ff.on("start", comd => {
if (verbose)
emitter.emit("log", colors_1.default.green("@comd:"), comd);
emitter.emit("start", comd);
})
.on("progress", progress => emitter.emit("progress", progress))
.on("error", error => emitter.emit("error", error.message))
.on("end", () => emitter.emit("end", filename));
switch (true) {
case stream:
emitter.emit("ready", {
ffmpeg: ff,
filename: path.join(folder, filename),
});
break;
case metadata:
emitter.emit("metadata", {
filename,
metaData: engineData.metaData,
ipAddress: engineData.ipAddress,
AudioLowF: engineData.AudioLowF,
AudioHighF: engineData.AudioHighF,
AudioLowDRC: engineData.AudioLowDRC,
AudioHighDRC: engineData.AudioHighDRC,
VideoLowF: engineData.VideoLowF,
VideoHighF: engineData.VideoHighF,
VideoLowHDR: engineData.VideoLowHDR,
VideoHighHDR: engineData.VideoHighHDR,
ManifestLow: engineData.ManifestLow,
ManifestHigh: engineData.ManifestHigh,
});
break;
default:
ff.output(path.join(folder, filename))
.on("end", () => emitter.emit("end", filename))
.on("error", error => emitter.emit("error", error.message))
.run();
break;
}
}
catch (error) {
switch (true) {
case error instanceof zod_1.ZodError:
emitter.emit("error", colors_1.default.red("@zod-error:"), error.errors);
break;
default:
emitter.emit("error", colors_1.default.red("@error:"), error.message);
break;
}
}
finally {
emitter.emit("info", colors_1.default.green("@info:"), "❣️ Thank you for using yt-dlx. Consider 🌟starring the GitHub repo https://github.com/yt-dlx.");
}
})();
return emitter;
}
exports.default = AudioVideoHighest;
//# sourceMappingURL=AudioVideoHighest.js.map