Pydub: работа с аудиофайлами в Python
Pydub - библиотека Python для простой обработки звука: она загружает аудиофайл в объект AudioSegment, с которым можно работать как с последовательностью миллисекунд. Из статьи вы узнаете, как установить pydub вместе с ffmpeg, нарезать и склеить записи, поменять громкость и формат, найти паузы и сохранить результат.

Содержание статьи
Установка pydub и ffmpeg
Сама библиотека ставится через pip одной командой. Если вы еще не работали с менеджером пакетов, загляните в руководство по pip, а для отдельного проекта удобно создать виртуальное окружение.
pip install pydubБез внешних программ pydub умеет читать и писать только WAV. Для MP3, OGG, FLAC, M4A и других форматов нужен ffmpeg (или libav), который pydub вызывает как отдельный процесс. Его ставят так:
- Windows: скачать сборку ffmpeg и добавить папку
binв переменную PATH; - macOS:
brew install ffmpeg; - Ubuntu и Debian:
sudo apt install ffmpeg.
Если ffmpeg не в PATH, путь к нему можно указать в коде через атрибут AudioSegment.converter. На Python 3.13 и новее из стандартной библиотеки удален модуль audioop, на котором построен pydub. В этом случае дополнительно установите пакет audioop-lts, иначе импорт закончится ошибкой ModuleNotFoundError.
from pydub import AudioSegment
# Явный путь к ffmpeg, если он не найден автоматически
AudioSegment.converter = r"C:\ffmpeg\bin\ffmpeg.exe"Загрузка файла и свойства AudioSegment
Основной класс библиотеки - AudioSegment. Универсальный метод from_file() принимает путь и, при необходимости, формат. Для частых форматов есть короткие варианты from_mp3(), from_wav(), from_ogg().
from pydub import AudioSegment
song = AudioSegment.from_file("track.mp3", format="mp3")
print(len(song)) # длительность в миллисекундах
print(song.duration_seconds) # длительность в секундах
print(song.channels) # 1 - моно, 2 - стерео
print(song.frame_rate) # частота дискретизации, например 44100
print(song.sample_width) # байт на сэмпл: 2 = 16 бит
print(round(song.dBFS, 1)) # средняя громкость в dBFSПараметры записи меняют методы set_frame_rate(), set_channels() и set_sample_width(). Например, для систем распознавания речи файл часто приводят к моно 16 кГц: song.set_channels(1).set_frame_rate(16000).
Объекты AudioSegment неизменяемы. Любая операция возвращает новый сегмент, поэтому результат нужно присвоить переменной, иначе изменения потеряются.
Нарезка и склейка фрагментов
Время в pydub всегда задается в миллисекундах, а срезы работают так же, как у списков и строк. Отрицательный индекс отсчитывается от конца записи.
first_10s = song[:10_000] # первые 10 секунд
last_5s = song[-5_000:] # последние 5 секунд
middle = song[60_000:90_000] # с 1:00 до 1:30Соединение записей
Оператор + между двумя сегментами ставит их друг за другом. Метод append() делает то же самое, но по умолчанию добавляет плавный переход (crossfade) длиной 100 мс, длину можно изменить параметром crossfade.
intro = AudioSegment.from_file("intro.wav")
speech = AudioSegment.from_file("speech.mp3")
pause = AudioSegment.silent(duration=1500) # 1,5 секунды тишины
episode = intro + pause + speech
smooth = intro.append(speech, crossfade=2000)Для склейки множества файлов в цикле удобно начинать с пустого сегмента AudioSegment.empty(). Список файлов можно получить через pathlib.
from pathlib import Path
result = AudioSegment.empty()
for path in sorted(Path("parts").glob("*.mp3")):
result += AudioSegment.from_file(path)
result.export("full.mp3", format="mp3")Наложение дорожек
Метод overlay() смешивает две записи: длина результата равна длине исходного сегмента. Параметр position задает момент начала в миллисекундах, а loop=True повторяет накладываемый звук до конца основной дорожки, это удобно для фоновой музыки.
voice = AudioSegment.from_file("voice.wav")
music = AudioSegment.from_file("music.mp3") - 18 # музыку делаем тише
mixed = voice.overlay(music, loop=True)
mixed.export("podcast.mp3", format="mp3")Громкость, затухание и эффекты
Громкость меняется сложением и вычитанием чисел в децибелах: song + 6 делает звук громче на 6 дБ, song - 3 тише на 3 дБ. Для точной настройки есть apply_gain(). Плавное появление и исчезновение звука задают fade_in() и fade_out(), аргумент - длительность в миллисекундах.
from pydub.effects import normalize
clip = song[:30_000].fade_in(2000).fade_out(3000)
loud = normalize(clip) # подтягивает пик к 0 dBFS с запасом 0.1 дБ
reversed_clip = clip.reverse()
repeated = clip * 3 # повтор фрагмента три разаВ модуле pydub.effects есть и другие функции: speedup() для ускорения, low_pass_filter() и high_pass_filter() для простой фильтрации частот, compress_dynamic_range() для компрессии. Эти функции доступны и как методы сегмента, например clip.speedup(playback_speed=1.5). Учтите, что speedup() ускоряет запись, вырезая короткие кусочки, поэтому при сильном ускорении слышны артефакты.
Конвертация форматов и экспорт
Метод export() сохраняет сегмент в файл. Формат задает параметр format, качество MP3 - параметр bitrate, метаданные - словарь tags. Через parameters можно передать любые дополнительные аргументы ffmpeg.
song = AudioSegment.from_file("input.mp3")
song.export("output.wav", format="wav")
song.export("output.ogg", format="ogg", codec="libvorbis")
song.export(
"output_128.mp3",
format="mp3",
bitrate="128k",
tags={"artist": "Unknown", "album": "Demo"},
)Чем отличаются основные форматы при сохранении:
| Формат | Сжатие | Нужен ffmpeg | Когда выбирать |
|---|---|---|---|
| WAV | Без сжатия | Нет | Промежуточная обработка, распознавание речи |
| MP3 | С потерями | Да | Публикация, совместимость с любыми плеерами |
| OGG | С потерями | Да | Игры и веб, меньший размер при том же качестве |
| FLAC | Без потерь | Да | Архив, когда важно качество и меньший размер, чем у WAV |
Поиск тишины и разбиение по паузам
Модуль pydub.silence помогает делить длинные записи, например лекцию или диктовку, на отдельные фразы. Функция split_on_silence() возвращает список сегментов между паузами.
from pydub.silence import split_on_silence
record = AudioSegment.from_file("lecture.mp3")
chunks = split_on_silence(
record,
min_silence_len=700, # пауза от 0,7 секунды
silence_thresh=record.dBFS - 16, # тише средней громкости на 16 дБ
keep_silence=200, # оставить по 200 мс тишины по краям
)
for i, chunk in enumerate(chunks, 1):
chunk.export(f"part_{i:03}.wav", format="wav")Порог тишины лучше считать от средней громкости конкретного файла, как в примере, а не задавать фиксированным числом: у тихой и громкой записи он сильно различается. Если нужны только координаты пауз, используйте detect_silence() или detect_nonsilent(), они возвращают пары [начало, конец] в миллисекундах.
Воспроизведение и доступ к сэмплам
Функция play() из pydub.playback проигрывает сегмент. Она работает через simpleaudio, pyaudio или утилиту ffplay, в зависимости от того, что установлено. Для записи звука с микрофона pydub не подходит, для этого есть PyAudio.
from pydub.playback import play
play(song[:5_000]) # прослушать первые 5 секунд
samples = song.get_array_of_samples() # array.array с целыми сэмплами
print(len(samples), max(samples))Метод get_array_of_samples() дает доступ к сырым данным. Для стерео сэмплы каналов идут поочередно (левый, правый). Массив легко превратить в массив NumPy и строить по нему графики или считать спектр.
Частые вопросы
Здесь собраны ошибки и вопросы, с которыми чаще всего сталкиваются при работе с pydub.
Что значит предупреждение "Couldn't find ffmpeg or avconv"?
Pydub не нашел ffmpeg в PATH. Установите ffmpeg, перезапустите терминал или IDE, чтобы обновилась переменная окружения, либо укажите путь в AudioSegment.converter. Без ffmpeg будут работать только WAV-файлы.
Почему после операции файл не изменился?
Методы возвращают новый объект, а исходный сегмент остается прежним. Пишите song = song + 5 или louder = song + 5 и экспортируйте именно новую переменную.
Как обрезать аудио по секундам, а не миллисекундам?
Умножайте секунды на 1000: song[int(12.5 * 1000):int(40 * 1000)]. Индексы среза должны быть целыми числами.
Подходит ли pydub для больших файлов?
Pydub загружает весь звук в оперативную память в несжатом виде: час стерео 44,1 кГц занимает около 600 МБ. Для очень длинных записей лучше обрабатывать файл частями или вызывать ffmpeg напрямую.
Где посмотреть полный список методов?
Все методы и параметры описаны в файле API.md в официальном репозитории pydub.