# Add handlers application.add_handler(CommandHandler("start", start)) application.add_handler(CommandHandler("help", help_command)) application.add_handler(CommandHandler("cancel", cancel)) application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_url)) application.add_handler(CallbackQueryHandler(button_callback)) application.add_error_handler(error_handler)
# Update message to show downloading await query.edit_message_text(f"📥 *Downloading {action}...*\n\nPlease wait, this may take a moment.", parse_mode='Markdown') youtube downloader telegram bot
try: if action == "audio": # Download audio with yt_dlp.YoutubeDL(YDL_OPTS_AUDIO) as ydl: info = ydl.extract_info(url, download=True) filename = ydl.prepare_filename(info).replace('.webm', '.mp3').replace('.m4a', '.mp3') # Send audio file with open(filename, 'rb') as audio_file: await context.bot.send_audio( chat_id=query.message.chat_id, audio=audio_file, title=info.get('title', 'Audio'), performer=info.get('uploader', 'YouTube'), duration=info.get('duration', 0) ) # Cleanup os.remove(filename) elif action == "video": # Download video with yt_dlp.YoutubeDL(YDL_OPTS_VIDEO) as ydl: info = ydl.extract_info(url, download=True) filename = ydl.prepare_filename(info) # Send video file (Telegram limit: 50MB) file_size = os.path.getsize(filename) / (1024 * 1024) if file_size > 50: await query.edit_message_text( f"❌ Video file is too large ({file_size:.1f}MB). Telegram limit is 50MB.\n" f"Try downloading audio instead." ) else: with open(filename, 'rb') as video_file: await context.bot.send_video( chat_id=query.message.chat_id, video=video_file, caption=f"📹 {info.get('title', 'Video')}", supports_streaming=True ) # Cleanup os.remove(filename) # Send success message await context.bot.send_message( chat_id=query.message.chat_id, text="✅ *Download complete!*\n\nSend another YouTube URL to continue.", parse_mode='Markdown' ) # Clear user data del user_data[user_id] except Exception as e: logger.error(f"Download error: {e}") await query.edit_message_text(f"❌ Download failed: {str(e)[:200]}") if user_id in user_data: del user_data[user_id] async def error_handler(update: Update, context: ContextTypes.DEFAULT_TYPE): logger.error(f"Update {update} caused error {context.error}") # Add handlers application
try: # Extract video info with yt_dlp.YoutubeDL(YDL_OPTS_INFO) as ydl: info = ydl.extract_info(url, download=False) title = info.get('title', 'Unknown Title') duration = info.get('duration', 0) # Format duration minutes, seconds = divmod(duration, 60) duration_str = f"{minutes}:{seconds:02d}" # Create keyboard for format selection keyboard = [ [ InlineKeyboardButton("🎥 Video (720p)", callback_data="video"), InlineKeyboardButton("🎵 Audio (MP3)", callback_data="audio") ], [InlineKeyboardButton("❌ Cancel", callback_data="cancel")] ] reply_markup = InlineKeyboardMarkup(keyboard) # Update message with video info info_text = ( f"✅ *Video found!*\n\n" f"📹 *Title:* {title}\n" f"⏱️ *Duration:* {duration_str}\n\n" f"Choose download format:" ) await status_msg.edit_text(info_text, parse_mode='Markdown', reply_markup=reply_markup) user_data[user_id]['title'] = title except Exception as e: logger.error(f"Error extracting info: {e}") await status_msg.edit_text("❌ Failed to analyze video. Please check the URL and try again.") async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): query = update.callback_query await query.answer() this may take a moment."
# Send info message status_msg = await update.message.reply_text("🔍 *Analyzing video...*", parse_mode='Markdown')