Spaces:
Sleeping
Sleeping
| """ | |
| Hugging Face Spaces - Vehicle Tracking App | |
| """ | |
| from flask import Flask, request, jsonify, send_file, send_from_directory | |
| from werkzeug.utils import secure_filename | |
| import os | |
| import subprocess | |
| import threading | |
| import time | |
| import shutil | |
| app = Flask(__name__) | |
| # Configuration | |
| UPLOAD_FOLDER = 'uploads' | |
| OUTPUT_FOLDER = 'outputs' | |
| ALLOWED_EXTENSIONS = {'mp4', 'avi', 'mov', 'mkv'} | |
| # Create folders | |
| 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 # 500 MB limit | |
| # Global status | |
| processing_status = { | |
| 'status': 'idle', | |
| 'progress': 0, | |
| 'message': '', | |
| 'output_file': None | |
| } | |
| def allowed_file(filename): | |
| return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS | |
| def process_video_background(input_path, output_path): | |
| global processing_status | |
| try: | |
| processing_status['status'] = 'processing' | |
| processing_status['progress'] = 0 | |
| processing_status['message'] = 'Starting processing...' | |
| # Run tracker with --no-display flag | |
| cmd = [ | |
| 'python', '-u', 'vehicle_tracker.py', | |
| '--video', input_path, | |
| '--output', output_path, | |
| '--no-display' | |
| ] | |
| process = subprocess.Popen( | |
| cmd, | |
| stdout=subprocess.PIPE, | |
| stderr=subprocess.PIPE, | |
| text=True, | |
| bufsize=1, | |
| universal_newlines=True | |
| ) | |
| for line in process.stdout: | |
| if "Progress:" in line: | |
| try: | |
| parts = line.split('|')[0] | |
| percent = float(parts.split(':')[1].strip().replace('%', '')) | |
| processing_status['progress'] = percent | |
| processing_status['message'] = f'Processing: {percent:.1f}%' | |
| except: | |
| pass | |
| process.wait() | |
| if process.returncode == 0: | |
| processing_status['status'] = 'complete' | |
| processing_status['progress'] = 100 | |
| processing_status['message'] = 'Processing complete!' | |
| processing_status['output_file'] = os.path.basename(output_path) | |
| else: | |
| stderr = process.stderr.read() | |
| processing_status['status'] = 'error' | |
| processing_status['message'] = f'Error: {stderr[:200]}' | |
| except Exception as e: | |
| processing_status['status'] = 'error' | |
| processing_status['message'] = f'System Error: {str(e)}' | |
| def index(): | |
| return send_file('web_app.html') | |
| def upload_file(): | |
| global processing_status | |
| processing_status = {'status': 'idle', 'progress': 0, 'message': '', 'output_file': None} | |
| if 'video' not in request.files: | |
| return jsonify({'error': 'No file part'}), 400 | |
| file = request.files['video'] | |
| if file.filename == '': | |
| return jsonify({'error': 'No selected file'}), 400 | |
| if file and allowed_file(file.filename): | |
| filename = secure_filename(file.filename) | |
| # Use simple timestamp to avoid collisions | |
| timestamp = int(time.time()) | |
| input_filename = f"{timestamp}_{filename}" | |
| input_path = os.path.join(app.config['UPLOAD_FOLDER'], input_filename) | |
| file.save(input_path) | |
| output_filename = f"tracked_{input_filename}" | |
| output_path = os.path.join(app.config['OUTPUT_FOLDER'], output_filename) | |
| thread = threading.Thread(target=process_video_background, args=(input_path, output_path)) | |
| thread.daemon = True | |
| thread.start() | |
| return jsonify({'success': True, 'filename': input_filename}) | |
| return jsonify({'error': 'Invalid file type'}), 400 | |
| def get_status(): | |
| return jsonify(processing_status) | |
| def download_file(filename): | |
| return send_from_directory(app.config['OUTPUT_FOLDER'], filename, as_attachment=True) | |
| if __name__ == '__main__': | |
| # Hugging Face Spaces runs on port 7860 | |
| app.run(host='0.0.0.0', port=7860) | |