vehicle-tracker / app.py
Stanley03's picture
Upload 9 files
de631bc verified
"""
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)}'
@app.route('/')
def index():
return send_file('web_app.html')
@app.route('/upload', methods=['POST'])
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
@app.route('/status')
def get_status():
return jsonify(processing_status)
@app.route('/download/<filename>')
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)