Spaces:
Running
Running
import os | |
import tempfile | |
import subprocess | |
import streamlit as st | |
import logging | |
# Clear Streamlit cache | |
st.cache_data.clear() | |
st.cache_resource.clear() | |
# Logging setup | |
logging.basicConfig(level=logging.INFO) | |
# Constants | |
CHECKPOINT_PATH = "checkpoints/wav2lip_gan.pth" | |
OUTPUT_VIDEO_PATH = "./results/result_voice.mp4" | |
# App config | |
st.set_page_config(page_title="Wav2Lip Lip-Sync App", layout="centered") | |
st.title("CodeHubb Lip-Sync") | |
st.write("Upload a face video and an audio file to generate a lip-synced output using the Wav2Lip model.") | |
# Upload video file | |
video_file = st.file_uploader("🎞️ Upload Video File (mp4)", type=["mp4"]) | |
# Audio file upload | |
st.markdown("---") | |
audio_file = st.file_uploader("🎵 Upload Audio File (mp3, wav)", type=["mp3", "wav"]) | |
# Expander for settings | |
with st.expander("⚙️ Advanced Settings"): | |
st.markdown(f"**Model Checkpoint:** `{CHECKPOINT_PATH}`") | |
# Determine if button should be active | |
audio_ready = audio_file is not None | |
generate_btn = st.button("🚀 Generate Lip-Synced Video", key="generate_button", disabled=not (video_file and audio_ready)) | |
# State management | |
if "processing" not in st.session_state: | |
st.session_state.processing = False | |
# Result flag | |
video_generated = False | |
if generate_btn and not st.session_state.processing: | |
st.session_state.processing = True | |
with st.spinner("Processing... This may take a few moments ⏳"): | |
with tempfile.TemporaryDirectory() as tempdir: | |
video_path = os.path.join(tempdir, video_file.name) | |
with open(video_path, "wb") as f: | |
f.write(video_file.read()) | |
audio_path = os.path.join(tempdir, audio_file.name) | |
with open(audio_path, "wb") as f: | |
f.write(audio_file.read()) | |
# Run Wav2Lip inference | |
try: | |
result = subprocess.run( | |
["python", "inference.py", | |
"--checkpoint_path", CHECKPOINT_PATH, | |
"--face", video_path, | |
"--audio", audio_path], | |
capture_output=True, | |
text=True | |
) | |
if result.returncode == 0: | |
st.success("✅ Processing complete!") | |
st.video(OUTPUT_VIDEO_PATH) | |
with open(OUTPUT_VIDEO_PATH, "rb") as f: | |
video_data = f.read() | |
video_generated = True | |
else: | |
st.error("❌ Error during processing:") | |
st.code(result.stderr, language="bash") | |
except Exception as e: | |
st.error(f"An unexpected error occurred: {e}") | |
st.session_state.processing = False | |
# Show download button only if video was successfully generated | |
if video_generated: | |
st.download_button( | |
label="⬇️ Download Lip-Synced Video", | |
data=video_data, | |
file_name="result_voice.mp4", | |
mime="video/mp4" | |
) | |