pydub is the most popular Python library for audio manipulation. It simplifies tasks that would require complex FFmpeg commands: format conversion, trimming, joining, normalization, and fade effects.
Installation
pip install pydub
sudo apt install ffmpeg # Ubuntu/Debian
brew install ffmpeg # macOS
Format conversion
from pydub import AudioSegment
audio = AudioSegment.from_file('song.mp3')
audio.export('song.wav', format='wav')
audio.export('song.flac', format='flac')
audio.export('song.ogg', format='ogg')
audio.export('song_128k.mp3', format='mp3', bitrate='128k')
audio.export('song_320k.mp3', format='mp3', bitrate='320k')
print(f"Duration: {len(audio)/1000:.2f}s | Channels: {audio.channels} | {audio.frame_rate} Hz")
Change sample rate and channels
audio = AudioSegment.from_file('audio.wav')
audio.set_frame_rate(44100).export('audio_44k.wav', format='wav')
audio.set_frame_rate(48000).export('audio_48k.wav', format='wav')
audio.set_channels(1).export('mono.mp3', format='mp3', bitrate='128k')
audio.set_channels(2).export('stereo.mp3', format='mp3', bitrate='128k')
audio.set_sample_width(2).export('16bit.wav', format='wav')
Trim and join
audio = AudioSegment.from_file('podcast.mp3')
segment = audio[30000:90000] # seconds 30 to 90 (in ms)
segment.export('segment.mp3', format='mp3', bitrate='192k')
p1 = AudioSegment.from_file('part1.mp3')
p2 = AudioSegment.from_file('part2.mp3')
silence = AudioSegment.silent(duration=1000)
combined = p1 + silence + p2
combined.export('combined.mp3', format='mp3', bitrate='192k')
Normalization and volume control
from pydub.effects import normalize
audio = AudioSegment.from_file('recording.wav')
audio_norm = normalize(audio)
audio_norm.export('normalized.wav', format='wav')
louder = audio + 6 # +6 dB
quieter = audio - 10 # -10 dB
def adjust_dbfs(audio, target=-14.0):
return audio + (target - audio.dBFS)
adjusted = adjust_dbfs(audio, -14.0) # Streaming standard
adjusted.export('adjusted.mp3', format='mp3', bitrate='256k')
print(f"Original: {audio.dBFS:.1f} dBFS → Adjusted: {adjusted.dBFS:.1f} dBFS")
Fades and crossfade
audio = AudioSegment.from_file('song.mp3')
with_fades = audio.fade_in(2000).fade_out(3000)
with_fades.export('with_fades.mp3', format='mp3', bitrate='320k')
song1 = AudioSegment.from_file('song1.mp3')
song2 = AudioSegment.from_file('song2.mp3')
mixed = song1.append(song2, crossfade=1000)
mixed.export('mixed.mp3', format='mp3')
Batch conversion
from pydub import AudioSegment
from pathlib import Path
import os
def convert_directory(directory, output_format='mp3', bitrate='192k'):
source = Path(directory)
audio_exts = {'.mp3', '.wav', '.flac', '.ogg', '.aac', '.m4a', '.wma', '.opus'}
ok = error = 0
for file in sorted(source.iterdir()):
if file.suffix.lower() not in audio_exts:
continue
dest = file.with_suffix(f'.{output_format}')
if dest == file:
continue
try:
audio = AudioSegment.from_file(file)
kwargs = {'format': output_format}
if output_format in ('mp3', 'ogg', 'aac'):
kwargs['bitrate'] = bitrate
audio.export(dest, **kwargs)
print(f"OK: {file.name} → {dest.name} "
f"({os.path.getsize(file)//1024}KB → {os.path.getsize(dest)//1024}KB)")
ok += 1
except Exception as e:
print(f"ERROR: {file.name}: {e}")
error += 1
print(f"\nTotal: {ok} converted, {error} errors")
convert_directory('music/', output_format='mp3', bitrate='192k')
Split on silence
from pydub.silence import split_on_silence
from pathlib import Path
audio = AudioSegment.from_file('interview.mp3')
segments = split_on_silence(
audio,
min_silence_len=1000, # minimum 1s silence
silence_thresh=-40, # silence threshold dBFS
keep_silence=200, # keep 200ms at each boundary
)
print(f"Segments: {len(segments)}")
Path('segments/').mkdir(exist_ok=True)
for i, seg in enumerate(segments, 1):
seg.export(f'segments/seg_{i:03d}.mp3', format='mp3', bitrate='192k')
Mix tracks (voice + background music)
voice = AudioSegment.from_file('voice.wav')
music = AudioSegment.from_file('background.mp3') - 15 # -15 dB
while len(music) < len(voice):
music = music + music
music = music[:len(voice)]
mixed = voice.overlay(music)
mixed.export('podcast_with_music.mp3', format='mp3', bitrate='256k')