2024年以来,抖音、视频号等技术知识类账号呈现爆发式增长。相比真人出镜,资料剪辑类视频(将技术大会演讲、课程视频精华片段重新剪辑包装)制作门槛更低、素材获取容易、且能充分发挥个人在特定领域的知识储备优势。
本文是我在制作技术知识类短视频过程中的一套端到端技术方案的完整复盘,涵盖:素材筛选 → 语音识别 → 字幕翻译 → 竖屏转制 → 字幕烧录 → 封面设计 → 视频合并的全部环节。本文不涉及任何本地路径和敏感信息,所有工具均为公开发布的成熟开源方案,代码可直接迁移使用。
原始视频 (横屏 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 竖屏,带字幕)环节 | 工具 | 选择理由 |
|---|---|---|
视频信息分析 | ffprobe (ffmpeg内置) | 零依赖,解析元数据极快 |
视频转码/处理 | ffmpeg 8.x | 事实标准,滤镜丰富 |
语音识别 | faster-whisper (OpenAI) | CPU推理,模型小,支持VAD |
字幕烧录 | PyAV + PIL | ffmpeg无libass/drawtext时的备选方案 |
封面绘制 | PIL (Pillow) | Python图像处理标准库 |
动态封面 | ffmpeg zoompan | Ken Burns效果生成 |
在正式处理之前,先用 ffprobe 了解素材的技术参数,避免后续踩坑:
ffprobe -v quiet -show_entries \
stream=codec_name,width,height,r_frame_rate \
-of csv=p=0 input.mp4输出示例:
h264,1280,720,25/1
aac,44100,2关键字段含义:
codec_name=h264 — 视频编码,H264兼容性最好width=1280, height=720 — 720p横屏,需转竖屏r_frame_rate=25/1 — 25fps,后续合并时需统一ffprobe -v quiet -show_entries \
format=duration -of csv=p=0 input.mp4对于技术类内容,建议按以下原则选段:
原始视频时长 | 建议切分方式 | 最终成品 |
|---|---|---|
<15分钟 | 整段使用 | 1个1-3分钟短片 |
15-45分钟 | 切3-5段精华 | 3-5个独立短片 |
>45分钟 | 按主题章节切分 | 系列内容 |
选段原则:
ffprobe -v quiet -show_entries \
stream=codec_name,sample_rate,channels \
-select_streams a:0 -of csv=p=0 input.mp4确认有音频轨道(aac/mp3)后再进行语音识别。纯视频文件无法做字幕。
市面主流语音识别方案对比:
方案 | 精度 | 速度 | 部署难度 | 本地CPU |
|---|---|---|---|---|
OpenAI Whisper API | 高 | 依赖网络 | 低 | 否 |
faster-whisper | 高(接近API) | 快(int8加速) | 中 | 是 |
Whisper.cpp | 高 | 极快 | 中 | 是 |
讯飞/百度SDK | 高 | 快 | 高(需注册) | 否 |
faster-whisper 是 Whisper 的 CTranslate2 推理实现,在 CPU 上也能达到较快的转录速度,完全本地运行,无需联网,适合处理敏感技术内容。
pip install faster-whisperimport os
os.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系列芯片需设置线程数避免OOMvad_filter=True — 自动过滤纯静音片段,减少无意义字幕language — 明确指定语言可提升准确率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 — 时间范围,可只截取目标段落Whisper输出的是带时间戳的片段列表,需要进一步处理:
segments_en = [
(18.8, 22.8, "BPF stands for Berkeley Packet Filter"),
(22.8, 27.8, "It's a virtual machine that runs in the kernel"),
# ...
]
def to_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)
return f"{h}:{m:02d}:{s:02d}.{cs:02d}"ASS(Advanced SubStation Alpha)是比SRT更强大的字幕格式,支持:
对于竖屏视频,字幕通常放在画面底部居中,ASS能精确控制这一布局。
[Script Info]
Title: eBPF Subtitles
ScriptType: 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, Encoding
Style: 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, Text
Dialogue: 0,0:00:18.80,0:00:22.80,Default,,0,0,0,,BPF全称是Berkeley Packet Filter
Dialogue: 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。
对于技术类内容,翻译需要特别注意:
横屏(16:9)转竖屏(9:16)有三种常见做法:
方式 | 做法 | 优缺点 |
|---|---|---|
裁切(crop) | 直接截取中间部分 | 信息损失,不推荐 |
缩放填充(scale+pad) | 缩放后上下/左右加黑边 | 保留完整画面,推荐 |
变形拉伸 | 直接拉伸 | 严重失真,绝对禁止 |
以1280x720(16:9)转1080x1920(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 | 不要音频(后续单独处理) |
如果竖屏视频不需要单独处理,可以直接保留音频:
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大多数预编译的ffmpeg(如macOS Homebrew bottle版本)没有包含libass和drawtext滤镜:
libass — ASS/SSA字幕渲染滤镜drawtext — 文字绘制滤镜这两个滤镜是ffmpeg烧录字幕的标准方案。如果ffmpeg编译时没有启用,字幕就无法直接烧入画面。
检查方法:
ffmpeg -filters 2>/dev/null | grep -E "subtitles|drawtext|ass"无输出说明没有这两个滤镜。
PyAV是ffmpeg的Python绑定,提供了底层访问能力。结合PIL(图像处理),可以实现逐帧绘制字幕的效果。
安装:
pip install av Pillow核心流程:
PyAV解码视频帧
↓
PIL Image 绘制字幕
↓
PyAV 编码为新视频#!/usr/bin/env python3
import av
from PIL import Image, ImageDraw, ImageFont
from fractions import Fraction
# 字幕数据:(开始秒, 结束秒, 文本)
subtitles = [
(18.8, 22.8, "BPF全称是Berkeley Packet Filter"),
(22.8, 27.8, "它是一个运行在内核中的虚拟机"),
# ...
]
defget_subtitle_at(time_sec):
"""根据当前时间返回字幕文本"""
for start, end, text in subtitles:
if start <= time_sec < end:
return text
returnNone
# 字体选择(按优先级尝试)
font = None
for 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}")
break
except Exception:
pass
if font isNone:
font = ImageFont.load_default()
# 视频参数
FPS = 25
WIDTH, HEIGHT = 1080, 1920
TEXT_MARGIN = 120 # 字幕距底部距离
SUB_BOX_PADDING = 20
defdraw_subtitle(draw, text, width, height):
"""在画面底部居中绘制字幕"""
bbox = draw.textbbox((0, 0), 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=(0, 0, 0, 200)
)
# 黑色描边(4个方向偏移)
for dx in [-2, -1, 1, 2]:
for dy in [-2, -1, 1, 2]:
ifabs(dx) == abs(dy): # 对角线方向
draw.text(
(box_x + SUB_BOX_PADDING + dx,
box_y + SUB_BOX_PADDING + dy),
text, font=font, fill=(0, 0, 0)
)
# 白色主体文字
draw.text(
(box_x + SUB_BOX_PADDING, box_y + SUB_BOX_PADDING),
text, font=font, fill=(255, 255, 255)
)
# 打开输入输出
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 = WIDTH
out_video.height = HEIGHT
out_video.pix_fmt = 'yuv420p'
out_video.options = {'crf': '23', 'preset': 'fast'}
frame_idx = 0
frame_duration = 1.0 / FPS
# 逐帧处理
for packet in in_container.demux(video=0):
if packet.dts isNone:
continue
for 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 += 1
if 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!")实测数据(PyAV + PIL逐帧烧录):
优化方向:
平台 | 推荐尺寸 | 宽高比 |
|---|---|---|
抖音 | 1080×1920 | 9:16 |
视频号 | 1080×1920 | 9:16 |
B站 | 1920×1080 | 16:9 |
技术知识类账号通常采用深色科技风封面,突出专业感。
from PIL import Image, ImageDraw, ImageFont
import os
WIDTH, HEIGHT = 1080, 1920
# 创建深色背景
img = Image.new('RGB', (WIDTH, HEIGHT), color=(5, 8, 15))
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*5, 200 - i*5, WIDTH - 50 + i*5, 205 - i*5],
outline=(0, 150, 255, 100 - 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((0, 0), title, font=font_title)
title_w = bbox[2] - bbox[0]
draw.text(((WIDTH - title_w) // 2, 400), title,
font=font_title, fill=(0, 200, 255))
# 副标题
draw.text(((WIDTH - 240) // 2, 560), "内核黑科技",
font=font_sub, fill=(255, 255, 255))
draw.text(((WIDTH - 420) // 2, 640), "从BPF到eBPF的演进史",
font=font_sub, fill=(200, 200, 210))
# 分割线
draw.line([(200, 750), (WIDTH - 200, 750)],
fill=(0, 150, 255), width=2)
# 标签
tags = ["Linux内核", "网络监控", "安全追踪", "性能分析"]
tag_y = 900
for tag in tags:
bbox = draw.textbbox((0, 0), 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=(0, 100, 200)
)
draw.text(((WIDTH - tag_w) // 2, tag_y), tag,
font=font_tag, fill=(255, 255, 255))
tag_y += 90
# 保存
img.save("cover.jpg", "JPEG", quality=95)技术知识类短视频封面设计要点:
Ken Burns效果是纪录片中常见的缓慢镜头推拉技术(缓慢放大+平移),用静态图片创造出动态感。技术演讲类视频用此效果作为片头,既能抓住观众注意力,又不喧宾夺主。
方案一: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.15d=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视频合并是整个流程中最容易出问题的环节,核心原因是音视频轨道不一致:
问题 | 原因 | 解法 |
|---|---|---|
合并后只有部分有声音 | 片头无音频轨道 | 补静音音轨 |
视频长度对不上 | 帧率不同 | 重新统一编码 |
画面错位/花屏 | 分辨率不同 | 重新统一编码 |
concat报错 | 编码参数不兼容 | 用filter_complex而非copy |
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.mp4anullsrc 生成静音音频源,零成本解决片头无声问题。
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.mp4Step 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.mp4Step 4: 验证输出
ffprobe -v quiet -show_streams final_output.mp4 \
| grep -E "codec_type|codec_name|width|height|duration"正确输出应该同时包含:
codec_type=video + codec_name=h264codec_type=audio + codec_name=aac将上述所有步骤整合为一个可复用的Shell脚本:
#!/bin/bash
# video-to-short.sh — 技术视频转竖屏短视频
INPUT=$1
OUTPUT=${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"参数 | 推荐值 | 说明 |
|---|---|---|
分辨率 | 1080×1920 | 抖音/视频号竖屏标准 |
帧率 | 25fps | 与原素材一致 |
视频编码 | H264 | 兼容性最好 |
视频码率 | CRF 22-23 | 无损质量,约3-5Mbps |
音频编码 | AAC | 全平台兼容 |
音频码率 | 128kbps | 足够清晰 |
文件格式 | MP4 | 抖音/视频号首选 |
环节 | 耗时(160秒视频) |
|---|---|
音频提取 | <1秒 |
Whisper语音识别 | 30-60秒 |
字幕翻译(人工) | 视段落数而定 |
ffmpeg竖屏转制 | 20-30秒 |
PyAV字幕烧录 | 30-60秒 |
视频合并 | <5秒 |
合计 | 约2-4分钟 |
类型 | 大小 |
|---|---|
封面图 (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-2小时内就可以完成从素材评估→语音识别→字幕制作→竖屏转制→封面设计→合并输出的全流程。如果有批量素材,可以进一步将各步骤脚本化,实现半自动化流水线生产。
对于安全研究领域的朋友,还可以将这套流程与之前的LLM安全研究结合起来——用garak做内容安全探测,用Whisper做内容提取,用ffmpeg做视觉包装,形成一套AI辅助的安全内容生产管线。
本文相关技术栈:ffmpeg 8.x / faster-whisper / PyAV / Pillow / ASS字幕格式