Spaces:
Runtime error
Runtime error
| #!/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 <input_video> <output_vr180_video>") | |
| 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() | |