Add web-enabled MPV main entry point

This commit is contained in:
2025-12-09 16:41:38 +11:00
parent 20d0da40ba
commit 48bb529b99

341
web_mpv_main.py Normal file
View File

@@ -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())