Spaces:
Sleeping
Sleeping
| # core/assembler.py | |
| """ | |
| Assembler combines video + music and optionally overlays images/text, | |
| and produces final assembled output. Uses ffmpeg for merging audio/video. | |
| Returns a dict with final path and metadata. | |
| """ | |
| import subprocess | |
| import time | |
| from pathlib import Path | |
| from typing import Dict | |
| from config import OUTPUT_DIR | |
| OUTPUT_DIR = Path(OUTPUT_DIR) | |
| OUTPUT_DIR.mkdir(parents=True, exist_ok=True) | |
| def assemble_video(video_result: Dict, music_result: Dict, out_name: str = None) -> Dict: | |
| """ | |
| video_result: dict returned from video_generator | |
| music_result: dict returned from music_generator | |
| Returns dict { "final_path":..., "duration":..., "meta":... } | |
| """ | |
| t0 = time.time() | |
| video_path = Path(video_result.get("video_path")) | |
| music_path = Path(music_result.get("music_path")) | |
| out_name = out_name or f"final_{int(time.time()*1000)}.mp4" | |
| out_path = OUTPUT_DIR / out_name | |
| # If ffmpeg is available, merge audio and video | |
| if video_path.exists() and music_path.exists(): | |
| cmd = [ | |
| "ffmpeg", "-y", | |
| "-i", str(video_path), | |
| "-i", str(music_path), | |
| "-c:v", "copy", # copy video stream | |
| "-c:a", "aac", | |
| "-shortest", | |
| str(out_path) | |
| ] | |
| try: | |
| subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) | |
| duration = video_result.get("duration", 0.0) | |
| except Exception as e: | |
| print(f"[assembler] ffmpeg merge failed: {e}. Creating placeholder final output.") | |
| with open(out_path, "wb") as f: | |
| f.write(b"") | |
| duration = 0.0 | |
| else: | |
| # If audio or video missing, create a placeholder | |
| with open(out_path, "wb") as f: | |
| f.write(b"") | |
| duration = 0.0 | |
| meta = { | |
| "video_src": str(video_path), | |
| "music_src": str(music_path), | |
| "assembled_at": time.time() - t0 | |
| } | |
| return {"final_path": str(out_path), "duration": duration, "meta": meta} | |