
简介这是一套面向创作者、品牌方与电商商家的跨平台桌面端AI短视频生产工具源码基于Electron与Vue 3构建支持Windows、macOS与Linux。它解决的是高频内容输出门槛高、剪辑耗时的问题输入一句产品卖点或主题即可自动完成脚本撰写、配音、字幕、特效与渲染约30秒出片同时支持文件夹级素材导入、自动混剪、智能转场与BGM添加可24×7无人值守批量生产适用于产品营销、泛内容短视频与规模化混剪场景。资源包共68个文件约6.38MB以TypeScript源码与JSON配置为主体辅以Vue组件、Node脚本、样式与图标资源并包含electron-builder打包配置、ffmpeg与sqlite相关模块目录结构清晰便于二次开发与功能扩展。目前已有508人学习下载适合希望快速搭建本地化AI视频流水线、研究桌面端架构与批量渲染实现的开发者参考。1. 短视频工厂到底在工厂化什么从一条成片到一百条混剪的产能跃迁一条 30 秒的口播视频剪辑师从找素材、对轴、加字幕到导出熟练工也要 20 分钟。如果一天要出 50 条不同版本投放到不同账号人力成本直接压垮整个投放计划。Short Video Factory 这类 AI 短视频工厂要解决的不是「让 AI 帮你剪一条片子」而是把「一条素材变成一百条可投放成片」这件事变成流水线——输入一批原始素材和文案输出一批结构相似但画面、字幕、配音、转场各不相同的视频文件。它适合两类人手里有大量素材需要批量分发的运营团队以及想用一套源码搭出自己混剪工具链的开发者。跨平台在这里的含义很具体同一套核心逻辑要能在 Windows 做批量渲染、在 Linux 服务器上跑无人值守任务、在 macOS 上做预览调试而不是三个平台各写一套。一键成片和 AI 批量混剪工具是这条流水线上的两个工位前者负责把文案和素材合成一条基准片后者负责在基准片基础上做变量替换产出差异化版本。2. 拆解 Short Video Factory 的流水线素材、文案、渲染三层怎么串2.1 素材层原始视频、图片、音频的入库与预处理批量混剪的第一个瓶颈从来不是剪辑算法而是素材管理。我一般会把素材按「可复用片段」和「一次性素材」分开存放可复用片段指那些没有特定时间语义的 B-roll、空镜、转场素材一次性素材指口播原片、产品特写这类带明确内容指向的片段。Short Video Factory 的素材层通常做三件事统一转码到相同分辨率和帧率、按镜头切分并打标签、生成缩略图索引供后续随机抽取。统一转码这一步不能省。不同手机、相机导出的素材编码格式五花八门H.264、H.265、ProRes 混在一起渲染时解码器切换会拖慢整体速度严重时直接报错。常见做法是用 FFmpeg 做一次批量归一化# 将 input 目录下所有视频统一转为 1080x1920、30fps、H.264、yuv420p # -vf 中的 scale 和 pad 保证竖屏输出不变形setsar 统一像素宽高比 for f in input/*.mp4; do ffmpeg -i $f \ -vf scale1080:1920:force_original_aspect_ratiodecrease,pad1080:1920:(ow-iw)/2:(oh-ih)/2,setsar1,fps30 \ -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p \ -c:a aac -b:a 128k -ar 44100 \ normalized/$(basename $f) done这段脚本的关键参数有三个force_original_aspect_ratiodecrease配合pad保证横屏素材放进竖屏画布时不会拉伸变形setsar1消除某些设备产生的非方形像素导致的画面比例异常-crf 23是画质和体积的平衡点批量处理时再低会显著增加渲染时间。归一化完成后用镜头检测做切分# 基于 PySceneDetect 做镜头切分输出每个片段的起止时间 from scenedetect import detect, ContentDetector scene_list detect(normalized/sample.mp4, ContentDetector(threshold27.0)) for i, (start, end) in enumerate(scene_list): print(f片段 {i}: {start.get_seconds():.2f}s - {end.get_seconds():.2f}s)threshold27.0是 ContentDetector 的默认值素材里如果有大量渐变转场需要调到 30 以上避免过切如果是快节奏卡点素材可以降到 20 左右让切分更细。切分后的片段按内容打标签标签体系不用太复杂按「景别主体情绪」三个维度就够用比如「特写产品积极」「全景人物中性」。2.2 文案层脚本结构化与变量槽位设计一键成片的核心不是把文案念出来而是把文案变成可替换的模板。我习惯把每条视频的脚本拆成固定段和变量段固定段是品牌名、产品名、行动号召这类不能改的部分变量段是场景描述、用户痛点、效果数据这类需要批量替换的部分。变量段用占位符标记比如{痛点}、{场景}、{数据}渲染时从词库中随机抽取填充。# 脚本模板与变量词库的映射结构 script_template { hook: 如果你也在为{痛点}头疼这条视频一定要看完, body: 我试过{方案A}也试过{方案B}最后发现{解决方案}才是真正管用的, cta: 评论区扣{关键词}我把{资料名}发你 } variable_pool { 痛点: [视频剪辑太慢, 素材管理混乱, 批量导出卡顿], 方案A: [手动剪辑, 外包团队], 方案B: [模板套用, 半自动工具], 解决方案: [Short Video Factory 批量混剪, AI 一键成片流水线], 关键词: [工厂, 混剪, 批量], 资料名: [配置清单, 参数手册] }这个结构的好处是变量槽位和词库解耦换一套词库就换一个投放方向脚本模板本身不用动。实际跑的时候要注意变量之间的语义一致性——如果{痛点}抽到「视频剪辑太慢」{解决方案}却抽到「AI 一键成片流水线」逻辑是通的但如果{痛点}抽到「素材管理混乱」{解决方案}还是「AI 一键成片流水线」读起来就有点跳。稳妥做法是给变量池加关联权重同一组语义的变量绑定抽取。2.3 渲染层FFmpeg 合成管线与并行调度渲染层是把素材、文案、配音、字幕合成最终视频的地方。Short Video Factory 这类工具通常用 FFmpeg 做底层合成Python 做调度。一条成片的合成流程是按脚本时间轴拼接视频片段、叠加字幕、混入配音和背景音乐、导出 MP4。import subprocess def render_video(clips, audio_path, subtitle_path, output_path): # 用 concat demuxer 拼接片段避免重新编码 with open(concat_list.txt, w) as f: for clip in clips: f.write(ffile {clip}\n) cmd [ ffmpeg, -y, -f, concat, -safe, 0, -i, concat_list.txt, -i, audio_path, -vf, fsubtitles{subtitle_path}:force_styleFontSize18,PrimaryColourHFFFFFF, -c:v, libx264, -preset, medium, -crf, 21, -c:a, aac, -b:a, 192k, -shortest, output_path ] subprocess.run(cmd, checkTrue)-f concat配合-safe 0允许拼接列表里出现绝对路径-shortest保证输出时长以最短的流为准避免音频比视频长导致黑屏拖尾。字幕样式通过force_style直接写 ASS 参数FontSize18在 1080x1920 画布上大约占屏幕高度的 3%是竖屏短视频的常见字号。并行调度方面一台 8 核机器同时跑 3 到 4 个 FFmpeg 进程比较合适再多会因为磁盘 I/O 和内存带宽成为瓶颈。可以用concurrent.futures.ProcessPoolExecutor控制并发数from concurrent.futures import ProcessPoolExecutor with ProcessPoolExecutor(max_workers4) as executor: futures [executor.submit(render_video, clips, audio, sub, out) for clips, audio, sub, out in render_tasks] for f in futures: f.result() # 逐个等待完成异常会在这里抛出max_workers4不是固定值实际要按机器配置调。判断标准很简单跑起来之后看 CPU 占用如果长期低于 70%说明并发不够如果磁盘写入队列长度持续超过 2说明并发过头了。3. 跨平台落地Windows、Linux、macOS 三端环境怎么配3.1 三端 FFmpeg 与 Python 环境的差异处理跨平台最容易被低估的坑是 FFmpeg 的编译选项差异。Windows 上从官网下载的静态编译版默认带libx264和libass但 macOS 上用 Homebrew 装的 FFmpeg 可能因为许可证原因不带某些编码器Linux 发行版仓库里的版本又可能太旧。我一般会在项目里固定一个 FFmpeg 版本三端都用同一份编译配置或者直接用imageio-ffmpeg这类 Python 包管理二进制。# 用 imageio-ffmpeg 获取跨平台一致的 FFmpeg 可执行文件路径 import imageio_ffmpeg ffmpeg_path imageio_ffmpeg.get_ffmpeg_exe() print(ffmpeg_path) # 三端返回各自平台对应的二进制路径Python 环境方面subprocess调用 FFmpeg 时 Windows 和 Unix 的路径分隔符差异要用os.path或pathlib处理不要硬编码反斜杠。文件锁行为也不同Windows 上如果 FFmpeg 进程还在写文件Python 尝试删除会直接报PermissionErrorLinux 和 macOS 则允许删除正在写入的文件。批量渲染时如果要做失败重试和临时文件清理必须加进程退出检测。3.2 用 Docker 统一渲染环境的最小配置如果不想在三端分别配环境Docker 是最省事的方案。基础镜像选python:3.11-slim装 FFmpeg 和字体把项目代码挂载进去。FROM python:3.11-slim RUN apt-get update apt-get install -y \ ffmpeg \ fonts-noto-cjk \ rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD [python, factory.py, --input, /data/input, --output, /data/output]fonts-noto-cjk是必须装的否则字幕里的中文会渲染成方块。Windows 上跑 Docker 需要 WSL2 后端macOS 上 Docker Desktop 的性能损耗在批量渲染场景下大约 10% 到 15%如果追求极致速度还是建议原生环境。Linux 服务器上直接跑 Docker 没有额外损耗是部署批量任务的首选。3.3 批量任务的目录约定与断点续跑批量混剪最怕跑到一半崩了重新跑一遍浪费几小时。我习惯在输出目录里放一个progress.json每完成一条就更新一次状态。import json import os def load_progress(progress_file): if os.path.exists(progress_file): with open(progress_file, r) as f: return json.load(f) return {completed: [], failed: []} def save_progress(progress_file, progress): with open(progress_file, w) as f: json.dump(progress, f, ensure_asciiFalse, indent2)启动时先读progress.json跳过completed列表里已经完成的条目。failed列表单独记录失败原因方便排查是素材问题还是参数问题。这个机制在跨平台场景下尤其重要因为不同平台的失败模式不一样——Windows 上常见的是文件占用Linux 上常见的是权限和磁盘满macOS 上常见的是字体缺失。4. 避坑与排查批量混剪翻车的五个典型场景4.1 现象渲染到第 37 条突然卡死CPU 占用归零原因通常是某个素材文件的音频流编码异常FFmpeg 在解码时进入死循环。Short Video Factory 这类工具如果没做超时控制整个进程会一直挂在那里。解决办法是在subprocess.run里加timeout参数try: subprocess.run(cmd, checkTrue, timeout300) except subprocess.TimeoutExpired: print(f渲染超时: {output_path}) # 记录到 failed 列表继续下一条timeout300是单条视频 5 分钟上限按素材总时长调整一般设为预期渲染时间的 3 倍。4.2 现象字幕位置在不同平台上偏移不一致原因是 ASS 字幕的定位依赖字体度量Windows 和 Linux 上同一字体的行高计算有差异。解决方法是不要用相对定位直接用绝对坐标写 ASS 样式并且三端统一使用同一份字体文件通过fontsdir参数指定。4.3 现象批量输出到第 50 条之后速度明显变慢原因是磁盘写入缓存满了或者输出目录所在分区剩余空间不足。Linux 上用df -h看Windows 上看资源监视器的磁盘队列长度。解决办法是分批输出每 20 条换一个子目录或者把输出写到 SSD 上再同步到机械盘。4.4 现象混剪出来的视频画面跳跃前后镜头不连贯原因是素材切分粒度过粗一个片段里包含了多个镜头随机拼接时把不同场景的片段接在一起。解决办法是提高镜头检测灵敏度把threshold从 27 降到 22 左右同时给每个片段打上场景标签拼接时只从同一场景标签的片段池里抽取。4.5 现象配音和字幕对不上字幕比声音快半秒原因是音频编码有起始延迟或者字幕时间轴没有做偏移补偿。FFmpeg 的-itsoffset可以调整音频偏移# 音频延迟 0.5 秒让字幕先出现 ffmpeg -i video.mp4 -itsoffset 0.5 -i audio.aac -c:v copy -c:a aac -shortest output.mp4更稳妥的做法是在生成 ASS 字幕时就加上统一的Delay样式参数避免每次渲染都调。5. 从能跑到好用批量混剪的差异化策略与质量抽检批量混剪最容易陷入的误区是「为了差异化而差异化」——画面随机切、转场随机加、背景音乐随机换结果一百条视频看起来像一百条不同的垃圾。真正有效的差异化是在保持核心信息一致的前提下让每条视频在开头三秒、节奏点和结尾行动号召上有变化。我一般会把变量控制在三个维度开头钩子的话术变体、B-roll 素材的抽取顺序、背景音乐的情绪匹配。这三个维度组合起来一百条视频里任意两条在前 5 秒内不会出现完全相同的画面和文案组合。质量抽检不能靠人眼看一百条我习惯用脚本做自动化检查。检查项包括视频时长是否在预期范围内、音频轨道是否存在且音量不低于 -30dB、字幕文件是否非空、首帧画面是否全黑。下面这段脚本可以批量跑import subprocess import json def check_video(path): result subprocess.run([ ffprobe, -v, quiet, -print_format, json, -show_format, -show_streams, path ], capture_outputTrue, textTrue) info json.loads(result.stdout) duration float(info[format][duration]) has_audio any(s[codec_type] audio for s in info[streams]) return { duration: duration, has_audio: has_audio, valid: 25 duration 35 and has_audio }ffprobe的输出是 JSON 格式解析后可以拿到时长、流信息、码率等元数据。valid的判断条件按实际需求改比如要求时长在 25 到 35 秒之间且必须有音频轨。跑完一百条之后把validFalse的挑出来单独看通常不超过 5 条人工复核成本可以接受。最后一个习惯每次批量任务跑完我会把当次的参数配置、素材版本、输出数量写进一个run_log.json下次换素材或调参数时能快速对比是哪次改动导致了质量波动。这个习惯帮我省过好几次「明明上次跑得好好的这次怎么全糊了」的排查时间。希望帮到你。本文还有配套的精品资源点击获取