Spaces:
Sleeping
Sleeping
| import logging | |
| import subprocess | |
| import os | |
| from pathlib import Path | |
| logging.basicConfig(level=logging.INFO) | |
| def extract_audio(video_url: str, identifier: str, output_dir: str = "temp_audio") -> str: | |
| """ | |
| استخراج الصوت من فيديو باستخدام ffmpeg streaming | |
| Args: | |
| video_url: رابط الفيديو من Internet Archive | |
| identifier: معرف الفيديو | |
| output_dir: مجلد حفظ الملفات المؤقتة | |
| Returns: | |
| مسار ملف الصوت المستخرج | |
| """ | |
| try: | |
| # إنشاء المجلد لو مش موجود | |
| Path(output_dir).mkdir(exist_ok=True) | |
| # مسار الملف النهائي | |
| output_file = os.path.join(output_dir, f"{identifier}.mp3") | |
| # لو الملف موجود من قبل، نرجعه مباشرة (caching) | |
| if os.path.exists(output_file): | |
| logging.info(f"Audio file already exists: {output_file}") | |
| return output_file | |
| logging.info(f"Extracting audio from: {video_url}") | |
| # أمر ffmpeg مع إعدادات محسّنة للسرعة | |
| command = [ | |
| 'ffmpeg', | |
| '-y', # Overwrite output file | |
| '-i', video_url, # Input video URL | |
| '-vn', # No video | |
| '-acodec', 'libmp3lame', # MP3 codec | |
| '-ab', '64k', # 64 kbps (خفيف ومناسب للكلام) | |
| '-ar', '16000', # 16 kHz sample rate (كافي للـ speech) | |
| '-ac', '1', # Mono (قناة واحدة) | |
| '-threads', '2', # استخدام 2 threads فقط | |
| output_file | |
| ] | |
| # تنفيذ الأمر مع timeout | |
| logging.info("Running ffmpeg...") | |
| result = subprocess.run( | |
| command, | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.PIPE, | |
| timeout=60 # Timeout بعد دقيقة | |
| ) | |
| if result.returncode != 0: | |
| error_msg = result.stderr.decode('utf-8', errors='ignore') | |
| logging.error(f"FFmpeg error: {error_msg}") | |
| raise Exception(f"FFmpeg failed: {error_msg[:200]}") | |
| # التحقق من وجود الملف وحجمه | |
| if not os.path.exists(output_file): | |
| raise Exception("Audio file was not created") | |
| file_size = os.path.getsize(output_file) | |
| file_size_mb = file_size / (1024 * 1024) | |
| logging.info(f"✅ Audio extracted successfully! Size: {file_size_mb:.2f} MB") | |
| return output_file | |
| except subprocess.TimeoutExpired: | |
| logging.error("FFmpeg timeout - video too long") | |
| raise Exception("Video too long for processing (max 1 minute)") | |
| except Exception as e: | |
| logging.error(f"Error extracting audio: {e}") | |
| # حذف الملف الناقص لو موجود | |
| if os.path.exists(output_file): | |
| try: | |
| os.remove(output_file) | |
| except: | |
| pass | |
| raise | |
| def cleanup_old_files(output_dir: str = "temp_audio", max_age_hours: int = 24): | |
| """ | |
| حذف الملفات القديمة لتوفير المساحة | |
| Args: | |
| output_dir: مجلد الملفات المؤقتة | |
| max_age_hours: حذف الملفات الأقدم من هذا العدد من الساعات | |
| """ | |
| try: | |
| import time | |
| current_time = time.time() | |
| for filename in os.listdir(output_dir): | |
| filepath = os.path.join(output_dir, filename) | |
| if os.path.isfile(filepath): | |
| file_age_hours = (current_time - os.path.getmtime(filepath)) / 3600 | |
| if file_age_hours > max_age_hours: | |
| os.remove(filepath) | |
| logging.info(f"Deleted old file: {filename}") | |
| except Exception as e: | |
| logging.warning(f"Cleanup error: {e}") |