Podcast distribution platforms (Spotify, Apple Podcasts, Anchor/Spotify for Podcasters) all accept MP3. The recording comes out of your DAW or recorder as WAV or AIFF — uncompressed, large, and not ready to upload. This guide covers the FFmpeg command that gets your file podcast-platform-ready in one step: right bitrate, right sample rate, right metadata.
TL;DR
- Spoken word podcast: 128-192kbps is indistinguishable from 320kbps for voice
- Music-heavy or audiophile show: 320kbps
- File size reference: 60-min episode at 192kbps = ~86MB; at 128kbps = ~58MB
- Spotify requirement: MP3, 96kbps–320kbps, 44.1kHz sample rate, stereo or mono
Platform requirements cheat sheet
| Platform | Accepted formats | Recommended bitrate | Max file size |
|---|---|---|---|
| Spotify for Podcasters | MP3, M4A, WAV | 128-192kbps | 200MB/episode |
| Apple Podcasts | MP3, AAC (M4A) | 128-192kbps | No limit via RSS |
| Amazon Music | MP3 | 128kbps min | 500MB |
| iHeart Radio | MP3 | 128kbps min | — |
For maximum compatibility: MP3, 192kbps, 44.1kHz, stereo. This works on every platform without exception.
FFmpeg: complete podcast conversion command
This single command handles conversion + normalization + metadata tagging:
# Standard podcast conversion (192kbps)
ffmpeg -i episode.wav \
-acodec libmp3lame \
-b:a 192k \
-ar 44100 \
-ac 2 \
-metadata title="Episode 42: Interview with Jane Smith" \
-metadata artist="My Podcast Name" \
-metadata album="My Podcast Name" \
-metadata date="2026" \
-metadata comment="https://mypodcast.com" \
-y episode-42.mp3
# High-quality version for music podcasts (320kbps)
ffmpeg -i episode.wav \
-acodec libmp3lame -b:a 320k -ar 44100 -ac 2 \
-metadata title="Episode 42" -metadata artist="My Podcast" \
-y episode-42-320.mp3
Flag reference:
-ar 44100: 44.1kHz sample rate (CD quality, required by Spotify)-ac 2: stereo (use-ac 1for mono to halve file size on voice-only shows)-b:a 192k: constant bitrate 192kbps
Audio normalization (loudness standard EBU R128)
Spotify normalizes all podcast audio to -14 LUFS. If your episode is much louder or quieter than this, Spotify will adjust it. It's better to normalize before uploading so you hear exactly what listeners will hear.
# Two-pass loudness normalization to -16 LUFS (podcast standard)
# Pass 1: analyze
ffmpeg -i episode.wav -af loudnorm=I=-16:LRA=11:TP=-1.5:print_format=json -f null - 2>&1 | tail -12
# Pass 2: apply (use the measured_I, measured_LRA, measured_TP from pass 1)
ffmpeg -i episode.wav \
-af loudnorm=I=-16:LRA=11:TP=-1.5:measured_I=-18.2:measured_LRA=8.1:measured_TP=-2.3:linear=true \
-acodec libmp3lame -b:a 192k -ar 44100 \
episode-normalized.mp3
import subprocess
import json
import re
def normalize_and_convert(in_path: str, out_path: str, bitrate: str = "192k") -> None:
# Pass 1: get loudness stats
r1 = subprocess.run([
"ffmpeg", "-i", in_path,
"-af", "loudnorm=I=-16:LRA=11:TP=-1.5:print_format=json",
"-f", "null", "-"
], capture_output=True, text=True)
# Parse JSON from stderr
json_str = re.search(r'\{[^}]+\}', r1.stderr, re.DOTALL).group()
stats = json.loads(json_str)
# Pass 2: apply normalization + encode
subprocess.run([
"ffmpeg", "-i", in_path,
"-af", (
f"loudnorm=I=-16:LRA=11:TP=-1.5"
f":measured_I={stats['input_i']}"
f":measured_LRA={stats['input_lra']}"
f":measured_TP={stats['input_tp']}"
f":linear=true"
),
"-acodec", "libmp3lame",
"-b:a", bitrate,
"-ar", "44100",
"-y", out_path
], check=True)
normalize_and_convert("raw-episode.wav", "episode-ready.mp3")
ChangeThisFile API
# WAV to MP3 via API
curl -X POST https://changethisfile.com/v1/convert \
-H "Authorization: Bearer ctf_sk_your_key_here" \
-F "file=@episode.wav" \
-F "target=mp3" \
--output episode.mp3
import requests
from pathlib import Path
API_KEY = "ctf_sk_your_key_here"
def convert_podcast(wav_path: str, out_path: str) -> None:
with open(wav_path, "rb") as f:
resp = requests.post(
"https://changethisfile.com/v1/convert",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"file": f},
data={"target": "mp3"},
timeout=300, # allow for long episodes
)
resp.raise_for_status()
Path(out_path).write_bytes(resp.content)
print(f"Saved: {out_path} ({Path(out_path).stat().st_size // (1024*1024)}MB)")
convert_podcast("episode-42.wav", "episode-42.mp3")
Edge cases and gotchas
- AIFF source files. FFmpeg handles AIFF identically to WAV. Just change the input filename — no other flags change.
- Mono vs stereo. Voice-only podcasts can use mono (
-ac 1) to halve file size with zero audible difference. Most podcast apps display stereo waveforms, but mono sounds identical through headphones and speakers. - WAV files over 200MB. Spotify for Podcasters has a 200MB episode limit. A 90-minute raw WAV at 48kHz/24-bit can exceed this. Convert to MP3 at 128kbps for 90 minutes = ~87MB — well under the limit.
- Jingle or music in intro/outro. If you're including licensed music, keep bitrate at 192kbps minimum. 128kbps can introduce audible artifacts on complex music even though voice is fine.
- Cover art embedding. Spotify requires cover art in your RSS feed, not embedded in the MP3. You can embed it for players that show it (
-i cover.jpg -map 0:a -map 1:v -id3v2_version 3) but it's not required.
Automated episode processing script
#!/bin/bash
# Drop WAV files in ./raw/, get podcast-ready MP3s in ./ready/
INPUT_DIR="./raw"
OUTPUT_DIR="./ready"
mkdir -p "$OUTPUT_DIR"
for wav in "$INPUT_DIR"/*.wav "$INPUT_DIR"/*.aiff; do
[ -f "$wav" ] || continue
base=$(basename "${wav%.*}")
out="$OUTPUT_DIR/${base}.mp3"
echo "Processing: $wav"
ffmpeg -i "$wav" \
-acodec libmp3lame -b:a 192k -ar 44100 -ac 2 \
-y "$out" 2>/dev/null
size=$(du -h "$out" | cut -f1)
echo "Done: $out ($size)"
done
The FFmpeg one-liner gets most podcasters 90% of the way there. Add the two-pass loudnorm if your episodes sound inconsistently loud across episodes. API free tier works well for occasional episode processing without a local FFmpeg install.