使用 ffmpeg 對唇形同步輸入進行預檢(500 MB / 10 MB,使用測試檔案執行)
Pre-flight checks for lip-sync inputs with ffmpeg (500 MB / 10 MB, run on test files)
這篇操作指南示範如何建立本機檢查工具,在提交唇形同步任務前檢查影片和音訊檔案的大小及副檔名;文中列出的上限約為 500 MB 和 10 MB。工具可配合 ffprobe 檢查串流資訊,並以合成檔案進行自我測試;指南沒有提交任何唇形同步任務。
Wan-family lip-sync tools ask for a person video and a target audio track. Public tool pages list practical caps such as video up to about 500 MB (MP4/MOV) and audio up to about 10 MB with short duration limits. Uploading first and learning from a red banner wastes time. This post builds a tiny local checker—and shows how to pair it with ffprobe—using synthetic files only. No lip-sync job is submitted.
For the product door after your files pass, see AI Video Lip Sync.

Diagram made for this article.
Limits we encode
From the public tool copy (verify on the live page before you rely on a number):
- Video: clear face/mouth preferred; MP4/MOV; size on the order of 500 MB max
- Audio: speech track; common compressed formats; size on the order of 10 MB max; duration caps apply
The script below treats those size/extension rules as constants you can edit when the page changes.

Diagram made for this article from public tool copy.
The checker
VIDEO_MAX = 500 * 1024 * 1024
AUDIO_MAX = 10 * 1024 * 1024
VIDEO_EXT = {".mp4", ".mov"}
AUDIO_EXT = {".mp3", ".wav", ".aac", ".m4a", ".ogg"}
Run python3 preflight_lipsync.py --video take.mp4 --audio line.wav. Exit code is non-zero on failure so it can sit in a folder action or CI step. --self-test writes tiny synthetic files and should print OK lines.

Real self-test output on 2026-10-26. Not a model run.
Optional ffprobe companion
Size checks do not prove the mouth is visible or that the audio is mono speech. After the script passes, a human (or a separate probe) should confirm duration, resolution and track layout:
ffprobe -hide_banner -show_streams -of json take.mp4
ffprobe -hide_banner -show_streams -of json line.wav
Reject clips where the mouth leaves frame, or where music beds drown the speech you want synced.

Diagram made for this article.
Failure playbook
- Oversize video: re-encode with a milder bitrate; do not upscale.
- Oversize audio: export speech-only WAV/MP3 at talk-radio bitrates.
- Wrong extension: remux; do not rename blindly.
- Empty file: fix the export path before debugging the model.

Diagram made for this article.

Screenshot: lip-sync tool page capture 2026-10-26 Asia/Shanghai.
Document the exact limits from the page on the day you ship; constants drift.
Why not call the API here
Lip-sync quality depends on the face crop and the speech take. Publishing fake "before/after" mouths would invent results. A pre-flight script is the honest technical artefact: it fails closed on files the UI would reject anyway.
Wiring the script into a folder action
On macOS or Linux you can wrap the checker in a one-liner that refuses to open the browser until exit code 0:
python3 preflight_lipsync.py --video "$1" --audio "$2" && open "https://wan30.io/ai-lip-sync"
Replace open with xdg-open on Linux. The point is behavioural: people stop treating the upload page as the validator.
What ffprobe should make you reject
- Video duration far longer than the speech you care about (the mouth will idle or invent).
- Audio with a huge leading silence—trim before upload.
- Stereo beds where the vocal is hard-panned; bounce a centre speech track.
- Variable frame-rate webcam files that some UIs accept then process oddly—re-wrap to constant frame rate when your editor supports it.
None of these are in the size script on purpose. Size is machine-checkable; taste still needs a human.
Synthetic self-test vs real takes
--self-test only proves the script runs. Before a team adopts it, run it once on a real rejected file (oversize) and a real accepted pair, and paste both transcripts into the repo README. That anchors the constants to lived UI behaviour on a dated page capture.
Security note
The script reads local files only. Do not point it at production customer media inside a shared CI cache without retention rules. Lip-sync inputs are often recognizable faces and voices.
Pairing with ffmpeg loudnorm (optional)
After size checks pass, some teams run a loudness pass so speech sits at a predictable level:
ffmpeg -i line.wav -af loudnorm=I=-16:TP=-1.5:LRA=11 line_norm.wav
This is optional and not required by the lip-sync UI. It simply reduces "why is this take quieter than yesterday" noise when producers A/B voices.
Changelog discipline
When the public page changes the 500 MB / 10 MB figures, bump a LIMITS_DATE constant in the script and re-run self-test. Leave the old numbers in a comment so archaeology is easy.
Operators who only remember one rule from this article should remember the checklist near the end: it is short on purpose so it fits on a sticky note next to the monitor. Long essays do not survive busy publish days; a five-line gate does. Revisit the sticky note whenever a shot fails for a reason you have already written down once.
Acceptance tests you can automate tomorrow
Beyond size, a future version of the script can shell out to ffprobe -v error -show_entries format=duration -of csv=p=0 and reject pairs where audio is more than a second longer than video without a documented hold. Start with printed warnings before you turn them into hard failures so editors learn the new rule.
Keep fixtures under code/fixtures/ with a manifest JSON listing expected OK/FAIL. New contributors run one command and see green/red without inventing files.
Finally, schedule a ten-minute review after the first accepted shot: what limit surprised you, which checklist line caught a real error, and which line you can delete because it never fires. Living checklists stay short; abandoned ones grow until nobody reads them.
Wrap-up
Validate extensions and sizes locally, probe streams, then open the lip-sync workspace. The model should see a face and a clean voice—not your first experiment with file too large.
來源:DEV Community · dev.to