
简介这是一套面向内容创作者、品牌运营与电商从业者的跨平台AI短视频制作桌面端源码基于Electron与Vue 3构建兼容Windows、macOS与Linux。它解决的是批量视频产出效率低、专业剪辑门槛高的问题提供智能速成与批量合成两种模式可自动完成文案生成、语音合成、字幕添加与视频渲染适合需要日更大量视频的中小团队与个人学习者。资源包共86个文件约21.13MB以ts与vue源码为主体辅以json配置、node原生模块、scss样式及少量mp4演示素材并包含better-sqlite3多平台二进制依赖与ffmpeg、edge-tts等工具模块目录结构清晰便于二次开发与功能扩展。目前已有291人学习下载。通过阅读源码读者可掌握Electron主进程与渲染进程通信、本地SQLite存储、多语种TTS接入及视频合成流水线的实现思路是学习桌面端AI应用架构的实用参考。1. 从一条视频到一百条AI短视频工厂到底在工厂化什么一个人做短视频最耗时的从来不是创意而是把创意变成成片的那些重复动作找素材、对齐字幕、卡点、导出、换封面、再导出一遍。当账号从 1 个变成 5 个、平台从抖音扩到视频号再扩到快手剪辑软件里那条时间线就成了瓶颈。Short Video Factory 这类「AI短视频工厂」要解决的正是这件事——它把「一条视频的生产流程」抽象成可配置的流水线用跨平台桌面端承载本地跑 AI 成片和批量混剪素材和成品都留在自己硬盘上。它适合三类人手里有大量素材但产能跟不上的运营、想给客户批量交付成片的接单工作室、以及想拿源码二次开发的工程师。核心词就三个跨平台桌面端、AI成片、批量混剪。桌面端意味着不依赖浏览器算力和上传带宽批量混剪意味着一次配置能吐出几十上百条差异化视频AI成片意味着文案、配音、字幕、配乐这些环节能自动串起来。这一章先把「工厂」的边界划清楚后面几章再拆怎么落地。2. 跨平台桌面端选型为什么不是纯 Web也不是 Electron 一把梭2.1 桌面端在这类工具里的不可替代性短视频工厂的负载有三个特点重 IO读写成百上千个视频文件、重 CPU/GPU转码、抽帧、人脸/场景检测、长任务一条批量任务可能跑几十分钟。纯 Web 方案在这三点上都吃亏浏览器沙箱拿不到完整的本地文件系统权限大文件上传下载来回折腾长任务一旦刷新页面就前功尽弃。所以「跨平台桌面端」不是噱头是被负载逼出来的选择。跨平台的价值在于一套代码同时覆盖 Windows 和 macOS。剪辑和运营团队里两种系统混用是常态如果只做 WindowsMac 用户就得靠虚拟机体验直接崩。常见做法是用 Tauri 或 Electron 做壳把 UI 和本地能力文件系统、进程调用、FFmpeg打通。Tauri 用系统 WebView包体小、内存占用低Electron 自带 Chromium生态成熟、坑少。选哪个取决于你对包体和内存的敏感度以及团队对 Node 生态的熟悉程度。我一般会这样判断如果核心逻辑是 PythonAI 推理、视频处理基本都在 Python 生态那就让桌面壳只做 UI 和进程管理重活全部丢给本地 Python 服务壳通过本地 HTTP 或 stdio 通信。这样 AI 部分可以独立升级不用重新打包整个客户端。2.2 用 Tauri Python 侧车跑通最小骨架下面是一个最小可跑的骨架Tauri 负责窗口Python 侧车负责真正的视频处理。先建 Python 侧车暴露一个 HTTP 接口。# sidecar/app.py # Python 侧车接收任务参数调用 FFmpeg 做混剪 from fastapi import FastAPI from pydantic import BaseModel import subprocess, uuid, os app FastAPI() class MixTask(BaseModel): clips: list[str] # 参与混剪的素材路径列表 out_dir: str # 成品输出目录 duration: int 15 # 单条成品目标时长秒 count: int 10 # 批量生成条数 app.post(/mix) def mix(task: MixTask): os.makedirs(task.out_dir, exist_okTrue) results [] for i in range(task.count): out os.path.join(task.out_dir, f{uuid.uuid4().hex}.mp4) # 用 concat demuxer 拼接-stream_loop 控制循环补足时长 cmd [ ffmpeg, -y, -f, concat, -safe, 0, -i, list.txt, # 由 clips 动态生成的清单文件 -t, str(task.duration), -c:v, libx264, -preset, veryfast, -c:a, aac, out ] subprocess.run(cmd, checkTrue) results.append(out) return {files: results}逻辑说明侧车用 FastAPI 起一个本地服务/mix接口接收素材列表和批量参数。每条成品用独立的 UUID 命名避免覆盖。-t控制时长-preset veryfast是产能和画质的折中批量场景下比slow快好几倍。参数说明clips是素材绝对路径跨平台要注意 Windows 的反斜杠和 macOS 的正斜杠统一用os.path处理count是批量条数实际生产里建议按素材总量动态算别写死duration要和素材总时长匹配素材不够长时-stream_loop会循环但循环点太密会显得重复后面避坑章会讲。Tauri 侧只需要在启动时拉起这个侧车进程并在窗口关闭时杀掉它// src-tauri/src/main.rs 里的启动逻辑示意 // 用 std::process::Command 拉起 Python 侧车记录 pid 便于退出时清理 use std::process::Command; fn spawn_sidecar() - std::process::Child { Command::new(python) .args([sidecar/app.py]) .spawn() .expect(sidecar 启动失败) }逻辑说明桌面壳不碰视频逻辑只负责生命周期管理。侧车崩了要能重启否则用户点「开始批量」没反应会一脸懵。参数上python建议换成打包后的可执行文件路径避免用户机器没装 Python。提示侧车和壳之间的端口别写死用随机端口 启动时回传否则多开客户端会端口冲突。3. AI成片的流水线拆解文案、配音、字幕、配乐怎么串3.1 一条 AI 成片的最小流水线AI成片听起来玄拆开就是四步文案生成 → 语音合成 → 字幕对齐 → 配乐混音。真正难的不是单步而是把它们串成一条能批量跑的流水线且每一步的产物都能被下一步直接消费。文案这步常见做法是接一个大模型接口输入主题和风格输出分镜脚本。语音合成用本地 TTS 或云 TTS本地的好处是免费且离线代价是音色自然度差一截。字幕对齐是重灾区TTS 输出的音频和文本时间戳往往对不齐需要靠强制对齐forced alignment重新算每个字的起止时间。配乐则是按情绪标签从本地曲库里挑再做 ducking人声出现时压低背景音乐。3.2 字幕强制对齐的可复现实现字幕对不齐是 AI 成片最容易被吐槽的点。下面用whisper做一次强制对齐把 TTS 音频和原始文案对齐成 SRT。# pipeline/align.py # 用 whisper 对 TTS 音频做转写再和原始文案做相似度对齐 import whisper model whisper.load_model(small) # small 在中文上够用速度也还行 def align(audio_path: str, script: str, out_srt: str): result model.transcribe(audio_path, languagezh, word_timestampsTrue) lines [] idx 1 for seg in result[segments]: start, end seg[start], seg[end] text seg[text].strip() # SRT 时间格式HH:MM:SS,mmm def fmt(t): h, m, s int(t // 3600), int(t % 3600 // 60), t % 60 return f{h:02d}:{m:02d}:{s:06.3f}.replace(., ,) lines.append(f{idx}\n{fmt(start)} -- {fmt(end)}\n{text}\n) idx 1 with open(out_srt, w, encodingutf-8) as f: f.write(\n.join(lines)) return out_srt逻辑说明word_timestampsTrue是关键它让每个词都带时间戳字幕才能精确到词级。small模型是精度和速度的平衡点medium更准但慢一倍批量场景下不划算。参数说明languagezh必须显式指定否则模型可能把中文识别成日文out_srt的编码必须是 UTF-8Windows 下用 GBK 写会导致播放器乱码。如果 TTS 音频里有背景音乐转写准确率会掉建议先做一次人声分离再对齐。3.3 配乐 ducking 的参数怎么定配乐不是简单叠上去人声一出来音乐就得让路。用 FFmpeg 的sidechaincompress做 ducking# 人声轨触发背景音乐压低threshold 越低压得越狠 ffmpeg -y -i voice.wav -i bgm.mp3 \ -filter_complex [1:a][0:a]sidechaincompressthreshold0.05:ratio8:attack20:release300[bg];[0:a][bg]amixinputs2:durationfirst \ -c:a aac out.m4a逻辑说明sidechaincompress用人声轨作为触发信号人声超过阈值时把 BGM 压下去。amix再把两轨混在一起。参数说明threshold0.05表示人声能量超过 5% 就触发压缩太低会一直压、音乐几乎听不见ratio8是压缩比8:1 比较激进适合口播attack20毫秒是压缩启动速度太快会有抽气感release300毫秒是恢复速度太短音乐忽大忽小。这套参数我一般先按口播场景定音乐类内容把 ratio 降到 3 左右。4. 批量混剪的差异化策略怎么让一百条视频不像复制粘贴4.1 差异化的四个维度批量混剪最大的风险是平台判定重复。要规避就得在四个维度上做随机化素材顺序、转场方式、字幕样式、配乐。素材顺序是基础把素材池打乱后按不同组合拼接转场在淡入淡出、滑动、缩放之间随机字幕样式随机换字体、颜色、位置配乐从情绪匹配的曲库里随机挑。但随机不等于乱来。完全随机的组合可能拼出逻辑不通的视频。常见做法是给素材打标签场景、人物、情绪只在同标签内随机保证语义连贯。4.2 用配置驱动批量任务把差异化策略写成配置比硬编码在代码里灵活得多。下面是一个任务配置的结构# config/task.py # 批量混剪任务配置定义素材池、差异化维度和输出规则 TASK { clips_pool: { opening: [a1.mp4, a2.mp4, a3.mp4], # 开场素材池 body: [b1.mp4, b2.mp4, b3.mp4, b4.mp4], ending: [c1.mp4, c2.mp4], }, transition: [fade, slideleft, zoomin], # 转场候选 subtitle_style: [ {font: SourceHanSans, color: #FFFFFF, pos: bottom}, {font: AlibabaPuHuiTi, color: #FFD700, pos: center}, ], bgm_pool: [upbeat_01.mp3, calm_02.mp3], output: {count: 50, duration: 20, dir: ./out}, }逻辑说明素材按「开场/主体/结尾」分段每段独立随机保证结构完整。转场、字幕、配乐各自有候选池组合数就是各池大小的乘积50 条成品很难撞车。参数说明count是目标条数实际能生成的组合上限是各池大小的乘积配置时先算一下够不够duration要和素材总时长匹配素材不够就得靠循环或放慢后者会伤画质。4.3 生成组合并调用 FFmpeg 的调度逻辑# pipeline/batch.py # 按配置随机组合素材逐条调用 FFmpeg 渲染 import random, itertools, subprocess, os from config.task import TASK def build_one(idx: int) - str: pool TASK[clips_pool] opening random.choice(pool[opening]) body random.sample(pool[body], k2) # 主体抽 2 段 ending random.choice(pool[ending]) clips [opening] body [ending] trans random.choice(TASK[transition]) style random.choice(TASK[subtitle_style]) bgm random.choice(TASK[bgm_pool]) out os.path.join(TASK[output][dir], ffinal_{idx:03d}.mp4) # 实际渲染交给 FFmpeg这里只拼命令 cmd [ffmpeg, -y] for c in clips: cmd [-i, c] cmd [-i, bgm] # xfade 做转场subtitles 烧字幕amix 混音 filter_complex _build_filter(clips, trans, style, bgm) cmd [-filter_complex, filter_complex, -t, str(TASK[output][duration]), out] subprocess.run(cmd, checkTrue) return out def _build_filter(clips, trans, style, bgm): # 省略具体 filter 拼接核心是 xfade subtitles amix return ...逻辑说明random.sample保证主体素材不重复random.choice用于单选项。每条成品独立命名方便追溯。真实项目里_build_filter是核心要把多路输入的转场、字幕、混音串成一条 filter graph。参数说明k2是主体段数段数越多视频越长但拼接点也越多转场处理不好会卡顿idx:03d保证文件名排序正确超过 999 条要改成04d。注意批量任务一定要做并发控制。FFmpeg 本身吃满 CPU开太多进程会互相抢资源反而更慢。一般按 CPU 核心数的一半来定并发数。5. 避坑与排查批量混剪翻车的五个真实场景5.1 成品全是黑屏或只有声音现象批量跑完打开成品发现画面全黑只有音频正常。 原因素材编码不一致concat demuxer 要求所有输入的分辨率、帧率、编码格式完全一致否则拼接后解码失败。 解决拼接前统一转码一遍用-vf scale1080:1920,fps30 -c:v libx264把所有素材规整到同一规格再进拼接流程。这一步会多花时间但能省掉后面反复排查的功夫。5.2 字幕和语音差半秒现象字幕比人声慢半拍越到后面偏得越多。 原因TTS 音频的采样率和转写模型的假设采样率不一致或者音频开头有静音段没被裁掉。 解决对齐前先用ffmpeg -af silenceremove裁掉首尾静音再统一重采样到 16kHz。whisper 对 16kHz 最友好其他采样率会引入累积误差。5.3 批量任务跑到一半卡死现象前 20 条正常第 21 条开始不动CPU 占用掉到 0。 原因FFmpeg 进程僵死通常是某个素材文件损坏或路径含特殊字符空格、中文、emoji。 解决任务开始前做一次素材体检用ffprobe逐个验证可读性损坏的直接剔除并记录。路径统一用绝对路径含空格的用引号包住。调度层加超时单条超过阈值就杀掉重试。5.4 平台判定重复播放量断崖现象批量发的视频前几条有量后面全是个位数播放。 原因差异化只做了素材顺序转场、字幕、配乐全一样平台一眼看出是同一模板。 解决把差异化维度全部打开尤其是开头 3 秒必须不同。开头是平台判重的重点区域素材池里开场素材至少准备 5 个以上且画面差异要明显。5.5 导出文件巨大硬盘爆了现象跑完一批任务硬盘少了上百 G。 原因默认码率太高或者中间产物没清理。 解决成品码率按平台推荐值设竖屏 1080P 一般 6~8 Mbps 够用用-b:v 8M -maxrate 10M -bufsize 16M控制。中间产物转码临时文件、抽帧图用完即删别留在输出目录里。6. 从能跑到好用把 AI 成片接进真实工作流的两个技巧第一个技巧是给流水线加「预检」。批量任务最怕跑到一半才发现素材有问题所以正式渲染前先跑一遍 dry-run只做素材体检、组合生成、时长校验不实际编码。dry-run 通过再进正式队列。这一步能把 80% 的翻车挡在门外代价只是几十秒的检查时间。我现在的习惯是任何超过 20 条的批量任务必须先 dry-run不通过不启动。第二个技巧是把 AI 成片的结果做成可回溯的清单。每条成品对应哪个素材组合、哪个转场、哪首配乐全部写进一个 JSON 清单。这样当某条视频数据特别好或特别差时能反查是哪个变量起了作用下一批就能有针对性地调配置。没有清单批量生产就是黑匣子跑一百条也不知道哪条为什么行。# pipeline/manifest.py # 每条成品生成一条可回溯记录便于后续分析 import json, os def write_manifest(out_dir: str, records: list[dict]): path os.path.join(out_dir, manifest.json) with open(path, w, encodingutf-8) as f: json.dump(records, f, ensure_asciiFalse, indent2) return path # records 示例 # {file: final_001.mp4, clips: [a1.mp4,b2.mp4,b3.mp4,c1.mp4], # transition: fade, bgm: upbeat_01.mp3, subtitle: bottom}逻辑说明清单和成品放在同一目录迁移时一起带走。ensure_asciiFalse保证中文标签正常显示。参数说明records里的字段要和配置里的维度一一对应否则回溯时对不上。字段名建议和配置键保持一致减少心智负担。这套东西值不值得做取决于你的产能瓶颈在哪。如果一天只出三五条手动剪更快一旦到了日产几十条、还要多平台分发工厂化的收益就出来了。我踩过最大的坑是过早追求全自动结果 AI 成片的文案质量撑不起账号调性返工比手动还累。后来改成「AI 出草稿 人工过一遍开头」产能和质量的平衡才找到。希望帮到你。本文还有配套的精品资源点击获取