#!/usr/bin/env python3 """ YouTube Video Downloader Backend Works with the provided HTML frontend """ from flask import Flask, request, jsonify, send_file, render_template from flask_cors import CORS import requests import os import json import uuid import logging from urllib.parse import quote, urlencode from werkzeug.utils import secure_filename # Configuration app = Flask(__name__) CORS(app) # Enable CORS for frontend # API Configuration API_URL = "https://don.aalyan.za.com/api.php" API_KEY = "demo_key_123" # Setup logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Create downloads directory DOWNLOAD_DIR = "downloads" os.makedirs(DOWNLOAD_DIR, exist_ok=True) def get_video_info_from_api(youtube_url): """Fetch video information from API""" try: params = { 'endpoint': 'video-info', 'api_key': API_KEY, 'url': youtube_url } logger.info(f"Fetching video info for: {youtube_url}") response = requests.get(API_URL, params=params, timeout=30) if response.status_code == 200: data = response.json() logger.info(f"API Response: {json.dumps(data, indent=2)[:500]}") return data else: logger.error(f"API Error: {response.status_code}") return None except Exception as e: logger.error(f"Error fetching video info: {str(e)}") return None def download_video_from_api(youtube_url, quality, format_type='mp4'): """Download video using API""" try: params = { 'endpoint': 'download', 'api_key': API_KEY, 'url': youtube_url, 'quality': quality, 'format': format_type } logger.info(f"Downloading video with params: {params}") # First, check if download works test_response = requests.get(API_URL, params=params, timeout=30, stream=True) if test_response.status_code == 200: # Generate unique filename filename = f"video_{uuid.uuid4().hex[:8]}.{format_type}" filepath = os.path.join(DOWNLOAD_DIR, filename) # Download file with open(filepath, 'wb') as f: for chunk in test_response.iter_content(chunk_size=8192): if chunk: f.write(chunk) logger.info(f"Video downloaded to: {filepath}") return { 'success': True, 'filepath': filepath, 'filename': filename, 'direct_url': f"{API_URL}?{urlencode(params)}" } else: logger.error(f"Download failed: {test_response.status_code}") return { 'success': False, 'error': f"API returned status {test_response.status_code}" } except Exception as e: logger.error(f"Download error: {str(e)}") return { 'success': False, 'error': str(e) } # API Routes @app.route('/') def index(): """Serve the HTML frontend""" return render_template('index.html') @app.route('/api/video-info', methods=['GET']) def video_info(): """Get video information""" youtube_url = request.args.get('url') if not youtube_url: return jsonify({ 'success': False, 'error': 'YouTube URL is required' }), 400 # Validate YouTube URL if 'youtube.com' not in youtube_url and 'youtu.be' not in youtube_url: return jsonify({ 'success': False, 'error': 'Invalid YouTube URL' }), 400 # Fetch video info from API video_data = get_video_info_from_api(youtube_url) if video_data: # Process API response if 'videos' in video_data: # Extract available formats formats = [] for video in video_data.get('videos', []): if isinstance(video, dict): formats.append({ 'quality': video.get('quality', 'Unknown'), 'size': video.get('size', 'N/A'), 'format': video.get('ext', 'mp4'), 'url': video.get('url', '') }) # Extract thumbnail (if available) thumbnail = '' if 'thumbnail' in video_data: thumbnail = video_data['thumbnail'] elif 'thumb' in video_data: thumbnail = video_data['thumb'] return jsonify({ 'success': True, 'data': { 'title': video_data.get('title', 'YouTube Video'), 'thumbnail': thumbnail, 'duration': video_data.get('duration', 0), 'formats': formats, 'raw_data': video_data # Include raw data for debugging } }) else: return jsonify({ 'success': True, 'data': { 'title': 'YouTube Video', 'thumbnail': '', 'duration': 0, 'formats': [], 'raw_data': video_data } }) else: return jsonify({ 'success': False, 'error': 'Could not fetch video information' }), 500 @app.route('/api/download', methods=['POST']) def download_video(): """Download video endpoint""" try: data = request.json youtube_url = data.get('url') format_type = data.get('format', 'mp4') quality = data.get('quality', '360') if not youtube_url: return jsonify({ 'success': False, 'error': 'YouTube URL is required' }), 400 # Download video result = download_video_from_api(youtube_url, quality, format_type) if result['success']: # Return download URL download_url = f"/api/download-file/{result['filename']}" return jsonify({ 'success': True, 'data': { 'download_url': download_url, 'direct_url': result['direct_url'], 'filename': result['filename'] } }) else: return jsonify({ 'success': False, 'error': result['error'] }), 500 except Exception as e: logger.error(f"Download endpoint error: {str(e)}") return jsonify({ 'success': False, 'error': str(e) }), 500 @app.route('/api/download-file/', methods=['GET']) def download_file(filename): """Serve downloaded file""" try: filepath = os.path.join(DOWNLOAD_DIR, secure_filename(filename)) if not os.path.exists(filepath): return jsonify({ 'success': False, 'error': 'File not found' }), 404 # Determine MIME type ext = os.path.splitext(filename)[1].lower() mime_types = { '.mp4': 'video/mp4', '.mp3': 'audio/mpeg', '.webm': 'video/webm', '.mkv': 'video/x-matroska' } mimetype = mime_types.get(ext, 'application/octet-stream') return send_file( filepath, as_attachment=True, download_name=filename, mimetype=mimetype ) except Exception as e: logger.error(f"File download error: {str(e)}") return jsonify({ 'success': False, 'error': str(e) }), 500 @app.route('/api/formats', methods=['GET']) def available_formats(): """Get available formats for a video""" youtube_url = request.args.get('url') if not youtube_url: return jsonify({ 'success': False, 'error': 'YouTube URL is required' }), 400 # Get video info video_data = get_video_info_from_api(youtube_url) if video_data and 'videos' in video_data: formats = [] # Video formats for video in video_data.get('videos', []): if isinstance(video, dict) and video.get('url'): formats.append({ 'type': 'video', 'quality': video.get('quality', 'Unknown'), 'format': video.get('ext', 'mp4'), 'size': video.get('size', 'N/A'), 'code': f"mp4-{video.get('quality', '360').replace('p', '')}" }) # Audio formats for audio in video_data.get('audios', []): if isinstance(audio, dict) and audio.get('url'): formats.append({ 'type': 'audio', 'quality': audio.get('quality', 'MP3'), 'format': audio.get('ext', 'mp3'), 'size': audio.get('size', 'N/A'), 'code': f"mp3-{audio.get('quality', 'high').lower()}" }) return jsonify({ 'success': True, 'formats': formats }) # Return default formats if API fails return jsonify({ 'success': True, 'formats': [ {'type': 'video', 'quality': '720p', 'format': 'mp4', 'size': 'HD', 'code': 'mp4-720'}, {'type': 'video', 'quality': '480p', 'format': 'mp4', 'size': 'SD', 'code': 'mp4-480'}, {'type': 'video', 'quality': '360p', 'format': 'mp4', 'size': 'Medium', 'code': 'mp4-360'}, {'type': 'video', 'quality': '240p', 'format': 'mp4', 'size': 'Low', 'code': 'mp4-240'}, {'type': 'audio', 'quality': 'High', 'format': 'mp3', 'size': '128kbps', 'code': 'mp3-high'}, {'type': 'audio', 'quality': 'Medium', 'format': 'mp3', 'size': '64kbps', 'code': 'mp3-medium'} ] }) @app.route('/api/health', methods=['GET']) def health_check(): """Health check endpoint""" return jsonify({ 'status': 'healthy', 'service': 'YouTube Downloader API', 'api_available': True }) # Error handlers @app.errorhandler(404) def not_found(error): return jsonify({ 'success': False, 'error': 'Endpoint not found' }), 404 @app.errorhandler(500) def server_error(error): return jsonify({ 'success': False, 'error': 'Internal server error' }), 500 if __name__ == '__main__': # Create templates directory os.makedirs('templates', exist_ok=True) # Save HTML to templates directory html_content = """ YouTube Video Downloader

YouTube Video Downloader

Download YouTube videos effortlessly for offline viewing and ad-free access.

Trusted by 1,000,000 users

If you want to convert YouTube to Video, you agree to the Usage Guidelines.
Video Thumbnail

Video Title

0%
Processing...
Download completed successfully!
An error occurred. Please try again.
""" with open('templates/index.html', 'w', encoding='utf-8') as f: f.write(html_content) print("="*60) print("šŸ¤– YouTube Video Downloader Backend") print("="*60) print(f"šŸ“ Downloads directory: {DOWNLOAD_DIR}") print(f"🌐 API Base URL: http://localhost:5000") print(f"šŸ“± Frontend: http://localhost:5000/") print(f"šŸ”§ Health Check: http://localhost:5000/api/health") print("="*60) print("\nšŸš€ Starting server...") # Run Flask app app.run(host='0.0.0.0', port=5000, debug=True)