fatma812's picture
Update app.py
08ecbc4 verified
Raw
History Blame Contribute Delete
4.52 kB
import gradio as gr
import fastapi
import starlette
import pydantic
import huggingface_hub
print("GRADIO =", gr.__version__)
print("FASTAPI =", fastapi.__version__)
print("STARLETTE =", starlette.__version__)
print("PYDANTIC =", pydantic.__version__)
print("HF HUB =", huggingface_hub.__version__)
import subprocess
import os
from PIL import Image
import numpy as np
from pydub import AudioSegment
# ----------------------------
# Save audio (numpy -> mp3)
# ----------------------------
def save_audio_mp3(audio_tuple, filename):
sampling_rate, audio_data = audio_tuple
audio_bytes = np.array(audio_data, dtype=np.int16).tobytes()
audio_segment = AudioSegment(
audio_bytes,
sample_width=2,
frame_rate=sampling_rate,
channels=1
)
audio_segment.export(filename, format="mp3")
# ----------------------------
# Merge video + audio (ffmpeg)
# ----------------------------
def merge_audio_video(video_path, audio_path, output_path):
if os.path.exists(output_path):
os.remove(output_path)
cmd = [
"ffmpeg",
"-y",
"-i", video_path,
"-i", audio_path,
"-c:v", "copy",
"-c:a", "aac",
"-map", "0:v:0",
"-map", "1:a:0",
output_path
]
subprocess.run(cmd, check=True)
return output_path
# ----------------------------
# Inference function
# ----------------------------
def run_inference(input_image, input_audio):
if input_image is None:
raise gr.Error("Please upload an image.")
if input_audio is None:
raise gr.Error("Please upload audio.")
os.makedirs("sample_data", exist_ok=True)
os.makedirs("results", exist_ok=True)
# Save image
image_path = "sample_data/uploaded_image.png"
Image.fromarray(input_image.astype(np.uint8)).save(image_path)
# Save audio
audio_path = "sample_data/uploaded_audio.mp3"
save_audio_mp3(input_audio, audio_path)
# Run Wav2Lip
cmd = [
"python3",
"inference.py",
"--checkpoint_path", "checkpoints/wav2lip_gan.pth",
"--face", image_path,
"--audio", audio_path
]
result = subprocess.run(
cmd,
capture_output=True,
text=True
)
if result.returncode != 0:
# نجمع stdout و stderr لأن بعض الرسائل قد تظهر في أي منهما
error = (result.stderr or "") + (result.stdout or "")
# رسالة عدم اكتشاف الوجه
if "Face not detected!" in error or "No face detected" in error:
raise gr.Error(
"❌ No face detected. Please upload a clear front-facing image."
)
# رسالة الصوت غير الصالح
if "Mel contains nan" in error:
raise gr.Error(
"❌ Invalid audio file. Please upload another audio."
)
# أي خطأ آخر
raise gr.Error("❌ Failed to generate video.")
wav2lip_video = "results/result_voice.mp4"
if not os.path.exists(wav2lip_video):
raise gr.Error("Wav2Lip output not found!")
# merge audio + video
final_video = merge_audio_video(
wav2lip_video,
audio_path,
"results/final_output.mp4"
)
return final_video
# ----------------------------
# UI
# ----------------------------
def create_demo():
with gr.Blocks() as demo:
gr.Markdown("# 🎤 Wav2Lip Demo")
with gr.Row():
input_image = gr.Image(
type="numpy",
label="Input Image"
)
input_audio = gr.Audio(
type="numpy",
label="Input Audio"
)
output_video = gr.Video(
label="Output Video"
)
btn = gr.Button("Generate Video")
btn.click(
fn=run_inference,
inputs=[input_image, input_audio],
outputs=output_video
)
gr.Markdown("## Sample")
with gr.Row():
gr.Image(
"sample/spark.png",
label="Sample Image"
)
gr.Audio(
"sample/spark_1.1.mp3",
label="Sample Audio"
)
gr.Video(
"sample/final_output.mp4",
label="Sample Output"
)
return demo
if __name__ == "__main__":
demo = create_demo()
demo.queue()
demo.launch(show_api=True)