Spaces:
Runtime error
Runtime error
| """ | |
| OutofLipSync - Lipsync Only Application | |
| Main Gradio UI module | |
| """ | |
| import os | |
| # Optimize PyTorch memory allocation to reduce fragmentation | |
| os.environ["PYTORCH_ALLOC_CONF"] = "expandable_segments:True" | |
| import logging | |
| import sys | |
| import shutil | |
| import gradio as gr | |
| import torchvision.transforms.functional as _F | |
| from processing import lipsync_with_audio_target | |
| from shared.model_manager import ModelManager | |
| logging.info("=" * 60) | |
| logging.info("APPLICATION STARTING") | |
| logging.info(f"Python version: {sys.version}") | |
| logging.info(f"Platform: {sys.platform}") | |
| logging.info(f"Working directory: {os.getcwd()}") | |
| logging.info("=" * 60) | |
| sys.modules["torchvision.transforms.functional_tensor"] = _F | |
| os.environ["PROCESSED_RESULTS"] = os.path.join(os.getcwd(), "processed_results") | |
| os.makedirs(os.environ["PROCESSED_RESULTS"], exist_ok=True) | |
| src = "/models" | |
| dst = os.path.expanduser("~/.cache/torch/hub/checkpoints") | |
| os.makedirs(dst, exist_ok=True) | |
| if os.path.exists(src): | |
| for item in os.listdir(src): | |
| src_path = os.path.join(src, item) | |
| dst_path = os.path.join(dst, item) | |
| if os.path.isfile(src_path) and not os.path.exists(dst_path): | |
| shutil.copy2(src_path, dst_path) | |
| print(f"Copied {item} to {dst}") | |
| print("Done copying checkpoints!") | |
| print("Loading LatentSync models...") | |
| manager = ModelManager.get_instance() | |
| manager.preload_latentsync_models() | |
| print("Models loaded!") | |
| css = """ | |
| #col-container { | |
| margin: 0 auto; | |
| max-width: 1400px; | |
| padding: 2rem 1rem; | |
| } | |
| .header-container { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| border-radius: 1rem; | |
| padding: 2rem; | |
| margin-bottom: 1.5rem; | |
| box-shadow: 0 4px 20px rgba(102, 126, 234, 0.3); | |
| } | |
| .header-title { | |
| color: white; | |
| margin: 0; | |
| font-size: 2.5rem; | |
| font-weight: 700; | |
| letter-spacing: -0.5px; | |
| } | |
| .header-subtitle { | |
| color: rgba(255, 255, 255, 0.9); | |
| margin: 0.5rem 0 0; | |
| font-size: 1.1rem; | |
| } | |
| .card-section { | |
| background: white; | |
| border-radius: 1rem; | |
| padding: 1.5rem; | |
| box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); | |
| border: 1px solid #e5e7eb; | |
| height: 100%; | |
| transition: all 0.3s ease; | |
| } | |
| .card-section:hover { | |
| box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12); | |
| } | |
| .section-header { | |
| color: #1f2937; | |
| font-size: 1.25rem; | |
| font-weight: 600; | |
| margin-bottom: 1rem; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| .footer-container { | |
| margin-top: 2rem; | |
| padding-top: 1.5rem; | |
| border-top: 1px solid #e5e7eb; | |
| text-align: center; | |
| color: #6b7280; | |
| font-size: 0.9rem; | |
| } | |
| .footer-link { | |
| color: #667eea; | |
| text-decoration: none; | |
| transition: color 0.2s ease; | |
| } | |
| .footer-link:hover { | |
| color: #764ba2; | |
| } | |
| """ | |
| def cleanup(request: gr.Request): | |
| sid = request.session_hash | |
| if sid: | |
| print(f"{sid} left") | |
| d1 = os.path.join(os.environ["PROCESSED_RESULTS"], sid) | |
| shutil.rmtree(d1, ignore_errors=True) | |
| def start_session(request: gr.Request): | |
| return request.session_hash | |
| with gr.Blocks(css=css) as demo: | |
| session_state = gr.State() | |
| demo.load(fn=start_session, outputs=[session_state]) | |
| with gr.Column(elem_id="col-container"): | |
| gr.HTML( | |
| """ | |
| <div class="header-container"> | |
| <h1 class="header-title">π¬ OutofLipSync</h1> | |
| <p class="header-subtitle">Lipsync video with custom audio (English only)</p> | |
| </div> | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| with gr.Group(elem_classes="card-section"): | |
| gr.HTML('<div class="section-header">πΉ Upload Video</div>') | |
| video_input = gr.Video(label="Video Source", height=400) | |
| with gr.Column(scale=1): | |
| with gr.Group(elem_classes="card-section"): | |
| gr.HTML('<div class="section-header">π΅ Upload Audio</div>') | |
| audio_input = gr.Audio( | |
| label="Target Audio (English only)", type="filepath" | |
| ) | |
| quality_level = gr.Radio( | |
| choices=["Fast", "Normal", "Medium", "Best", "Super Best"], | |
| value="Normal", | |
| label="Quality", | |
| ) | |
| lipsync_only_btn = gr.Button( | |
| "π Lipsync", variant="primary", size="lg" | |
| ) | |
| with gr.Group(elem_classes="card-section"): | |
| gr.HTML('<div class="section-header">π¬ Final Output</div>') | |
| final_video = gr.Video(label="Final Output", height=500) | |
| gr.HTML( | |
| """ | |
| <div class="footer-container"> | |
| <p>Made with β₯ by <a href="#" class="footer-link">LT Tech</a> β’ Powered by <a href="#" class="footer-link">LatentSync</a></p> | |
| <p style="margin-top: 0.5rem; font-size: 0.85rem;">Version 1.0.0</p> | |
| </div> | |
| """ | |
| ) | |
| lipsync_only_btn.click( | |
| fn=lipsync_with_audio_target, | |
| inputs=[video_input, audio_input, session_state, quality_level], | |
| outputs=[final_video], | |
| ) | |
| if __name__ == "__main__": | |
| demo.unload(cleanup) | |
| demo.queue() | |
| demo.launch(ssr_mode=False, share=True) | |