From 48bb529b9922c893c86c9690623365c51828f910 Mon Sep 17 00:00:00 2001 From: jessikitty Date: Tue, 9 Dec 2025 16:41:38 +1100 Subject: [PATCH] Add web-enabled MPV main entry point --- web_mpv_main.py | 341 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 web_mpv_main.py diff --git a/web_mpv_main.py b/web_mpv_main.py new file mode 100644 index 0000000..70e9ae7 --- /dev/null +++ b/web_mpv_main.py @@ -0,0 +1,341 @@ +# 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())