FFmpeg 批次音訊擷取流程:2.2 秒從 20 個影片檔案擷取音訊
I Extracted the Audio From 20 Video Files in 2.2 Seconds — Here's the Batch Pipeline
作者以 FFmpeg 8.0 建立批次流程,在 M-series MacBook 上用 2.2 秒從 20 個影片檔案擷取音訊,並以 `-vn` 跳過大部分影片解碼。測試中的 20 段各 30 秒、720p H.264 + AAC 影片共 240.8 MB,轉成 MP3 q=4 後為 2.4 MB,體積減少 99%。
I help maintain a small archive of recorded meetings and talks. The videos are useful, but
nobody re-watches a 40-minute recording to find one decision. What people actually want is
the audio — to listen on the go, or to feed into a transcription tool.
So I built a tiny batch pipeline that rips the audio track out of every video in a folder
and throws the video away. Here's what surprised me: for pure audio extraction, the whole
job is I/O-bound on your disk, not CPU-bound on your codec.
The one-liner that does all the work
for f in *.mp4; do
ffmpeg -y -i "$f" -vn -c:a libmp3lame -q:a 4 "out/${f%.mp4}.mp3"
done
Two flags matter more than they look:
-
-vn— drop the video stream entirely. FFmpeg skips decoding most of the video, which is where the speed comes from. -
-c:a libmp3lame -q:a 4— re-encode to MP3 at VBR quality 4 (~165 kbps, transparent for speech). If your source audio is already AAC and you don't need MP3 specifically, use-c:a copyand it's even faster.
Real numbers from my machine
I generated 20 test videos (30 s each, 720p H.264 + AAC, 240.8 MB total) and ran the loop
on an M-series MacBook with FFmpeg 8.0:
| Metric | Result |
|---|---|
| 20 files, sequential loop | 2.2 s total |
| Throughput | ~9.3 files/s |
| Size before | 240.8 MB |
| Size after (MP3 q=4) | 2.4 MB |
That's a 99% size reduction. The MP3s are what you actually want to keep around long
term; the video only matters if someone asks for the slides.
Wrapping it in Python (for the pipeline part)
A shell loop is fine for one folder. If this runs on a schedule — new recordings land in
inbox/, processed files move to done/ — a thin Python wrapper keeps the state machine
honest:
from pathlib import Path
import subprocess, shutil
INBOX, DONE, OUT = Path("inbox"), Path("done"), Path("mp3")
for src in INBOX.glob("*.mp4"):
dst = OUT / f"{src.stem}.mp3"
subprocess.run(
["ffmpeg", "-y", "-i", str(src), "-vn",
"-c:a", "libmp3lame", "-q:a", "4", str(dst)],
check=True, capture_output=True,
)
shutil.move(str(src), DONE / src.name)
print(f"{src.name} -> {dst} ({dst.stat().st_size // 1024} KB)")
check=True means a corrupt file stops the batch instead of silently producing an empty
MP3 — which matters when the next stage is a transcription API billing you by the minute.
When I don't reach for FFmpeg at all
FFmpeg is the right answer for anything recurring. But for one-off files — someone sends
you a single recording and you just need the MP3 to drop into a notes app — installing a
codec stack is overkill. For those cases I use a web converter instead, e.g.
iloveconvert.com's MP4 to MP3 tool,
which handles the common formats without any local setup.
Takeaways
-
-vnis the speed lever. Don't decode video you're going to discard. - Sequential is fine: at 9 files/s, parallelism adds complexity for no felt gain.
- Keep the extracted audio, archive or delete the video — 99% of the bytes were pixels you'll never miss.
來源:DEV Community · dev.to