#!/usr/bin/env python3 """ VR180 Metadata Injector Adds proper VR180 metadata to side-by-side stereoscopic videos for VR headset compatibility. """ import os import sys import subprocess import json import tempfile from pathlib import Path def check_spatial_media_installer(): """Check if Google's Spatial Media Metadata Injector is installed.""" try: # Try to find the spatial media installer result = subprocess.run(['spatial-media', '--help'], capture_output=True, text=True, timeout=10) return True except (subprocess.TimeoutExpired, FileNotFoundError, subprocess.CalledProcessError): return False def install_spatial_media(): """Install Google's Spatial Media Metadata Injector.""" print("Installing Google's Spatial Media Metadata Injector...") try: # Install via pip subprocess.run([sys.executable, '-m', 'pip', 'install', 'spatial-media'], check=True) print("✅ Spatial Media Metadata Injector installed successfully!") return True except subprocess.CalledProcessError as e: print(f"❌ Failed to install spatial-media: {e}") return False def create_metadata_json(): """Create VR180 metadata JSON configuration.""" metadata = { "spatial_audio": False, "stereo_mode": "left-right", "projection": "180" } # Create temporary JSON file temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) json.dump(metadata, temp_file, indent=2) temp_file.close() return temp_file.name def inject_vr180_metadata(input_file, output_file): """Inject VR180 metadata into the video file.""" print(f"Processing: {input_file}") print(f"Output: {output_file}") # Create metadata JSON metadata_file = create_metadata_json() try: # Use spatial-media to inject metadata cmd = [ 'spatial-media', 'inject', '--input', input_file, '--output', output_file, '--metadata', metadata_file ] print("Injecting VR180 metadata...") result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) if result.returncode == 0: print("✅ VR180 metadata injected successfully!") print(f"✅ Output saved as: {output_file}") return True else: print(f"❌ Error injecting metadata: {result.stderr}") return False except subprocess.TimeoutExpired: print("❌ Process timed out. Video might be too large.") return False except Exception as e: print(f"❌ Error: {e}") return False finally: # Clean up temporary metadata file try: os.unlink(metadata_file) except: pass def validate_input_file(input_file): """Validate that the input file exists and is a video.""" if not os.path.exists(input_file): print(f"❌ Input file not found: {input_file}") return False # Check if it's a video file video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.webm'] if not any(input_file.lower().endswith(ext) for ext in video_extensions): print(f"❌ Input file doesn't appear to be a video: {input_file}") return False return True def main(): """Main function.""" if len(sys.argv) != 3: print("Usage: python add_vr180_metadata.py ") print("\nExample:") print("python add_vr180_metadata.py input.mp4 output_vr180.mp4") sys.exit(1) input_file = sys.argv[1] output_file = sys.argv[2] print("🥽 VR180 Metadata Injector") print("=" * 40) # Validate input file if not validate_input_file(input_file): sys.exit(1) # Check if spatial media installer is available if not check_spatial_media_installer(): print("📦 Spatial Media Metadata Injector not found.") if not install_spatial_media(): print("❌ Cannot proceed without Spatial Media Metadata Injector.") sys.exit(1) # Create output directory if it doesn't exist output_dir = os.path.dirname(output_file) if output_dir and not os.path.exists(output_dir): os.makedirs(output_dir) # Inject VR180 metadata if inject_vr180_metadata(input_file, output_file): print("\n🎉 Success! Your video is now VR180-compliant!") print(f"📱 You can now play '{output_file}' in VR headsets like:") print(" • Oculus Quest/Quest 2/Quest Pro") print(" • HTC Vive") print(" • PlayStation VR") print(" • Windows Mixed Reality") print("\n💡 Make sure to select 'Side-by-Side' or 'SBS' mode in your VR player.") else: print("\n❌ Failed to inject VR180 metadata.") sys.exit(1) if __name__ == "__main__": main()