一条科普短视频从脚本到成品需要多久?传统流程:写文案1小时、录音30分钟、找素材2小时、剪辑1小时 = 至少4.5小时。用AI辅助:35秒出片,人工只需审核把关。本文分享完整的技术架构和实现细节。


背景与动机

做自媒体短视频,最大的痛点不是创意,而是产能。一个人手动做视频,一天能产出3-5条就到极限了。但如果用AI辅助自动化呢?

我的目标很简单:输入一个选题,输出一条成片

经过反复迭代,我最终搭建了一套基于Python的AI辅助视频生产管道,从文本脚本到最终视频,大幅减少了重复性工作。AI负责配音、配图、合成,人负责选题、审核和质量把关。


整体架构

选题输入
  ↓
[脚本生成] → Markdown脚本(口播文案+字幕轨+配图指令)
  ↓
[TTS配音] → edge-tts生成音频(zh-CN-YunxiNeural男声)
  ↓
[配图生成] → Stable Diffusion逐句生成配图(SD 1.5)
  ↓
[视频合成] → ffmpeg拼接+ASS字幕+混音
  ↓
成品MP4(1080p/H.264)

核心依赖只有4个:

  • Python 3.10+:主控脚本
  • edge-tts:微软免费TTS(pip install edge-tts)
  • Stable Diffusion:AI绘图(本地部署,RTX显卡)
  • ffmpeg:音视频处理

模块一:脚本模板设计

脚本是整个管道的灵魂。我设计了一套结构化的Markdown脚本格式:

---
id: v001
title: Windows 11重大更新
duration_target: 35s
voice: zh-CN-YunxiNeural
fps: 30
resolution: 1920x1080
---

## 口播

Windows 11刚刚推送了一次重大更新。这次更新带来了全新的AI助手功能,可以直接在任务栏召唤,帮你写邮件、总结文档、甚至生成图片。

## 字幕

Windows 11重大更新 | AI助手来了

## 画面

prompt: Windows 11 desktop with AI assistant, modern UI, blue theme, 4k screenshot style

三段式结构:口播文案(TTS朗读用)+ 字幕轨(视频底部显示)+ 画面指令(SD绘图用)。

每一段口播对应一张配图和一行字幕,逐段处理。


模块二:TTS自动配音

使用微软的edge-tts,完全免费,效果接近真人:

import edge_tts
import asyncio

async def generate_voice(text: str, output_path: str, 
                         voice: str = "zh-CN-YunxiNeural"):
    """生成TTS音频"""
    communicate = edge_tts.Communicate(text, voice)
    await communicate.save(output_path)

# 使用
asyncio.run(generate_voice("Windows 11刚刚推送了一次重大更新", 
                           "audio_001.mp3"))

选择zh-CN-YunxiNeural的原因:

  • 男声,声音自然,适合科普解说
  • 免费无限制调用
  • 支持SSML调节语速和停顿
  • 输出mp3格式,ffmpeg直接可用

模块三:AI配图自动生成

对每一段口播文案,使用Stable Diffusion生成对应配图:

import requests
import base64

def generate_image(prompt: str, output_path: str, 
                   sd_url: str = "http://127.0.0.1:7860"):
    """调用本地SD API生成配图"""
    payload = {
        "prompt": f"{prompt}, high quality, detailed, 16:9 aspect ratio",
        "negative_prompt": "blurry, low quality, watermark, text",
        "width": 1920,
        "height": 1080,
        "steps": 20,
        "cfg_scale": 7,
        "sampler_name": "DPM++ 2M Karras"
    }
    
    response = requests.post(
        f"{sd_url}/sdapi/v1/txt2img", json=payload
    )
    
    if response.status_code == 200:
        img_data = base64.b64decode(response.json()["images"][0])
        with open(output_path, "wb") as f:
            f.write(img_data)
        return True
    return False

优化技巧:

  • SD 1.5模型速度快,RTX 5080下单张约2秒
  • prompt末尾加16:9 aspect ratio确保横屏比例
  • 配合negative prompt过滤低质量输出
  • 每段口播文案对应一张图,按时间线拼接

模块四:ffmpeg视频合成

这是最关键的模块,把音频、配图、字幕合成为最终视频:

import subprocess

def compose_video(clips: list, output_path: str):
    """
    将多个片段(图片+音频)合成为完整视频
    clips: [{"image": "img1.png", "audio": "aud1.mp3", "duration": 5.2}, ...]
    """
    # Step 1: 每个片段图片+音频合成为短视频
    segment_files = []
    for i, clip in enumerate(clips):
        seg_path = f"temp_seg_{i:03d}.mp4"
        cmd = [
            "ffmpeg", "-y",
            "-loop", "1", "-i", clip["image"],
            "-i", clip["audio"],
            "-c:v", "libx264", "-tune", "stillimage",
            "-c:a", "aac", "-b:a", "192k",
            "-pix_fmt", "yuv420p",
            "-t", str(clip["duration"]),
            "-shortest",
            seg_path
        ]
        subprocess.run(cmd, capture_output=True)
        segment_files.append(seg_path)
    
    # Step 2: 拼接所有片段
    concat_file = "temp_concat.txt"
    with open(concat_file, "w") as f:
        for seg in segment_files:
            f.write(f"file '{seg}'\n")
    
    cmd = [
        "ffmpeg", "-y",
        "-f", "concat", "-safe", "0",
        "-i", concat_file,
        "-c", "copy",
        "temp_no_sub.mp4"
    ]
    subprocess.run(cmd, capture_output=True)
    
    # Step 3: 叠加ASS字幕
    cmd = [
        "ffmpeg", "-y",
        "-i", "temp_no_sub.mp4",
        "-vf", f"ass=subtitle.ass",
        "-c:v", "libx264", "-preset", "fast",
        "-c:a", "copy",
        output_path
    ]
    subprocess.run(cmd, capture_output=True)

踩坑记录(重要):

  1. NVENC + ASS字幕不兼容:一开始用显卡硬编码(h264_nvenc),结果ASS字幕滤镜不支持,画面无字幕。必须改用libx264软编码。
  2. 图片loop参数:静态图片转视频必须加-loop 1,否则只有一帧。
  3. 音频时长获取:用ffprobe获取每段音频精确时长,确保画面和声音同步。

模块五:ASS字幕生成

ASS格式的字幕可以实现更丰富的样式控制:

def generate_ass(subtitles: list, output_path: str, resolution=(1920, 1080)):
    """
    生成ASS字幕文件
    subtitles: [{"start": 0.0, "end": 5.2, "text": "字幕内容"}, ...]
    """
    header = f"""[Script Info]
Title: Auto Generated Subtitles
ScriptType: v4.00+
PlayResX: {resolution[0]}
PlayResY: {resolution[1]}

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, OutlineColour, 
        BackColour, Bold, Italic, BorderStyle, Outline, Shadow, 
        Alignment, MarginL, MarginR, MarginV
Style: Default,Microsoft YaHei,72,&H00FFFFFF,&H00000000,
       &H80000000,-1,0,1,3,2,2,10,10,50

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
"""
    
    events = []
    for sub in subtitles:
        start = format_time(sub["start"])
        end = format_time(sub["end"])
        events.append(
            f"Dialogue: 0,{start},{end},Default,,0,0,0,,{sub['text']}"
        )
    
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(header + "\n".join(events))

def format_time(seconds: float) -> str:
    h = int(seconds // 3600)
    m = int((seconds % 3600) // 60)
    s = int(seconds % 60)
    ms = int((seconds % 1) * 100)
    return f"{h}:{m:02d}:{s:02d}.{ms:02d}"

主控流程

把所有模块串起来:

def produce_video(script_path: str, output_dir: str):
    """AI辅助视频生产主流程"""
    
    # 1. 解析脚本
    script = parse_script(script_path)
    
    segments = []
    for i, section in enumerate(script["sections"]):
        # 2. TTS配音
        audio_path = f"{output_dir}/audio_{i:03d}.mp3"
        asyncio.run(generate_voice(section["narration"], audio_path))
        duration = get_audio_duration(audio_path)
        
        # 3. SD配图
        image_path = f"{output_dir}/image_{i:03d}.png"
        generate_image(section["image_prompt"], image_path)
        
        # 4. 记录字幕时间
        start_time = sum(s["duration"] for s in segments)
        subtitles.append({
            "start": start_time,
            "end": start_time + duration,
            "text": section["subtitle"]
        })
        
        segments.append({
            "image": image_path,
            "audio": audio_path,
            "duration": duration
        })
    
    # 5. 生成ASS字幕
    generate_ass(subtitles, f"{output_dir}/subtitle.ass")
    
    # 6. 合成最终视频
    compose_video(segments, f"{output_dir}/final.mp4")
    
    print(f"视频生产完成: {output_dir}/final.mp4")

实际产出效果

第一条全AI生成的视频:

指标 数值
时长 38.6秒
分辨率 1920x1080
文件大小 2.9MB
编码 H.264
生产耗时 ~35秒
人工参与 脚本审核+质量把关

性能优化建议

  1. SD批处理:多张配图可以批量生成,减少模型加载开销
  2. 音频预缓存:edge-tts首次连接稍慢,可以提前生成
  3. ffmpeg硬件加速:如果不需要ASS字幕滤镜,用NVENC硬编码速度快10倍
  4. 脚本模板复用:同类型视频共用模板框架,只替换内容

未来计划

  • 接入更多TTS音色(女声、多角色对话)
  • 支持视频片段混剪(不只是静态图片)
  • 发布后数据自动追踪(阅读量/点赞/评论)
  • 基于热点自动选题(接入热搜API)
  • A/B测试不同封面和标题的数据效果

总结

这套管道的核心思路是:用AI辅助完成配音、配图、合成等重复性工作,把人的精力解放到选题、审核和策略上

技术栈很简单——Python + edge-tts + Stable Diffusion + ffmpeg,全部开源免费,一台有显卡的电脑就能跑。

如果你也在做短视频,强烈建议尝试自动化。一开始搭管道可能需要一两天,但搭好之后,你的产能会提升一个数量级。

所有代码都在本文中了,有问题欢迎评论区交流。如果觉得有用,点个赞收藏,后续我会持续更新这个系列。


关注我,获取更多AI+自动化的实战教程。下一篇文章预告:《AI内容矩阵:如何用Python高效管理并发布100篇文章》。

更多推荐