pydub es la biblioteca Python más popular para manipulación de audio. Simplifica tareas que con FFmpeg directo requerirían comandos complejos: conversión, recorte, unión, normalización y efectos de fade.
Instalación
pip install pydub
sudo apt install ffmpeg # Ubuntu/Debian
brew install ffmpeg # macOS
Conversión básica
from pydub import AudioSegment
audio = AudioSegment.from_file('cancion.mp3')
audio.export('cancion.wav', format='wav')
audio.export('cancion.flac', format='flac')
audio.export('cancion.ogg', format='ogg')
audio.export('cancion_128k.mp3', format='mp3', bitrate='128k')
audio.export('cancion_320k.mp3', format='mp3', bitrate='320k')
print(f"Duración: {len(audio)/1000:.2f}s | Canales: {audio.channels} | {audio.frame_rate} Hz")
Cambiar sample rate y canales
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')
Recortar y unir
audio = AudioSegment.from_file('podcast.mp3')
segmento = audio[30000:90000] # del segundo 30 al 90 (en ms)
segmento.export('segmento.mp3', format='mp3', bitrate='192k')
p1 = AudioSegment.from_file('parte1.mp3')
p2 = AudioSegment.from_file('parte2.mp3')
silencio = AudioSegment.silent(duration=1000)
completo = p1 + silencio + p2
completo.export('completo.mp3', format='mp3', bitrate='192k')
Normalización y volumen
from pydub.effects import normalize
audio = AudioSegment.from_file('grabacion.wav')
audio_norm = normalize(audio)
audio_norm.export('normalizado.wav', format='wav')
mas_alto = audio + 6 # +6 dB
mas_bajo = audio - 10 # -10 dB
def ajustar_dbfs(audio, objetivo=-14.0):
return audio + (objetivo - audio.dBFS)
ajustado = ajustar_dbfs(audio, -14.0) # Estándar streaming
ajustado.export('ajustado.mp3', format='mp3', bitrate='256k')
print(f"Original: {audio.dBFS:.1f} dBFS → Ajustado: {ajustado.dBFS:.1f} dBFS")
Fades y crossfade
audio = AudioSegment.from_file('cancion.mp3')
con_fades = audio.fade_in(2000).fade_out(3000)
con_fades.export('con_fades.mp3', format='mp3', bitrate='320k')
cancion1 = AudioSegment.from_file('cancion1.mp3')
cancion2 = AudioSegment.from_file('cancion2.mp3')
mezclado = cancion1.append(cancion2, crossfade=1000)
mezclado.export('mezclado.mp3', format='mp3')
Conversión masiva
from pydub import AudioSegment
from pathlib import Path
import os
def convertir_directorio(directorio, formato='mp3', bitrate='192k'):
origen = Path(directorio)
exts = {'.mp3', '.wav', '.flac', '.ogg', '.aac', '.m4a', '.wma', '.opus'}
ok = error = 0
for archivo in sorted(origen.iterdir()):
if archivo.suffix.lower() not in exts:
continue
destino = archivo.with_suffix(f'.{formato}')
if destino == archivo:
continue
try:
audio = AudioSegment.from_file(archivo)
kwargs = {'format': formato}
if formato in ('mp3', 'ogg', 'aac'):
kwargs['bitrate'] = bitrate
audio.export(destino, **kwargs)
print(f"OK: {archivo.name} → {destino.name} "
f"({os.path.getsize(archivo)//1024}KB → {os.path.getsize(destino)//1024}KB)")
ok += 1
except Exception as e:
print(f"ERROR: {archivo.name}: {e}")
error += 1
print(f"\nTotal: {ok} convertidos, {error} errores")
convertir_directorio('musica/', formato='mp3', bitrate='192k')
Dividir por silencio
from pydub.silence import split_on_silence
from pathlib import Path
audio = AudioSegment.from_file('entrevista.mp3')
segmentos = split_on_silence(
audio,
min_silence_len=1000, # silencio mínimo 1s
silence_thresh=-40, # umbral en dBFS
keep_silence=200, # mantener 200ms en cada borde
)
print(f"Segmentos: {len(segmentos)}")
Path('segmentos/').mkdir(exist_ok=True)
for i, seg in enumerate(segmentos, 1):
seg.export(f'segmentos/seg_{i:03d}.mp3', format='mp3', bitrate='192k')
Mezclar pistas (voz + música de fondo)
voz = AudioSegment.from_file('voz.wav')
musica = AudioSegment.from_file('musica.mp3') - 15 # -15 dB
while len(musica) < len(voz):
musica = musica + musica
musica = musica[:len(voz)]
mezcla = voz.overlay(musica)
mezcla.export('podcast_con_musica.mp3', format='mp3', bitrate='256k')