乐于分享
好东西不私藏

从技术视频到短视频:AI辅助剪辑全流程技术复盘

从技术视频到短视频:AI辅助剪辑全流程技术复盘

前言

2024年以来,抖音、视频号等技术知识类账号呈现爆发式增长。相比真人出镜,资料剪辑类视频(将技术大会演讲、课程视频精华片段重新剪辑包装)制作门槛更低、素材获取容易、且能充分发挥个人在特定领域的知识储备优势。

本文是我在制作技术知识类短视频过程中的一套端到端技术方案的完整复盘,涵盖:素材筛选 → 语音识别 → 字幕翻译 → 竖屏转制 → 字幕烧录 → 封面设计 → 视频合并的全部环节。本文不涉及任何本地路径和敏感信息,所有工具均为公开发布的成熟开源方案,代码可直接迁移使用。


一、整体技术架构

1.1 流程总览

原始视频 (横屏 16:9)    │    ▼┌─────────────────────────────────┐│  Step 1: 素材评估与片段选取     ││  ffprobe 检测分辨率/时长/编码    │└────────────────┬────────────────┘                 │    ┌────────────▼────────────┐    │  Step 2: 语音识别        │    │  faster-whisper (CPU)   │    │  输出时间戳+原文         │    └────────────┬────────────┘                 │    ┌────────────▼────────────┐    │  Step 3: 字幕制作        │    │  人工/AI翻译 + ASS时间轴  │    └────────────┬────────────┘                 │    ┌────────────▼────────────┐    │  Step 4: 竖屏转制        │    │  ffmpeg scale+pad 滤镜  │    │  16:9 → 9:16 加黑边     │    └────────────┬────────────┘                 │    ┌────────────▼────────────┐    │  Step 5: 字幕烧录        │    │  PyAV + PIL 逐帧绘制    │    │  字幕嵌入画面(非外挂)  │    └────────────┬────────────┘                 │    ┌────────────▼────────────┐    │  Step 6: 封面图制作      │    │  PIL 绘制静态封面        │    │  ffmpeg zoompan 动态化  │    └────────────┬────────────┘                 │    ┌────────────▼────────────┐    │  Step 7: 视频合并        │    │  ffmpeg concat 协议      │    │  片头 + 正片 + 音轨     │    └────────────┬────────────┘                 │              成品 MP4         (9:16 竖屏,带字幕)

1.2 工具选型说明

环节
工具
选择理由
视频信息分析
ffprobe (ffmpeg内置)
零依赖,解析元数据极快
视频转码/处理
ffmpeg 8.x
事实标准,滤镜丰富
语音识别
faster-whisper (OpenAI)
CPU推理,模型小,支持VAD
字幕烧录
PyAV + PIL
ffmpeg无libass/drawtext时的备选方案
封面绘制
PIL (Pillow)
Python图像处理标准库
动态封面
ffmpeg zoompan
Ken Burns效果生成

二、素材评估与片段选取

2.1 视频信息探测

在正式处理之前,先用 ffprobe 了解素材的技术参数,避免后续踩坑:

ffprobe -v quiet -show_entries \  stream=codec_name,width,height,r_frame_rate \  -of csv=p=0 input.mp4

输出示例:

h264,1280,720,25/1aac,44100,2

关键字段含义:

  • • codec_name=h264 — 视频编码,H264兼容性最好
  • • width=1280, height=720 — 720p横屏,需转竖屏
  • • r_frame_rate=25/1 — 25fps,后续合并时需统一

2.2 时长与内容预判

ffprobe -v quiet -show_entries \  format=duration -of csv=p=0 input.mp4

对于技术类内容,建议按以下原则选段:

原始视频时长
建议切分方式
最终成品
<15分钟
整段使用
1个1-3分钟短片
15-45分钟
切3-5段精华
3-5个独立短片
>45分钟
按主题章节切分
系列内容

选段原则:

  • • 完整性:选取概念自洽的独立段落(不选半中间截断的内容)
  • • 信息密度:优先选讲原理、讲历史、讲架构的段落
  • • 视觉辅助:优先选PPT+讲解的视频,避免纯文字墙
  • • 时长控制:单条短片控制在60-180秒最佳

2.3 音频轨道检查

ffprobe -v quiet -show_entries \  stream=codec_name,sample_rate,channels \  -select_streams a:0 -of csv=p=0 input.mp4

确认有音频轨道(aac/mp3)后再进行语音识别。纯视频文件无法做字幕。


三、语音识别:faster-whisper

3.1 为什么用 faster-whisper

市面主流语音识别方案对比:

方案
精度
速度
部署难度
本地CPU
OpenAI Whisper API
依赖网络
faster-whisper
高(接近API)
快(int8加速)
Whisper.cpp
极快
讯飞/百度SDK
高(需注册)

faster-whisper 是 Whisper 的 CTranslate2 推理实现,在 CPU 上也能达到较快的转录速度,完全本地运行,无需联网,适合处理敏感技术内容。

3.2 安装

pip install faster-whisper

3.3 语音识别代码

import osos.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"from faster_whisper import WhisperModel# 模型选择:tiny(39M) / base(74M) / small(244M) / medium(769M)# CPU推理推荐 base 或 small,精度和速度平衡model = WhisperModel("base", compute_type="int8", cpu_threads=4)segments, info = model.transcribe("input_audio.wav",    language="en",           # 源语言    vad_filter=True,         # 启用语音活动检测,过滤静音    vad_parameters=dict(min_silence_duration_ms=500))print(f"语言: {info.language}, 时长: {info.duration:.1f}s")for seg in segments:print(f"[{seg.start:.1f}s -> {seg.end:.1f}s] {seg.text.strip()}")

参数说明

  • • compute_type="int8" — 启用int8量化,大幅降低内存占用且几乎不损失精度
  • • cpu_threads=4 — macOS M系列芯片需设置线程数避免OOM
  • • vad_filter=True — 自动过滤纯静音片段,减少无意义字幕
  • • language — 明确指定语言可提升准确率

3.4 音频提取

ffmpeg将视频中的音轨单独提取为wav(16kHz单声道为Whisper最优输入):

ffmpeg -y \  -i input.mp4 \  -vn -acodec pcm_s16le \  -ar 16000 -ac 1 \  -ss 0 -t 180 \  audio_clip.wav

参数说明:

  • • -vn — 不要视频
  • • -acodec pcm_s16le — 无压缩音频,适合识别
  • • -ar 16000 -ac 1 — 16kHz单声道,Whisper最佳输入格式
  • • -ss -t — 时间范围,可只截取目标段落

3.5 识别结果处理

Whisper输出的是带时间戳的片段列表,需要进一步处理:

segments_en = [    (18.822.8"BPF stands for Berkeley Packet Filter"),    (22.827.8"It's a virtual machine that runs in the kernel"),# ...]defto_ass_time(seconds):"""将秒数转为ASS时间格式 H:MM:SS.CS"""    h = int(seconds // 3600)    m = int((seconds % 3600) // 60)    s = int(seconds % 60)    cs = int((seconds % 1) * 100)returnf"{h}:{m:02d}:{s:02d}.{cs:02d}"

四、字幕制作:ASS格式

4.1 为什么要用ASS格式

ASS(Advanced SubStation Alpha)是比SRT更强大的字幕格式,支持:

  • • 字体大小、颜色、粗细、描边
  • • 卡拉OK效果(逐字变色)
  • • 位置控制(任意坐标)
  • • 旋转、模糊等特效

对于竖屏视频,字幕通常放在画面底部居中,ASS能精确控制这一布局。

4.2 ASS文件结构

[Script Info]Title: eBPF SubtitlesScriptType: v4.00+[V4+ Styles]Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, EncodingStyle: Default,Arial,36,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,2,1,2,10,10,10,1[Events]Format: Layer, Start, End, Style, TextDialogue: 0,0:00:18.80,0:00:22.80,Default,,0,0,0,,BPF全称是Berkeley Packet FilterDialogue: 0,0:00:22.80,0:00:27.80,Default,,0,0,0,,它是一个运行在内核中的虚拟机

样式关键参数说明

参数
含义
Fontname
Arial
字体(建议使用系统内置字体)
Fontsize
36
字号,竖屏视频建议36-44
PrimaryColour
&H00FFFFFF
白色(字幕主体颜色)
OutlineColour
&H00000000
黑色(描边颜色)
Outline
2
描边宽度,2-3视觉效果好
Shadow
1
阴影偏移
Alignment
2
底部居中(竖屏视频推荐)

Alignment值含义

1=左下  2=中下  3=右下4=左中  5=正中  6=右中7=左上  8=中上  9=右上

竖屏视频字幕放底部居中,选 Alignment=2

4.3 翻译策略

对于技术类内容,翻译需要特别注意:

  1. 1. 术语一致性:建立术语表(如 BPF/eBPF/XDP/内核探针等统一译法)
  2. 2. 口语化处理:演讲内容口语化较重,翻译时适当调整为符合中文习惯的表达
  3. 3. 时间压缩:英语演讲通常语速较慢,翻译成中文后同等时间的文字量更少,无需额外压缩
  4. 4. 保留关键英文术语:常见缩写(CPU/GPU/API)保留英文,不翻译

五、竖屏转制:ffmpeg

5.1 核心思路

横屏(16:9)转竖屏(9:16)有三种常见做法:

方式
做法
优缺点
裁切

(crop)
直接截取中间部分
信息损失,不推荐
缩放填充

(scale+pad)
缩放后上下/左右加黑边
保留完整画面,推荐
变形拉伸
直接拉伸
严重失真,绝对禁止

5.2 scale+pad 加黑边方案

以1280×720(16:9)转1080×1920(9:16)为例:

原始: 1280 × 720目标: 1080 × 1920计算:- 宽度缩放到1080,高度等比 → 1080 × 607- 上下各加 (1920 - 607) / 2 = 656.5 像素的黑边

ffmpeg命令:

ffmpeg -y \  -ss 18 -t 162 \  -i input.mp4 \  -vf "scale=1080:607:force_original_aspect_ratio=decrease,\       pad=1080:1920:(ow-iw)/2:(oh-ih)/2:color=black" \  -c:v libx264 -preset fast -crf 23 \  -r 25 \  -an \  portrait_video.mp4

参数详解

参数
说明
scale=1080:607:force_original_aspect_ratio=decrease
将宽度缩放到1080,高度按比例计算(不超出原比例)
pad=1080:1920:(ow-iw)/2:(oh-ih)/2:color=black
在图像周围填充黑色区域至目标尺寸;(ow-iw)/2 正好居中
force_original_aspect_ratio=decrease
确保缩放后不超过原尺寸
-crf 23
质量参数,18-28之间推荐,23为平均质量与大小的平衡
-preset fast
编码速度与压缩率权衡:ultrafast → veryslow
-an
不要音频(后续单独处理)

5.3 音频轨道保留

如果竖屏视频不需要单独处理,可以直接保留音频:

ffmpeg -y \  -ss 18 -t 162 \  -i input.mp4 \  -vf "scale=1080:607:force_original_aspect_ratio=decrease,\       pad=1080:1920:(ow-iw)/2:(oh-ih)/2:color=black" \  -c:v libx264 -preset fast -crf 23 \  -c:a aac -b:a 128k \  -r 25 \  portrait_with_audio.mp4

六、字幕烧录:PyAV + PIL

6.1 为什么不用ffmpeg直接烧录

大多数预编译的ffmpeg(如macOS Homebrew bottle版本)没有包含libass和drawtext滤镜:

  • • libass — ASS/SSA字幕渲染滤镜
  • • drawtext — 文字绘制滤镜

这两个滤镜是ffmpeg烧录字幕的标准方案。如果ffmpeg编译时没有启用,字幕就无法直接烧入画面。

检查方法

ffmpeg -filters 2>/dev/null | grep -E "subtitles|drawtext|ass"

无输出说明没有这两个滤镜。

6.2 PyAV 方案

PyAV是ffmpeg的Python绑定,提供了底层访问能力。结合PIL(图像处理),可以实现逐帧绘制字幕的效果。

安装

pip install av Pillow

核心流程

PyAV解码视频帧    ↓PIL Image 绘制字幕    ↓PyAV 编码为新视频

6.3 完整烧录代码

#!/usr/bin/env python3import avfrom PIL import Image, ImageDraw, ImageFontfrom fractions import Fraction# 字幕数据:(开始秒, 结束秒, 文本)subtitles = [    (18.822.8"BPF全称是Berkeley Packet Filter"),    (22.827.8"它是一个运行在内核中的虚拟机"),# ...]defget_subtitle_at(time_sec):"""根据当前时间返回字幕文本"""for start, end, text in subtitles:if start <= time_sec < end:return textreturnNone# 字体选择(按优先级尝试)font = Nonefor fp in ["/System/Library/Fonts/STHeiti Light.ttc",   # macOS黑体"/System/Library/Fonts/PingFang.ttc",        # macOS苹方"/System/Library/Fonts/Hiragino Sans GB.ttc"# macOS冬青黑体"/Library/Fonts/Arial Unicode.ttf",           # 系统通用]:if os.path.exists(fp):try:            font = ImageFont.truetype(fp, 44)print(f"Font loaded: {fp}")breakexcept Exception:passif font isNone:    font = ImageFont.load_default()# 视频参数FPS = 25WIDTH, HEIGHT = 10801920TEXT_MARGIN = 120# 字幕距底部距离SUB_BOX_PADDING = 20defdraw_subtitle(draw, text, width, height):"""在画面底部居中绘制字幕"""    bbox = draw.textbbox((00), text, font=font)    text_w = bbox[2] - bbox[0]    text_h = bbox[3] - bbox[1]# 计算字幕框尺寸    box_w = text_w + SUB_BOX_PADDING * 2    box_h = text_h + SUB_BOX_PADDING * 2 + 10    box_x = (width - box_w) // 2    box_y = height - TEXT_MARGIN - box_h# 圆角黑色半透明背景    draw.rounded_rectangle(        [box_x, box_y, box_x + box_w, box_y + box_h],        radius=8, fill=(000200)    )# 黑色描边(4个方向偏移)for dx in [-2, -112]:for dy in [-2, -112]:ifabs(dx) == abs(dy):  # 对角线方向                draw.text(                    (box_x + SUB_BOX_PADDING + dx,                      box_y + SUB_BOX_PADDING + dy),                    text, font=font, fill=(000)                )# 白色主体文字    draw.text(        (box_x + SUB_BOX_PADDING, box_y + SUB_BOX_PADDING),        text, font=font, fill=(255255255)    )# 打开输入输出in_container = av.open("input_portrait.mp4")out_container = av.open("output_with_subs.mp4"'w')# 创建输出流out_video = out_container.add_stream('libx264', rate=FPS)out_video.width = WIDTHout_video.height = HEIGHTout_video.pix_fmt = 'yuv420p'out_video.options = {'crf''23''preset''fast'}frame_idx = 0frame_duration = 1.0 / FPS# 逐帧处理for packet in in_container.demux(video=0):if packet.dts isNone:continuefor frame in packet.decode():        current_time = frame_idx * frame_duration# 转PIL Image        img = frame.to_image()# 绘制字幕        sub = get_subtitle_at(current_time)if sub:            draw = ImageDraw.Draw(img)            draw_subtitle(draw, sub, WIDTH, HEIGHT)# 编码输出        out_frame = av.VideoFrame.from_image(img)        out_frame.pts = frame_idx        out_frame.dts = frame_idx        out_frame.time_base = Fraction(1, FPS)for p in out_video.encode(out_frame):            out_container.mux(p)        frame_idx += 1if frame_idx % 500 == 0:print(f"  Processed {frame_idx} frames...")# flush编码器for p in out_video.encode():    out_container.mux(p)out_container.close()in_container.close()print("Done!")

6.4 性能数据参考

实测数据(PyAV + PIL逐帧烧录):

  • • 分辨率:1080×1920
  • • 帧数:约4000帧(160秒视频)
  • • 处理时间:约30秒(macOS普通配置)
  • • 输出大小:约3MB(crf=23)

优化方向

  • • 降低字幕框刷新频率(只在字幕变化时重绘背景)
  • • 使用NumPy直接操作像素而非PIL(更底层,速度更快)
  • • 批量处理多段视频

七、封面图设计

7.1 竖屏封面尺寸

平台
推荐尺寸
宽高比
抖音
1080×1920
9:16
视频号
1080×1920
9:16
B站
1920×1080
16:9

技术知识类账号通常采用深色科技风封面,突出专业感。

7.2 PIL封面绘制代码

from PIL import Image, ImageDraw, ImageFontimport osWIDTH, HEIGHT = 10801920# 创建深色背景img = Image.new('RGB', (WIDTH, HEIGHT), color=(5815))draw = ImageDraw.Draw(img)# 垂直渐变背景for y inrange(HEIGHT):    ratio = y / HEIGHT    r = int(5 + ratio * 20)    g = int(8 + ratio * 30)    b = int(15 + ratio * 60)    draw.line([(0, y), (WIDTH, y)], fill=(r, g, b))# 装饰线条(顶部)for i inrange(3):    draw.rectangle(        [50 - i*5200 - i*5, WIDTH - 50 + i*5205 - i*5],        outline=(0150255100 - i * 25)    )# 主标题font_title = ImageFont.truetype("/System/Library/Fonts/STHeiti Light.ttc"120)font_sub = ImageFont.truetype("/System/Library/Fonts/STHeiti Light.ttc"52)font_tag = ImageFont.truetype("/System/Library/Fonts/STHeiti Light.ttc"36)# 标题文字title = "eBPF"bbox = draw.textbbox((00), title, font=font_title)title_w = bbox[2] - bbox[0]draw.text(((WIDTH - title_w) // 2400), title,          font=font_title, fill=(0200255))# 副标题draw.text(((WIDTH - 240) // 2560), "内核黑科技",          font=font_sub, fill=(255255255))draw.text(((WIDTH - 420) // 2640), "从BPF到eBPF的演进史",          font=font_sub, fill=(200200210))# 分割线draw.line([(200750), (WIDTH - 200750)],          fill=(0150255), width=2)# 标签tags = ["Linux内核""网络监控""安全追踪""性能分析"]tag_y = 900for tag in tags:    bbox = draw.textbbox((00), tag, font=font_tag)    tag_w = bbox[2] - bbox[0]    pad = 16    bx = (WIDTH // 2) - (tag_w // 2) - pad    draw.rounded_rectangle(        [bx, tag_y - pad, bx + tag_w + pad * 2, tag_y - pad + 60],        radius=8, fill=(0100200)    )    draw.text(((WIDTH - tag_w) // 2, tag_y), tag,              font=font_tag, fill=(255255255))    tag_y += 90# 保存img.save("cover.jpg""JPEG", quality=95)

7.3 封面设计原则

技术知识类短视频封面设计要点:

  1. 1. 主标题醒目:大字号、高对比度颜色,在信息流缩略图中也能看清
  2. 2. 色系统一:深蓝/深紫背景 + 青色/白色文字 = 科技感标准配色
  3. 3. 标签明确:3-5个关键词标签,帮助算法理解内容分类
  4. 4. 留白充足:上下边缘留足够空白,避免被平台UI遮挡
  5. 5. 中英文混排:技术词汇保留英文,整体视觉更专业

八、动态封面:Ken Burns效果

8.1 什么是Ken Burns

Ken Burns效果是纪录片中常见的缓慢镜头推拉技术(缓慢放大+平移),用静态图片创造出动态感。技术演讲类视频用此效果作为片头,既能抓住观众注意力,又不喧宾夺主。

8.2 生成动态封面

方案一:ffmpeg zoompan(推荐)

ffmpeg -y \  -loop 1 \  -i cover.jpg \  -vf "    scale=1200:-1,    zoompan=z='min(zoom+0.0015,1.15)':d=125:         x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)',    fps=25  " \  -t 5 \  -c:v libx264 -preset fast -crf 23 \  -pix_fmt yuv420p \  intro.mp4

参数说明:

  • • scale=1200:-1 — 放大图片分辨率便于zoom操作
  • • zoom+0.0015 — 每帧放大0.0015,从1.0到1.15
  • • d=125 — 每帧停留125帧后开始缩放
  • • x='iw/2-(iw/zoom/2)' — 始终从中心裁剪

方案二:多张封面切换

如果想用多张不同的封面图做轮播:

ffmpeg -y \  -f concat -safe 0 -i list.txt \  -vf "zoompan=z='1.0+0.005*t':d=125:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)',fps=25" \  -t 5 -c:v libx264 intro.mp4

九、视频合并:片头+正片+音轨

9.1 常见问题与解法

视频合并是整个流程中最容易出问题的环节,核心原因是音视频轨道不一致

问题
原因
解法
合并后只有部分有声音
片头无音频轨道
补静音音轨
视频长度对不上
帧率不同
重新统一编码
画面错位/花屏
分辨率不同
重新统一编码
concat报错
编码参数不兼容
用filter_complex而非copy

9.2 标准合并流程

Step 1: 确保片头有音频轨道

如果片头是纯视觉封面,需补静音音轨:

ffmpeg -y \  -i intro_video.mp4 \  -f lavfi -i "anullsrc=r=44100:cl=stereo" \  -t 5 \  -c:v copy -c:a aac -b:a 128k \  -shortest \  intro_with_audio.mp4

anullsrc 生成静音音频源,零成本解决片头无声问题。

Step 2: 统一编码两个视频

# 片头统一编码ffmpeg -y -i intro_with_audio.mp4 \  -c:v libx264 -preset fast -crf 23 \  -r 25 -pix_fmt yuv420p \  intro_u.mp4# 正片统一编码ffmpeg -y -i main_content.mp4 \  -c:v libx264 -preset fast -crf 23 \  -r 25 -pix_fmt yuv420p \  main_u.mp4

Step 3: concat合并

# 创建文件列表cat > concat_list.txt << 'EOF'file 'intro_u.mp4'file 'main_u.mp4'EOF# 合并ffmpeg -y \  -f concat -safe 0 \  -i concat_list.txt \  -c copy \  final_output.mp4

Step 4: 验证输出

ffprobe -v quiet -show_streams final_output.mp4 \  | grep -E "codec_type|codec_name|width|height|duration"

正确输出应该同时包含:

  • • codec_type=video + codec_name=h264
  • • codec_type=audio + codec_name=aac

十、完整脚本封装

将上述所有步骤整合为一个可复用的Shell脚本:

#!/bin/bash# video-to-short.sh — 技术视频转竖屏短视频INPUT=$1OUTPUT=${2:-output.mp4}SS=${3:-0}DURATION=${4:-180}echo"开始处理: $INPUT"echo"输出文件: $OUTPUT"echo"截取范围: ${SS}s - $((SS+DURATION))s"# 1. 提取音频echo"[1/6] 提取音频..."ffmpeg -y -i "$INPUT" -ss $SS -t $DURATION \  -vn -acodec pcm_s16le -ar 16000 -ac 1 \  audio.wav# 2. 语音识别 (调用Python脚本)echo"[2/6] 语音识别..."python3 whisper_transcribe.py audio.wav > subtitles.srt# 3. 翻译字幕 (调用Python脚本)echo"[3/6] 翻译字幕..."python3 translate_subtitles.py subtitles.srt subtitles_cn.ass# 4. 竖屏转制echo"[4/6] 竖屏转制..."ffmpeg -y -i "$INPUT" -ss $SS -t $DURATION \  -vf "scale=1080:607:force_original_aspect_ratio=decrease,\       pad=1080:1920:(ow-iw)/2:(oh-ih)/2:color=black" \  -c:v libx264 -preset fast -crf 23 -r 25 -an \  portrait.mp4# 5. 字幕烧录echo"[5/6] 字幕烧录..."python3 burn_subtitles.py portrait.mp4 subtitles_cn.ass portrait_sub.mp4# 6. 合并echo"[6/6] 合并..."ffmpeg -y -i portrait_sub.mp4 \  -i "$INPUT" -ss $SS -t $DURATION \  -map 0:v -map 1:a \  -c:v copy -c:a aac -b:a 128k -shortest \"$OUTPUT"echo"完成! 输出: $OUTPUT"

十一、技术指标总结

11.1 输出规格

参数
推荐值
说明
分辨率
1080×1920
抖音/视频号竖屏标准
帧率
25fps
与原素材一致
视频编码
H264
兼容性最好
视频码率
CRF 22-23
无损质量,约3-5Mbps
音频编码
AAC
全平台兼容
音频码率
128kbps
足够清晰
文件格式
MP4
抖音/视频号首选

11.2 性能参考

环节
耗时(160秒视频)
音频提取
<1秒
Whisper语音识别
30-60秒
字幕翻译(人工)
视段落数而定
ffmpeg竖屏转制
20-30秒
PyAV字幕烧录
30-60秒
视频合并
<5秒
合计 约2-4分钟

11.3 文件大小参考

类型
大小
封面图 (JPEG)
100-200KB
片头视频 (5秒)
200-500KB
正片 (160秒,竖屏+字幕)
3-5MB
最终成品 (167秒) 4-6MB

十二、常见问题排查

Q1: ffprobe显示视频有音频,但转码后没声音A: 检查是否使用了 -an 参数(禁止音频)。竖屏转制时如果不需要单独处理音频,应去掉该参数。

Q2: Whisper识别准确率低A: 尝试使用更大的模型(如 small 而非 base);确保音频是16kHz单声道;技术术语可提前建立词汇表做后处理纠正。

Q3: ffmpeg报错 “Invalid argument”A: 通常是输入文件编码参数不兼容,尝试加上 -pix_fmt yuv420p 强制统一像素格式。

Q4: 合并后画面花屏A: 两个视频的分辨率/帧率/编码参数不一致。用统一编码(不用 -c copy)重新处理两个视频后再合并。

Q5: macOS M芯片上运行Whisper崩溃A: 设置环境变量 KMP_DUPLICATE_LIB_OK=TRUE;同时设置 OMP_NUM_THREADS=1 避免多线程冲突。


结语

从技术视频素材到抖音/视频号的竖屏短视频,整个流程的核心难点有两个:

  1. 1. 字幕烧录:大多数用户的ffmpeg环境缺少libass/drawtext,PyAV+PIL方案可以无依赖地解决这一问题
  2. 2. 音视频轨道同步:片头无声、分辨率不一致、帧率不匹配是合并失败的三大原因,按本文的分步流程可以有效规避

掌握这套方案后,一个人在1-2小时内就可以完成从素材评估→语音识别→字幕制作→竖屏转制→封面设计→合并输出的全流程。如果有批量素材,可以进一步将各步骤脚本化,实现半自动化流水线生产。

对于安全研究领域的朋友,还可以将这套流程与之前的LLM安全研究结合起来——用garak做内容安全探测,用Whisper做内容提取,用ffmpeg做视觉包装,形成一套AI辅助的安全内容生产管线


本文相关技术栈:ffmpeg 8.x / faster-whisper / PyAV / Pillow / ASS字幕格式