from flask import Flask, request, jsonify, send_file from flask_cors import CORS import os import cv2 import numpy as np from PIL import Image import moviepy.editor as mp from werkzeug.utils import secure_filename import tempfile import uuid import json from .video_processor import VideoProcessor # Fixed relative import def process_video(video_path, progress_callback=None): """ Process a video file and return the result. This function is used by both Flask API and Gradio interface. """ try: # Initialize video processor processor = VideoProcessor() # Generate output filename input_filename = os.path.basename(video_path) output_filename = f"vr180_{input_filename}" output_path = os.path.join(OUTPUT_FOLDER, output_filename) # Process video if progress_callback: progress_callback(0.2, desc="Initializing video processing...") result = processor.process_video(video_path, output_path, progress_callback) if result['success']: if progress_callback: progress_callback(1.0, desc="Processing complete!") return { 'success': True, 'output_path': output_path, 'output_filename': output_filename, 'message': 'Video processed successfully', 'processing_time': result.get('processing_time', 0) } else: return { 'success': False, 'error': result.get('error', 'Processing failed') } except Exception as e: return { 'success': False, 'error': f'Error processing video: {str(e)}' } app = Flask(__name__) CORS(app) # Configuration UPLOAD_FOLDER = 'uploads' OUTPUT_FOLDER = 'outputs' ALLOWED_EXTENSIONS = {'mp4', 'avi', 'mov', 'mkv', 'webm'} # Create directories os.makedirs(UPLOAD_FOLDER, exist_ok=True) os.makedirs(OUTPUT_FOLDER, exist_ok=True) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER app.config['OUTPUT_FOLDER'] = OUTPUT_FOLDER app.config['MAX_CONTENT_LENGTH'] = 500 * 1024 * 1024 # 500MB max file size def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/api/health', methods=['GET']) def health_check(): return jsonify({'status': 'healthy', 'message': 'VR180 Converter API is running'}) @app.route('/api/upload', methods=['POST']) def upload_video(): if 'video' not in request.files: return jsonify({'error': 'No video file provided'}), 400 file = request.files['video'] if file.filename == '': return jsonify({'error': 'No file selected'}), 400 if not allowed_file(file.filename): return jsonify({'error': 'Invalid file type. Please upload MP4, AVI, MOV, MKV, or WebM'}), 400 # Generate unique filename filename = secure_filename(file.filename) unique_filename = f"{uuid.uuid4()}_{filename}" filepath = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename) try: file.save(filepath) # Get video info video = mp.VideoFileClip(filepath) duration = video.duration fps = video.fps size = video.size video.close() return jsonify({ 'success': True, 'filename': unique_filename, 'original_name': filename, 'duration': duration, 'fps': fps, 'size': size }) except Exception as e: return jsonify({'error': f'Error processing file: {str(e)}'}), 500 @app.route('/api/process', methods=['POST']) def process_video_api(): data = request.get_json() filename = data.get('filename') if not filename: return jsonify({'error': 'No filename provided'}), 400 filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) if not os.path.exists(filepath): return jsonify({'error': 'File not found'}), 404 # Use the shared process_video function result = process_video(filepath) if result['success']: return jsonify(result) else: return jsonify({'error': result.get('error', 'Processing failed')}), 500 @app.route('/api/download/') def download_video(filename): filepath = os.path.join(app.config['OUTPUT_FOLDER'], filename) if not os.path.exists(filepath): return jsonify({'error': 'File not found'}), 404 return send_file(filepath, as_attachment=True) @app.route('/api/status/') def get_processing_status(filename): # This would be implemented with a proper job queue in production # For now, we'll return a simple status return jsonify({ 'status': 'completed', 'progress': 100 }) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000)