pydub es la biblioteca de Python más popular para manipulación de audio. Simplifica tareas que con FFmpeg directo requerirían comandos complejos: conversión de formatos, recorte, unión, normalización y efectos de fade.
Instalación
pip install pydub
# pydub necesita FFmpeg instalado en el sistema
# Ubuntu/Debian
sudo apt install ffmpeg
# macOS
brew install ffmpeg
# Windows — descargar desde ffmpeg.org y añadir al PATH
Conversión de formatos
from pydub import AudioSegment
# Cargar audio (pydub detecta el formato automáticamente)
audio = AudioSegment.from_file('cancion.mp3')
# Exportar a diferentes formatos
audio.export('cancion.wav', format='wav')
audio.export('cancion.flac', format='flac')
audio.export('cancion.ogg', format='ogg')
audio.export('cancion.aac', format='aac')
# Con bitrate específico (MP3)
audio.export('cancion_128k.mp3', format='mp3', bitrate='128k')
audio.export('cancion_320k.mp3', format='mp3', bitrate='320k')
# Con parámetros de códec adicionales
audio.export('cancion.ogg', format='ogg', codec='libvorbis', bitrate='192k')
# Información del audio cargado
print(f"Duración: {len(audio) / 1000:.2f} segundos")
print(f"Canales: {audio.channels}")
print(f"Sample rate: {audio.frame_rate} Hz")
print(f"Bits por muestra: {audio.sample_width * 8}")
Cambiar sample rate y canales
from pydub import AudioSegment
audio = AudioSegment.from_file('audio.wav')
# Cambiar sample rate (resample)
audio_48k = audio.set_frame_rate(48000)
audio_44k = audio.set_frame_rate(44100)
audio_22k = audio.set_frame_rate(22050)
audio_44k.export('audio_44100.wav', format='wav')
# Convertir a mono
audio_mono = audio.set_channels(1)
audio_mono.export('audio_mono.mp3', format='mp3', bitrate='128k')
# Convertir a estéreo
audio_stereo = audio_mono.set_channels(2)
# Cambiar bit depth
audio_16bit = audio.set_sample_width(2) # 16 bits
audio_24bit = audio.set_sample_width(3) # 24 bits
audio_32bit = audio.set_sample_width(4) # 32 bits
Recortar y unir segmentos
from pydub import AudioSegment
audio = AudioSegment.from_file('podcast.mp3')
# Recortar (tiempos en milisegundos)
intro = audio[:5000] # primeros 5 segundos
final = audio[-10000:] # últimos 10 segundos
segmento = audio[30000:90000] # del segundo 30 al 90
segmento.export('segmento.mp3', format='mp3', bitrate='192k')
# Unir múltiples archivos
parte1 = AudioSegment.from_file('parte1.mp3')
parte2 = AudioSegment.from_file('parte2.mp3')
parte3 = AudioSegment.from_file('parte3.mp3')
completo = parte1 + parte2 + parte3
completo.export('completo.mp3', format='mp3', bitrate='192k')
# Insertar silencio entre partes
silencio_1s = AudioSegment.silent(duration=1000) # 1 segundo
con_pausas = parte1 + silencio_1s + parte2 + silencio_1s + parte3
con_pausas.export('con_pausas.mp3', format='mp3')
Normalización y control de volumen
from pydub import AudioSegment
from pydub.effects import normalize
audio = AudioSegment.from_file('grabacion.wav')
# Normalizar (ajustar al máximo sin clipear)
audio_norm = normalize(audio)
audio_norm.export('grabacion_norm.wav', format='wav')
# Subir/bajar volumen (en dB)
mas_alto = audio + 6 # +6 dB (el doble de amplitud)
mas_bajo = audio - 10 # -10 dB
# Ajustar a un nivel objetivo (dBFS)
def ajustar_a_dbfs(audio, objetivo_dbfs=-14.0):
"""Ajusta el volumen a un nivel objetivo en dBFS."""
diferencia = objetivo_dbfs - audio.dBFS
return audio + diferencia
audio_ajustado = ajustar_a_dbfs(audio, -14.0) # Estándar streaming (Spotify, YouTube)
audio_ajustado.export('audio_normalizado.mp3', format='mp3', bitrate='256k')
print(f"Nivel original: {audio.dBFS:.1f} dBFS")
print(f"Nivel ajustado: {audio_ajustado.dBFS:.1f} dBFS")
Efectos de fade in y fade out
from pydub import AudioSegment
audio = AudioSegment.from_file('cancion.mp3')
# Fade in al principio (2 segundos)
con_fade_in = audio.fade_in(2000)
# Fade out al final (3 segundos)
con_fade_out = audio.fade_out(3000)
# Ambos
con_fades = audio.fade_in(2000).fade_out(3000)
con_fades.export('cancion_con_fades.mp3', format='mp3', bitrate='320k')
# Crossfade entre dos canciones (1 segundo de solapamiento)
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 de un directorio
from pydub import AudioSegment
from pathlib import Path
import os
def convertir_directorio(directorio, formato_salida='mp3', bitrate='192k'):
"""Convierte todos los archivos de audio de una carpeta al formato indicado."""
origen = Path(directorio)
extensiones_audio = {'.mp3', '.wav', '.flac', '.ogg', '.aac', '.m4a', '.wma', '.opus'}
resultados = {'ok': 0, 'error': 0}
for archivo in sorted(origen.iterdir()):
if archivo.suffix.lower() not in extensiones_audio:
continue
destino = archivo.with_suffix(f'.{formato_salida}')
if destino == archivo:
continue # ya es el formato destino
try:
audio = AudioSegment.from_file(archivo)
kwargs = {'format': formato_salida}
if formato_salida in ('mp3', 'ogg', 'aac'):
kwargs['bitrate'] = bitrate
audio.export(destino, **kwargs)
tam_orig = os.path.getsize(archivo) // 1024
tam_dest = os.path.getsize(destino) // 1024
print(f"OK: {archivo.name} → {destino.name} ({tam_orig}KB → {tam_dest}KB)")
resultados['ok'] += 1
except Exception as e:
print(f"ERROR: {archivo.name}: {e}")
resultados['error'] += 1
print(f"\nTotal: {resultados['ok']} convertidos, {resultados['error']} errores")
convertir_directorio('musica/', formato_salida='mp3', bitrate='192k')
Dividir por silencio (split on silence)
from pydub import AudioSegment
from pydub.silence import split_on_silence, detect_silence
from pathlib import Path
audio = AudioSegment.from_file('entrevista_larga.mp3')
# Detectar silencios (min_silence_len en ms, silence_thresh en dBFS)
silencios = detect_silence(audio, min_silence_len=1000, silence_thresh=-40)
print(f"Silencios detectados: {len(silencios)}")
for inicio, fin in silencios[:5]:
print(f" {inicio/1000:.1f}s – {fin/1000:.1f}s")
# Dividir en segmentos eliminando silencios
segmentos = split_on_silence(
audio,
min_silence_len=1000, # silencio mínimo 1 segundo
silence_thresh=-40, # umbral de silencio en dBFS
keep_silence=200, # mantener 200ms de silencio al inicio/fin de cada segmento
)
print(f"Segmentos generados: {len(segmentos)}")
# Guardar cada segmento
Path('segmentos/').mkdir(exist_ok=True)
for i, seg in enumerate(segmentos, 1):
seg.export(f'segmentos/segmento_{i:03d}.mp3', format='mp3', bitrate='192k')
print(f" Segmento {i}: {len(seg)/1000:.1f}s")
Mezclar pistas (overlay)
from pydub import AudioSegment
# Mezclar voz con música de fondo
voz = AudioSegment.from_file('voz.wav')
musica = AudioSegment.from_file('musica_fondo.mp3')
# Bajar la música de fondo -15 dB
musica_baja = musica - 15
# Si la música es más corta, repetirla (loop)
while len(musica_baja) < len(voz):
musica_baja = musica_baja + musica_baja
# Recortar música al mismo largo que la voz
musica_baja = musica_baja[:len(voz)]
# Mezclar (overlay)
mezcla = voz.overlay(musica_baja)
mezcla.export('podcast_con_musica.mp3', format='mp3', bitrate='256k')
Conversiones relacionadas
Pares de formatos de audio más frecuentes: