商品短影片在 TikTok Shop、Shopee Video、Instagram Reels 和 YouTube Shorts 上都能帶貨,但每個商品都手工剪一條影片,商品一多就做不過來。本文在你的伺服器上用一個小巧的 Python 指令碼和 ffmpeg,把一個裝有商品圖片和簡短配音文案的資料夾做成帶 AI 配音、燒錄字幕和可選背景音樂的 9:16 豎屏成品影片,然後一次批次生成數百個商品的影片。
本文以用 Kokoro 生成 AI 配音為基礎:請先按該教程配置好 /opt/tts 和 tts.py。然後安裝中文和日文字幕所需的字型:
apt install -y ffmpeg fonts-noto-cjk
fc-list | grep -i "Noto Sans CJK" | head -3
/data/videos/LS-01/
├── 01.jpg # photos, shown in name order
├── 02.jpg
├── 03.jpg
├── script.txt # narration, one subtitle line per line
└── music.mp3 # optional background music
cat > /opt/tts/makevideo.py <<'EOF2'
import os, subprocess, sys
import soundfile as sf
W, H, FPS = 1080, 1920, 30
FONT = os.environ.get("SUB_FONT", "Noto Sans CJK SC")
os.chdir(sys.argv[1])
images = sorted(f for f in os.listdir(".") if f.lower().endswith((".jpg", ".jpeg", ".png", ".webp")))
if not images:
sys.exit("No photos found in " + os.getcwd())
per = sf.info("script.wav").duration / len(images) # each photo stays on screen for an equal share
def ffmpeg(*args):
subprocess.run(["ffmpeg", "-y", "-loglevel", "error", *args], check=True)
with open("clips.txt", "w") as lst:
for i, img in enumerate(images):
clip = f"clip{i:03d}.mp4" # photo centred on a blurred copy of itself, 9:16
ffmpeg("-loop", "1", "-t", f"{per:.3f}", "-i", img, "-filter_complex",
f"[0:v]split[a][b];[a]scale={W}:{H}:force_original_aspect_ratio=increase,crop={W}:{H},boxblur=20[bg];"
f"[b]scale={W}:{H}:force_original_aspect_ratio=decrease[fg];[bg][fg]overlay=(W-w)/2:(H-h)/2,format=yuv420p",
"-r", str(FPS), "-c:v", "libx264", "-preset", "veryfast", "-crf", "20", clip)
lst.write(f"file '{clip}'\n")
style = f"FontName={FONT},FontSize=11,Bold=1,Outline=2,Shadow=0,Alignment=2,MarginV=50"
inputs = ["-f", "concat", "-safe", "0", "-i", "clips.txt", "-i", "script.wav"]
if os.path.exists("music.mp3"): # optional background music, quietly under the voice
inputs += ["-stream_loop", "-1", "-i", "music.mp3"]
audio = "[2:a]volume=0.15[m];[1:a][m]amix=inputs=2:duration=first,loudnorm=I=-14:TP=-1.5[a]"
else:
audio = "[1:a]loudnorm=I=-14:TP=-1.5[a]"
ffmpeg(*inputs, "-filter_complex", f"[0:v]subtitles=script.srt:force_style='{style}'[v];{audio}",
"-map", "[v]", "-map", "[a]", "-c:v", "libx264", "-preset", "veryfast", "-crf", "20",
"-pix_fmt", "yuv420p", "-c:a", "aac", "-b:a", "160k", "-ar", "48000", "-ac", "2", "-shortest", "-movflags", "+faststart", "video.mp4")
for f in ["clips.txt"] + [f"clip{i:03d}.mp4" for i in range(len(images))]:
os.remove(f)
print("done:", os.path.abspath("video.mp4"))
EOF2
每張圖片在畫面中停留的時長相同,平分整段配音。圖片居中疊放在它自身經過模糊處理的全屏副本上,因此橫圖和豎圖都能鋪滿豎屏畫面。隨後指令碼會拼接各個片段,加入配音和(如果有的話)低音量的背景音樂,燒錄字幕,把響度標準化到約 -14 LUFS,最後輸出 video.mp4。
cd /data/videos/LS-01
TTS_LANG=z TTS_VOICE=zf_xiaobei /opt/tts/bin/python /opt/tts/tts.py script.txt
/opt/tts/bin/python /opt/tts/makevideo.py /data/videos/LS-01
生成的是 1080x1920、30 fps 的 H.264 影片,音訊為 AAC,各大短影片平台都支援這種格式。字幕位於畫面底部稍上方,避開了大多數平台的按鈕區域。如需日文字幕,請在執行第二條命令時加上 SUB_FONT="Noto Sans CJK JP"。要調整字幕大小或位置,請修改指令碼中 style 這一行的 FontSize 和 MarginV。
for d in /data/videos/*/; do
[ -f "$d/video.mp4" ] && continue # skip products that are already done
TTS_LANG=z TTS_VOICE=zf_xiaobei /opt/tts/bin/python /opt/tts/tts.py "$d/script.txt" &&
/opt/tts/bin/python /opt/tts/makevideo.py "$d" || echo "FAILED: $d"
done
耗時較長的批次任務請用 nohup 或在 screen 中執行,這樣退出登入後任務也會繼續執行。在我們的測試中,一條 16 秒的影片渲染耗時約 5 秒;大部分時間花在影片編碼上,因此多核 CPU 會有明顯幫助。
volume=0.15。可以,但影片素材需要按同樣的方式裁剪時長和縮放,這需要修改指令碼。更簡單的做法是按配音教程生成配音和 SRT 字幕,再在影片剪輯軟體中與你的影片素材合成。
翻譯 script.txt,然後換用該語言的音色執行這兩條命令。對於已有的影片,請參閱用 AI 將影片翻譯配音成其他語言。
這是缺少字型導致的。請按步驟 1 安裝 fonts-noto-cjk,並確認 fc-list 的輸出中有“Noto Sans CJK SC”。
如果按以上步驟操作後問題仍未解決,請提交工單聯絡 IMIDC 7×24 技術支援,並附上伺服器 IP、系統版本、資料夾結構和完整報錯資訊,方便工程師快速定位。