跳到正文
DEV Community· Denny Guide·· 3 小時前AI 評分49

FFmpeg 批次音訊擷取流程:2.2 秒從 20 個影片檔案擷取音訊

I Extracted the Audio From 20 Video Files in 2.2 Seconds — Here's the Batch Pipeline

AI 導讀

作者以 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%。

正文

Denny Guide

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 copy and 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

  1. -vn is the speed lever. Don't decode video you're going to discard.
  2. Sequential is fine: at 9 files/s, parallelism adds complexity for no felt gain.
  3. Keep the extracted audio, archive or delete the video — 99% of the bytes were pixels you'll never miss.

來源:DEV Community · dev.to