-
-
Save kajju027/168c1db126f207d9015d50b3e996724c to your computer and use it in GitHub Desktop.
Download Everything, YT-DLP and CURL - DownLoadAll.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * dla.js - Advanced Media Downloader for LevanterBot | |
| * Copyright (C) 2025 Weskerty | |
| * Updated & Stylized for Peak Performance | |
| */ | |
| const fs = require('fs').promises; | |
| const path = require('path'); | |
| const os = require('os'); | |
| const { promisify } = require('util'); | |
| const { execFile } = require('child_process'); | |
| const { bot, isUrl } = require('../lib'); | |
| const execFileAsync = promisify(execFile); | |
| // --- Configuration & Constants --- | |
| const FILE_TYPES = { | |
| video: { extensions: new Set(['mp4', 'mkv', 'avi', 'webm', 'mov', 'flv', 'm4v']), mimetype: 'video/mp4' }, | |
| image: { extensions: new Set(['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'tiff', 'svg']), mimetype: 'image/jpeg' }, | |
| audio: { extensions: new Set(['mp3', 'wav', 'ogg', 'flac', 'm4a', 'aac', 'wma']), mimetype: 'audio/mpeg' }, | |
| document: { | |
| extensions: new Set(['pdf', 'epub', 'docx', 'txt', 'apk', 'apks', 'zip', 'rar', 'iso', 'ini', 'cbr', 'cbz', 'torrent', 'json', 'xml', 'html', 'css', 'js', 'csv', 'xls', 'xlsx', 'ppt', 'pptx']), | |
| mimetypes: new Map([ | |
| ['pdf', 'application/pdf'], ['apk', 'application/vnd.android.package-archive'], | |
| ['zip', 'application/zip'], ['rar', 'application/x-rar-compressed'] | |
| ]), | |
| defaultMimetype: 'application/octet-stream', | |
| } | |
| }; | |
| const TIMEOUT_MS = 300000; | |
| // --- Helper Functions --- | |
| const withTimeout = (promise, ms = TIMEOUT_MS, errorMsg = 'Operation timeout') => | |
| Promise.race([promise, new Promise((_, reject) => setTimeout(() => reject(new Error(errorMsg)), ms))]); | |
| function getFileDetails(filePath) { | |
| const ext = path.extname(filePath).slice(1).toLowerCase(); | |
| for (const [category, typeInfo] of Object.entries(FILE_TYPES)) { | |
| if (typeInfo.extensions.has(ext)) { | |
| return { category, mimetype: category === 'document' ? typeInfo.mimetypes.get(ext) || typeInfo.defaultMimetype : typeInfo.mimetype }; | |
| } | |
| } | |
| return { category: 'document', mimetype: FILE_TYPES.document.defaultMimetype }; | |
| } | |
| // --- Task Queue Manager --- | |
| class DownloadQueue { | |
| constructor(maxConcurrent = 2) { | |
| this.queue = []; | |
| this.activeDownloads = 0; | |
| this.maxConcurrent = maxConcurrent; | |
| this.isProcessing = false; | |
| } | |
| async add(task) { | |
| return new Promise((resolve, reject) => { | |
| this.queue.push({ task, resolve, reject }); | |
| this.processNext(); | |
| }); | |
| } | |
| async processNext() { | |
| if (this.isProcessing) return; | |
| this.isProcessing = true; | |
| try { | |
| while (this.activeDownloads < this.maxConcurrent && this.queue.length > 0) { | |
| const { task, resolve, reject } = this.queue.shift(); | |
| this.activeDownloads++; | |
| task().then(resolve).catch(reject).finally(() => { | |
| this.activeDownloads--; | |
| setImmediate(() => this.processNext()); | |
| }); | |
| } | |
| } finally { this.isProcessing = false; } | |
| } | |
| } | |
| // --- Core Downloader Class --- | |
| class MediaDownloader { | |
| constructor() { | |
| this.ctx = null; | |
| this.ytDlpBinaryPath = null; | |
| this.ytDlpBinaries = new Map([ | |
| ['win32-x64', 'yt-dlp.exe'], ['linux-x64', 'yt-dlp_linux'], | |
| ['linux-arm64', 'yt-dlp_linux_aarch64'], ['default', 'yt-dlp'] | |
| ]); | |
| this.defaultFormats = { | |
| video: ['-f', 'bestvideo[height<=720][vcodec*=h264]+bestaudio[acodec*=aac]/best[height<=720]', '--sponsorblock-remove', 'all'], | |
| audio: ['-f', 'ba/best', '-x', '--audio-format', 'mp3', '--audio-quality', '0'] | |
| }; | |
| } | |
| setContext(ctx) { | |
| this.config = { | |
| tempDir: path.join(process.cwd(), 'tmp'), | |
| maxFileSize: (parseInt(ctx.MAX_UPLOAD) * 1048576) || 1500000000, | |
| ytDlpPath: path.join(process.cwd(), 'media', 'bin'), | |
| maxConcurrent: parseInt(ctx.MAXSOLICITUD) || 2, | |
| playlistLimit: parseInt(ctx.PLAYLIST_LIMIT) || 20, | |
| cookies: ctx.COOKIES || null, | |
| }; | |
| this.downloadQueue = new DownloadQueue(this.config.maxConcurrent); | |
| } | |
| async ensureDirectories() { | |
| await fs.mkdir(this.config.tempDir, { recursive: true }); | |
| await fs.mkdir(this.config.ytDlpPath, { recursive: true }); | |
| } | |
| async detectYtDlpBinary() { | |
| if (this.ytDlpBinaryPath) return this.ytDlpBinaryPath; | |
| const platformKey = `${os.platform()}-${os.arch()}`; | |
| const fileName = this.ytDlpBinaries.get(platformKey) || this.ytDlpBinaries.get('default'); | |
| const filePath = path.join(this.config.ytDlpPath, fileName); | |
| try { | |
| await fs.access(filePath); | |
| this.ytDlpBinaryPath = filePath; | |
| } catch { this.ytDlpBinaryPath = 'yt-dlp'; } | |
| return this.ytDlpBinaryPath; | |
| } | |
| async processDownloadedFile(message, filePath, quoted, caption = null) { | |
| const { mimetype, category } = getFileDetails(filePath); | |
| const fileBuffer = await fs.readFile(filePath); | |
| await message.send(fileBuffer, { fileName: path.basename(filePath), mimetype, caption, quoted }, category); | |
| await fs.unlink(filePath).catch(() => {}); | |
| } | |
| async downloadWithYtDlp(message, urls, type = 'video') { | |
| return this.downloadQueue.add(async () => { | |
| const ytPath = await this.detectYtDlpBinary(); | |
| const outputDir = path.join(this.config.tempDir, `dl_${Date.now()}`); | |
| await fs.mkdir(outputDir, { recursive: true }); | |
| try { | |
| for (const url of urls) { | |
| const args = [ | |
| '--max-filesize', this.config.maxFileSize.toString(), | |
| ...this.defaultFormats[type], | |
| '-o', path.join(outputDir, '%(title).70s.%(ext)s'), | |
| url | |
| ]; | |
| await execFileAsync(ytPath, args, { timeout: TIMEOUT_MS }); | |
| } | |
| const files = await fs.readdir(outputDir); | |
| for (const file of files) { | |
| await this.processDownloadedFile(message, path.join(outputDir, file), message.quoted); | |
| } | |
| } catch (err) { | |
| throw new Error(`Download Failed: ${err.message}`); | |
| } finally { | |
| await fs.rm(outputDir, { recursive: true, force: true }).catch(() => {}); | |
| } | |
| }); | |
| } | |
| async searchAndDownload(message, query, isVideo = false) { | |
| const searchUrl = `ytsearch1:${query}`; | |
| return this.downloadWithYtDlp(message, [searchUrl], isVideo ? 'video' : 'audio'); | |
| } | |
| } | |
| const mediaDownloader = new MediaDownloader(); | |
| bot( | |
| { | |
| pattern: 'dla ?(.*)', | |
| fromMe: true, | |
| desc: 'Advanced Universal Media Downloader', | |
| type: 'download', | |
| }, | |
| async (message, match, ctx) => { | |
| mediaDownloader.setContext(ctx); | |
| const input = match.trim() || message.reply_message?.text || ''; | |
| if (!input) { | |
| const helpMenu = ` | |
| ✨ *ᴀʟʟ-ɪɴ-ᴏɴᴇ ᴅᴏᴡɴʟᴏᴀᴅᴇʀ* ✨ | |
| ━━━━━━━━━━━━━━━━━━━━ | |
| 📊 *Usage Guide:* | |
| • *Audio Search:* \`dla <song name>\` | |
| • *Video Search:* \`dla vd <video name>\` | |
| • *Direct URL:* \`dla <link>\` | |
| • *MP3 Playlist:* \`dla mp3 <playlist link>\` | |
| 🛠 *System:* yt-dlp Core | |
| 🚀 *Powered By:* Sayan OAI | |
| ━━━━━━━━━━━━━━━━━━━━`; | |
| return await message.send(helpMenu.trim()); | |
| } | |
| const urls = (input.match(/(https?:\/\/[^\s]+)/g) || []).filter(url => isUrl(url)); | |
| if (urls.length > 0) { | |
| const isMp3 = input.toLowerCase().includes('mp3'); | |
| await message.send(`_📥 Processing your request..._`); | |
| return await mediaDownloader.downloadWithYtDlp(message, urls, isMp3 ? 'audio' : 'video'); | |
| } | |
| if (input.startsWith('vd ')) { | |
| await message.send(`_🎬 Searching for video..._`); | |
| return await mediaDownloader.searchAndDownload(message, input.replace('vd ', ''), true); | |
| } else { | |
| await message.send(`_🎵 Searching for audio..._`); | |
| return await mediaDownloader.searchAndDownload(message, input, false); | |
| } | |
| } | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment