Murad Jabir преди 1 година
родител
ревизия
7f90047ce5
променени са 1 файла, в които са добавени 113 реда и са изтрити 2 реда
  1. 113 2
      main.py

+ 113 - 2
main.py

@@ -3,6 +3,8 @@ import time
 import datetime
 import pickle
 import threading
+import queue
+from concurrent.futures import ThreadPoolExecutor
 from googleapiclient.discovery import build
 import subprocess
 from google.auth.transport.requests import Request
@@ -18,6 +20,14 @@ EXIT_TIME = datetime.time(6, 0)  # Exit the script at 06:00
 POPULAR_VIDEOS_MAX_RESULTS = 10  # Number of popular videos to fetch (you can change this)
 REGION_CODES = ["US", "GB", "LU", "LK"]  # Regions to fetch popular videos from
 
+# Conversion Queue Settings
+MAX_CONCURRENT_CONVERSIONS = 2  # Maximum number of simultaneous video conversions
+CONVERSION_QUEUE_SIZE = 50       # Maximum items in conversion queue
+
+# Global conversion queue and executor
+conversion_queue = queue.Queue(maxsize=CONVERSION_QUEUE_SIZE)
+conversion_executor = ThreadPoolExecutor(max_workers=MAX_CONCURRENT_CONVERSIONS, thread_name_prefix="VideoConverter")
+
 def update_yt_dlp():
     """Update yt-dlp to the latest version."""
     print("Updating yt-dlp to the latest version...")
@@ -129,6 +139,65 @@ def download_video(video_id, output_path):
         return False
     return True
 
+def add_to_conversion_queue(input_file, priority=1):
+    """Add a video file to the conversion queue with priority."""
+    try:
+        # Higher number = higher priority (4K gets priority 2, others get 1)
+        conversion_queue.put((priority, input_file), timeout=1)
+        print(f"Added to conversion queue: {os.path.basename(input_file)} (priority: {priority})")
+        return True
+    except queue.Full:
+        print(f"⚠️ Conversion queue is full! Skipping: {os.path.basename(input_file)}")
+        return False
+
+def get_queue_status():
+    """Get current conversion queue status."""
+    queue_size = conversion_queue.qsize()
+    active_conversions = conversion_executor._threads  # Active thread count
+    return {
+        'queued': queue_size,
+        'active': len(active_conversions) if active_conversions else 0,
+        'max_concurrent': MAX_CONCURRENT_CONVERSIONS
+    }
+
+def print_queue_status():
+    """Print current queue status."""
+    status = get_queue_status()
+    print(f"🎬 Conversion Status: {status['active']}/{status['max_concurrent']} active, {status['queued']} queued")
+
+def process_conversion_queue():
+    """Background worker to process the conversion queue."""
+    while True:
+        try:
+            # Get item from queue (blocks until available)
+            priority, input_file = conversion_queue.get(timeout=30)
+            
+            # Check if file still exists
+            if not os.path.exists(input_file):
+                print(f"⚠️ File no longer exists, skipping conversion: {input_file}")
+                conversion_queue.task_done()
+                continue
+            
+            print(f"🔄 Starting conversion (priority {priority}): {os.path.basename(input_file)}")
+            
+            # Perform the conversion
+            success = convert_to_apple_tv_compatible(input_file)
+            
+            if success:
+                print(f"✅ Conversion completed: {os.path.basename(input_file)}")
+            else:
+                print(f"❌ Conversion failed: {os.path.basename(input_file)}")
+            
+            # Mark task as done
+            conversion_queue.task_done()
+            
+        except queue.Empty:
+            # No items in queue for 30 seconds, continue waiting
+            continue
+        except Exception as e:
+            print(f"❌ Conversion queue error: {e}")
+            conversion_queue.task_done()
+
 def convert_to_apple_tv_compatible(input_file):
     """Convert a video to Apple TV 4K compatible format, optimized by resolution."""
     base_name = os.path.splitext(input_file)[0]
@@ -271,6 +340,14 @@ def check_exit_time():
         sys.exit(0)
 
 def main():
+    # Start the conversion queue worker
+    print("🎬 Starting video conversion queue system...")
+    print(f"📊 Max concurrent conversions: {MAX_CONCURRENT_CONVERSIONS}")
+    
+    # Start background conversion worker
+    conversion_worker = threading.Thread(target=process_conversion_queue, daemon=True, name="ConversionQueueWorker")
+    conversion_worker.start()
+    
     # Update yt-dlp
     update_yt_dlp()
 
@@ -340,7 +417,18 @@ def main():
                             break
             
             if needs_conversion and conversion_file:
-                threading.Thread(target=convert_to_apple_tv_compatible, args=(conversion_file,)).start()
+                # Determine priority based on video resolution
+                try:
+                    probe_cmd = ["ffprobe", "-v", "quiet", "-select_streams", "v:0", 
+                               "-show_entries", "stream=height", "-of", "csv=p=0", conversion_file]
+                    result = subprocess.run(probe_cmd, capture_output=True, text=True, check=True)
+                    height = int(result.stdout.strip()) if result.stdout.strip().isdigit() else 1080
+                    priority = 2 if height >= 2160 else 1  # 4K gets higher priority
+                except:
+                    priority = 1  # Default priority
+                
+                add_to_conversion_queue(conversion_file, priority)
+                print_queue_status()
             
             # Create the NFO file
             nfo_file_path = os.path.join(video_dir, "movie.nfo")
@@ -397,13 +485,36 @@ def main():
                             break
             
             if needs_conversion and conversion_file:
-                threading.Thread(target=convert_to_apple_tv_compatible, args=(conversion_file,)).start()
+                # Determine priority based on video resolution
+                try:
+                    probe_cmd = ["ffprobe", "-v", "quiet", "-select_streams", "v:0", 
+                               "-show_entries", "stream=height", "-of", "csv=p=0", conversion_file]
+                    result = subprocess.run(probe_cmd, capture_output=True, text=True, check=True)
+                    height = int(result.stdout.strip()) if result.stdout.strip().isdigit() else 1080
+                    priority = 2 if height >= 2160 else 1  # 4K gets higher priority
+                except:
+                    priority = 1  # Default priority
+                
+                add_to_conversion_queue(conversion_file, priority)
+                print_queue_status()
             
             # Create the NFO file
             nfo_file_path = os.path.join(video_dir, "movie.nfo")
             create_nfo_file(video, nfo_file_path)
     
     print("All videos processed successfully!")
+    
+    # Final conversion queue status
+    print("\n🎬 Final Conversion Queue Status:")
+    print_queue_status()
+    
+    queued_items = conversion_queue.qsize()
+    if queued_items > 0:
+        print(f"⏳ {queued_items} videos still in conversion queue")
+        print("💡 Conversions will continue in the background")
+        print("💡 You can monitor progress by checking the output folder")
+    else:
+        print("✅ All conversions completed!")
 
 if __name__ == "__main__":
     main()