# web_mpv_main.py """ MPV Video Player with Web Interface Integration Combines the enhanced debug console with web interface capabilities """ import sys import threading import logging import time from datetime import datetime from pathlib import Path def check_web_requirements(): """Check if web interface requirements are available""" print("Checking Web Interface Requirements...") print("=" * 40) # Check Flask and Flask-SocketIO try: import flask print("✓ Flask available") except ImportError: print("✗ Flask not installed") print("Install with: pip install flask") return False try: import flask_socketio print("✓ Flask-SocketIO available") except ImportError: print("✗ Flask-SocketIO not installed") print("Install with: pip install flask-socketio") return False # Check MPV try: import mpv print("✓ python-mpv available") # Test MPV functionality try: test_player = mpv.MPV(vo='null', ao='null', video=False, quiet=True) test_player.terminate() print("✓ MPV functionality test passed") except Exception as e: print(f"✗ MPV test failed: {e}") return False except ImportError: print("✗ python-mpv not installed") print("Install with: pip install python-mpv") return False # Check other requirements try: from config import Config print("✓ config module available") except ImportError: print("✗ config.py not found") return False try: from enhanced_debug_console import EnhancedDebugConsoleWithWeb print("✓ enhanced debug console available") except ImportError: print("✗ enhanced_debug_console.py not found") return False try: from mpv_seamless_player import MPVSeamlessPlayer print("✓ MPV seamless player available") except ImportError: print("✗ mpv_seamless_player.py not found") return False print("✓ All web interface requirements satisfied") return True # Import after requirement check from config import Config from enhanced_debug_console import EnhancedDebugConsoleWithWeb from mpv_seamless_player import MPVSeamlessPlayer def make_json_safe(data): """Convert data to be JSON-safe by handling datetime objects""" if isinstance(data, dict): return {key: make_json_safe(value) for key, value in data.items()} elif isinstance(data, list): return [make_json_safe(item) for item in data] elif isinstance(data, datetime): return data.isoformat() elif hasattr(data, 'total_seconds'): # timedelta return str(data) else: return data class WebMPVVideoPlayerApp: def __init__(self, web_port=8547): self.config = Config() self.running = True self.debug_console = None self.video_player = None self.video_thread = None self.web_port = web_port self.logger = logging.getLogger(__name__) def initialize_components(self): """Initialize all components with web interface support""" try: self.logger.info("=== WEB + MPV APPLICATION INITIALIZATION START ===") # Create enhanced debug console with web interface (runs in main thread) self.debug_console = EnhancedDebugConsoleWithWeb( enable_web=True, web_port=self.web_port ) self.logger.info("Enhanced debug console with web interface created") # Create MPV seamless player (runs in separate thread) self.video_player = MPVSeamlessPlayer(self.config, self.debug_console) self.logger.info("MPV seamless player created") # Connect components self.debug_console.set_video_player(self.video_player) self.logger.info("Components connected successfully") self.logger.info("=== WEB + MPV APPLICATION INITIALIZATION COMPLETE ===") return True except Exception as e: self.logger.error(f"Web + MPV initialization failed: {e}", exc_info=True) print(f"\nInitialization Error: {e}") print("\nTroubleshooting:") print("1. Ensure MPV is installed and DLL files are present") print("2. Check that python-mpv is installed: pip install python-mpv") print("3. Check that Flask is installed: pip install flask flask-socketio") print("4. Verify video files exist in the trailers folder") return False def start_video_player_thread(self): """Start MPV video player in separate thread""" def mpv_video_player_worker(): try: self.logger.info("MPV video player thread starting...") self.video_player.run() except Exception as e: self.logger.error(f"MPV video player thread error: {e}", exc_info=True) print(f"Video player error: {e}") finally: self.logger.info("MPV video player thread ended") self.video_thread = threading.Thread( target=mpv_video_player_worker, daemon=True, name="MPVVideoPlayerThread" ) self.video_thread.start() self.logger.info("MPV video player thread started") def run(self): """Main application loop with web interface""" self.logger.info("=== WEB + MPV APPLICATION START ===") # Get local IP for display try: import socket with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: s.connect(('8.8.8.8', 80)) local_ip = s.getsockname()[0] except: try: hostname = socket.gethostname() local_ip = socket.gethostbyname(hostname) if local_ip.startswith('127.'): local_ip = 'your-computer-ip' except: local_ip = 'your-computer-ip' print("\n" + "="*70) print("🎬 MPV SEAMLESS VIDEO PLAYER WITH WEB INTERFACE") print("="*70) print("🌐 Web interface enabled - modern control dashboard!") print("📱 Mobile responsive design") print("⚡ Real-time status updates") print("🎮 Remote control via web browser") print("✓ All original functionality preserved") print("✓ Global input capture maintained") print("✓ Superior MPV video quality") print("="*70) print(f"\n🔗 WEB INTERFACE ACCESS URLS:") print(f" 📍 Local: http://localhost:{self.web_port}") print(f" 🌐 Network: http://{local_ip}:{self.web_port}") print(f" 📱 Mobile: http://{local_ip}:{self.web_port}") print("="*70) print("📱 MOBILE ACCESS INSTRUCTIONS:") print(f" 1. Connect phone/tablet to same WiFi network") print(f" 2. Open browser on mobile device") print(f" 3. Go to: http://{local_ip}:{self.web_port}") print(f" 4. Bookmark for easy access!") print("="*70) print("\nInitializing components...") if not self.initialize_components(): self.logger.error("Failed to initialize components - exiting") return 1 try: # Start MPV video player in background thread self.start_video_player_thread() # Give MPV player time to initialize print("🎬 MPV player starting...") time.sleep(2) print("✓ MPV player ready!") print(f"\n🌐 Web interface starting on port {self.web_port}...") time.sleep(1) print("✓ Web interface ready!") print("\n🎯 DUAL CONTROL OPTIONS:") print(" 1. 🖥️ Traditional Debug Console (this window)") print(" 2. 🌐 Modern Web Interface (browser)") print(" 3. 📱 Mobile/Remote Control (any device)") print("\n🚀 ENHANCED FEATURES:") print(" • Real-time video statistics") print(" • Performance monitoring") print(" • Video history tracking") print(" • Remote NFC input") print(" • System health monitoring") print(" • Hot-reload mappings") print(" • Manual video selection") print(f"\n📖 Quick Start:") print(f" 1. Open browser to: http://localhost:{self.web_port}") print(f" 2. Control videos from web dashboard") print(f" 3. NFC cards work globally (even fullscreen)") print(f" 4. Edit mappings and click 'Reload Mappings'") print(f" 5. Close debug window OR web interface to exit") print("\n" + "="*70) print("🎬 SYSTEM READY - Access web interface via URLs above!") print("="*70) # Run debug console in main thread (blocks until window closes) # The web interface runs in parallel threads self.debug_console.run() except KeyboardInterrupt: self.logger.info("Web + MPV application interrupted by user") print("\nApplication interrupted by user") except Exception as e: self.logger.error(f"Web + MPV application error: {e}", exc_info=True) print(f"\nApplication error: {e}") finally: self.cleanup() self.logger.info("=== WEB + MPV APPLICATION END ===") return 0 def cleanup(self): """Clean up all resources""" self.logger.info("=== WEB + MPV CLEANUP START ===") self.running = False print("\nShutting down web + MPV application...") if hasattr(self, 'video_player') and self.video_player: try: self.video_player.stop() self.logger.info("MPV video player stopped") print("✓ MPV video player stopped") except Exception as e: self.logger.error(f"Error stopping MPV video player: {e}") # Wait for video thread to finish if hasattr(self, 'video_thread') and self.video_thread and self.video_thread.is_alive(): try: print("Waiting for MPV thread to finish...") self.video_thread.join(timeout=5) if self.video_thread.is_alive(): self.logger.warning("MPV video thread did not stop cleanly") print("⚠ MPV thread did not stop cleanly") else: self.logger.info("MPV video thread joined successfully") print("✓ MPV thread stopped") except Exception as e: self.logger.error(f"Error joining MPV video thread: {e}") if hasattr(self, 'debug_console') and self.debug_console: try: self.debug_console.stop() self.logger.info("Enhanced debug console stopped") print("✓ Debug console and web interface stopped") except Exception as e: self.logger.error(f"Error stopping debug console: {e}") self.logger.info("=== WEB + MPV CLEANUP COMPLETE ===") print("✓ Cleanup complete - all resources freed") def main(): """Main entry point with web interface""" print("MPV Seamless Video Player with Web Interface") print("Next-Generation Video Control System") print("-" * 50) # Check requirements first if not check_web_requirements(): print("\n✗ Requirements not met. Please install missing components.") print("\nRequired installations:") print("pip install flask flask-socketio python-mpv") return 1 print("\n🚀 Starting web-enabled MPV application...") # Allow custom port via command line web_port = 8547 if len(sys.argv) > 1: try: web_port = int(sys.argv[1]) print(f"Using custom port: {web_port}") except ValueError: print("Invalid port number, using default: 8547") try: app = WebMPVVideoPlayerApp(web_port=web_port) return app.run() except Exception as e: print(f"\n✗ Fatal error: {e}") logging.error(f"Fatal application error: {e}", exc_info=True) return 1 if __name__ == "__main__": # Set up basic logging logging.basicConfig( level=logging.INFO, format='%(asctime)s [%(name)s] %(levelname)s: %(message)s' ) sys.exit(main())