# -*- coding: utf-8 -*- """命令行入口 用法: python cli.py --topic "人工智能的未来" --scenes 5 --rate 160 """ import argparse import os import sys import uuid from core.script_gen import generate_script from core.tts import text_to_speech from core.subtitle import build_srt from core.video import compose_video OUTPUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "output") def _probe_duration(path: str) -> float: from moviepy.editor import AudioFileClip clip = AudioFileClip(path) dur = clip.duration clip.close() return float(dur) def main(): parser = argparse.ArgumentParser(description="AI 全自动短视频生成器") parser.add_argument("--topic", required=True, help="视频主题") parser.add_argument("--scenes", type=int, default=5, help="场景数量(1-8)") parser.add_argument("--rate", type=int, default=160, help="配音语速") args = parser.parse_args() if args.scenes < 1 or args.scenes > 8: print("场景数需在 1-8 之间") sys.exit(1) job_id = uuid.uuid4().hex[:8] job_dir = os.path.join(OUTPUT_DIR, job_id) audio_dir = os.path.join(job_dir, "audio") os.makedirs(audio_dir, exist_ok=True) print(f"[1/4] 生成脚本...") script = generate_script(args.topic, args.scenes) for s in script: print(f" {s['index']}. {s['text']}") print(f"[2/4] 合成语音...") audio_paths, durations = [], [] for s in script: ap = os.path.join(audio_dir, f"{s['index']}.mp3") text_to_speech(s["text"], ap, rate=args.rate) audio_paths.append(ap) durations.append(_probe_duration(ap)) print(f" {ap} ({durations[-1]:.2f}s)") print(f"[3/4] 生成字幕...") srt_path = os.path.join(job_dir, "subtitle.srt") build_srt(script, durations, srt_path) print(f" {srt_path}") print(f"[4/4] 合成视频...") video_path = os.path.join(job_dir, "video.mp4") compose_video(script, audio_paths, durations, video_path) print(f"\n✅ 完成:{video_path}") if __name__ == "__main__": main()