Spaces:
Runtime error
Runtime error
File size: 3,662 Bytes
de45b38 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
from flask import Flask, render_template, request, jsonify, Response, send_file
import cv2
import uuid
import numpy as np
from face_swap import face_swap
from moviepy.editor import VideoFileClip
app = Flask(__name__)
# Use /tmp for uploads and outputs to avoid permission errors in cloud/container
app.config['UPLOAD_FOLDER'] = '/tmp/uploads'
app.config['OUTPUT_FOLDER'] = '/tmp/outputs'
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['OUTPUT_FOLDER'], exist_ok=True)
source_face = None
anonymize = False
save_faces = False
webcam_active = False
cap = None
@app.route('/')
def landing():
return render_template('landing.html')
@app.route('/app')
def main_app():
return render_template('app.html')
@app.route('/upload-face', methods=['POST'])
def upload_face():
global source_face
file = request.files['file']
path = os.path.join(app.config['UPLOAD_FOLDER'], f"face_{uuid.uuid4().hex}.jpg")
file.save(path)
source_face = cv2.imread(path)
return jsonify({'status': 'success'})
@app.route('/upload-video', methods=['POST'])
def upload_video():
global source_face
file = request.files['file']
path = os.path.join(app.config['UPLOAD_FOLDER'], f"video_{uuid.uuid4().hex}.mp4")
file.save(path)
cap = cv2.VideoCapture(path)
width, height = int(cap.get(3)), int(cap.get(4))
fps = cap.get(cv2.CAP_PROP_FPS) or 25.0
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
output_path = os.path.join(app.config['OUTPUT_FOLDER'], f"output_{uuid.uuid4().hex}.mp4")
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
result = face_swap(source_face, frame)
out.write(result)
cap.release()
out.release()
try:
original = VideoFileClip(path)
edited = VideoFileClip(output_path)
final = edited.set_audio(original.audio)
final_path = output_path.replace(".mp4", "_with_audio.mp4")
final.write_videofile(final_path, codec='libx264', audio_codec='aac')
return send_file(final_path, as_attachment=True)
except Exception as e:
print("Audio merge error:", e)
return send_file(output_path, as_attachment=True)
@app.route('/toggle-anonymize', methods=['POST'])
def toggle_anonymize():
global anonymize
anonymize = not anonymize
return jsonify({'status': 'success', 'anonymize': anonymize})
@app.route('/toggle-save-faces', methods=['POST'])
def toggle_save_faces():
global save_faces
save_faces = not save_faces
return jsonify({'status': 'success', 'save_faces': save_faces})
@app.route('/start-webcam')
def start_webcam():
global webcam_active, cap
if not webcam_active:
cap = cv2.VideoCapture(0)
webcam_active = True
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/stop-webcam')
def stop_webcam():
global webcam_active, cap
webcam_active = False
if cap:
cap.release()
return jsonify({'status': 'stopped'})
def gen_frames():
global cap, webcam_active, source_face
while webcam_active and cap.isOpened():
ret, frame = cap.read()
if not ret:
break
frame = face_swap(source_face, frame)
_, buffer = cv2.imencode('.jpg', frame)
frame_bytes = buffer.tobytes()
yield (b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
if cap:
cap.release()
if __name__ == '__main__':
app.run(debug=True)
|