async-ffmpeg
async-ffmpeg — современная, строго типизированная, production-ready асинхронная библиотека-обёртка над ffmpeg и ffprobe для Python 3.11+.
Она построена непосредственно поверх asyncio.create_subprocess_exec() без сторонних C-библиотек, без устаревших binding-ов и с нулевыми зависимостями времени выполнения (zero runtime dependencies, только стандартная библиотека Python).
Сравнение с аналогами
| Возможность | async-ffmpeg |
ffmpeg-python |
moviepy |
subprocess (ручной) |
|---|---|---|---|---|
Нативная асинхронность (asyncio) |
Да | Нет | Нет | Требует ручной реализации |
| Зависимости времени выполнения | 0 (только stdlib) | 2 | 10+ (тяжёлые) | 0 |
Строгая типизация (mypy --strict) |
100% (Zero Any) | Нет типов | Частичная | Нет |
| Парсинг прогресса в реальном времени | Да (-progress pipe:1) |
Нет | Tqdm (базовый) | Ручной парсинг |
| Безопасная остановка (Graceful Shutdown) | Да (q\n -> SIGINT) |
Нет | Нет | Нет |
| Многоуровневый API (Facade / Pipeline / Builder) | Да | Только builder | Только facade | Нет |
| Автоопределение GPU (CUDA/AMF/QSV/Toolbox) | Да | Нет | Нет | Нет |
| Поддержка современного Python 3.14+ | Да | Заброшен | Медленный | Да |
Ключевые возможности
- Полноценная асинхронность: неблокирующий запуск процессов через
asyncio.create_subprocess_exec(), контроль конкурентности черезasyncio.Semaphore. - Строгая типизация: 100% соответствие
mypy --strictиZero Any policy, frozen dataclass-модели соslots=True, маркер PEP 561 (py.typed). - Машиночитаемый прогресс: чтение и потоковый разбор протокола
-progress pipe:1(кадры, время, битрейт, скорость кодирования, процент выполнения). - Graceful Shutdown: предотвращение повреждения медиафайлов (битых заголовков MP4 / unclosed
moovatom) путём отправкиqв stdin перед отправкой системных сигналов завершения. - Трёхуровневый API:
- Facade (
FFmpegClient): готовые методы для решения 95% повседневных задач. - Pipeline (
MediaPipeline): декларативный конвейер цепочек обработки видео и аудио. - Command Builder (
FFmpegCommand): строгий конструктор аргументов CLI с контролем порядка и валидацией конфликтов.
- Facade (
- Типизированный FFprobe: детальный разбор контейнеров, видео/аудио/субтитр-потоков, глав и метаданных.
- Аппаратное ускорение: автоопределение и конфигурация NVENC, AMF, QSV, D3D11VA, VideoToolbox.
- Интеграция с
async-yt-dlp: бесшовный конвейер загрузки и последующей обработки медиафайлов.
Методы высокоуровневого клиента (FFmpegClient)
| Метод | Назначение |
|---|---|
transcode(...) |
Универсальное перекодирование с контролем кодеков, битрейта, разрешения, FPS и фильтров. |
extract_audio(...) |
Извлечение аудиодорожки (-vn) с конвертацией в AAC, MP3, FLAC, OPUS или WAV. |
trim(...) |
Быстрая обрезка медиафрагментов по меткам времени (со stream copy или перекодированием). |
concat(...) |
Склейка нескольких файлов без перекодирования (demuxer) или через граф фильтров. |
screenshot(...) |
Извлечение одного кадра в указанной временной метке в высоком качестве. |
thumbnails(...) |
Серийная генерация миниатюр по фиксированному интервалу, общему числу или частоте кадров. |
convert(...) |
Быстрая смена контейнера (remuxing, например MKV -> MP4) со stream copy. |
normalize_audio(...) |
Двухпроходная нормализация громкости по вещательному стандарту EBU R128 (loudnorm). |
scale(...) |
Масштабирование видеоряда с сохранением исходной аудиодорожки без перекодирования. |
two_pass_transcode(...) |
Двухпроходное кодирование с контролем битрейта и автоматической очисткой временных логов. |
create_contact_sheet(...) |
Сборка раскадровки (storyboard/contact sheet) в виде сетки миниатюр (tile). |
detect_silence(...) |
Детектирование тишины и пауз в аудиодорожке с получением интервалов (SilenceInterval). |
probe(...) |
Детальный анализ метаданных файла или потока с возвратом типизированного MediaInfo. |
Установка
# Базовая установка (zero external dependencies)
uv add async-ffmpeg
# Или через pip:
pip install async-ffmpeg
# С опциональной поддержкой интеграции с async-yt-dlp
pip install "async-ffmpeg[ytdlp]"
Требования:
- Python >= 3.14
- Установленный в системе
ffmpegиffprobe(вPATHили указанный через аргументы клиента / переменнуюFFMPEG_PATH)
Быстрый старт
1. Анализ медиафайла (FFprobe)
import asyncio
from async_ffmpeg import FFmpegClient
async def main() -> None:
client = FFmpegClient()
info = await client.probe("video.mp4")
print(f"Формат: {info.format.format_long_name}")
print(f"Длительность: {info.duration} сек")
if info.primary_video:
v = info.primary_video
print(f"Видео: {v.codec_name}, {v.width}x{v.height} @ {v.frame_rate:.2f} fps")
if info.primary_audio:
a = info.primary_audio
print(f"Аудио: {a.codec_name}, {a.sample_rate} Hz, каналов: {a.channels}")
asyncio.run(main())
2. Транскодирование с отслеживанием прогресса
import asyncio
from async_ffmpeg import FFmpegClient, ProgressInfo
async def main() -> None:
client = FFmpegClient()
async def on_progress(p: ProgressInfo) -> None:
print(f"Прогресс: {p.percent:.1f}% | Скорость: {p.speed} | FPS: {p.fps:.1f}")
result = await client.transcode(
input="input.mp4",
output="output_720p.mp4",
video_codec="libx264",
crf=23,
resolution=(1280, 720),
audio_codec="aac",
audio_bitrate="128k",
on_progress=on_progress,
)
print(f"Готово за {result.duration_seconds:.2f} сек!")
asyncio.run(main())
3. Декларативный конвейер (MediaPipeline)
import asyncio
from async_ffmpeg import FFmpegClient
async def main() -> None:
client = FFmpegClient()
# Цепочка: обрезка -> масштабирование -> нормализация звука -> вывод
await (
client.pipeline("input.mp4")
.trim(start=10, duration=60)
.scale(1280, 720)
.normalize_audio(target_lufs=-16.0)
.output("highlight_720p.mp4")
.run()
)
asyncio.run(main())
4. Интеграция с загрузчиком (async-yt-dlp)
import asyncio
from async_ffmpeg import FFmpegClient
from async_ffmpeg.integration import process_download_result
async def main() -> None:
# Загрузка через yt-dlp (или совместимый объект с протоколом DownloadResultProtocol)
# Предположим, результат загрузки сохранён в download_result
client = FFmpegClient()
# Автоматическое извлечение аудиодорожки или конвертация
post_result = await process_download_result(
download_result,
action="extract_audio",
client=client,
audio_format="mp3",
audio_bitrate="320k",
)
print(f"Обработано: {post_result.output_path}")
asyncio.run(main())
Примеры использования (examples/)
В каталоге examples/ содержатся готовые исполняемые сценарии:
simple_transcode.py— Базовое перекодирование с отслеживанием прогресса в реальном времени.extract_audio.py— Извлечение звуковых дорожек в форматах MP3, AAC, FLAC и нормализация звука.video_thumbnails.py— Снятие скриншотов, серийная генерация миниатюр и раскадровка (contact sheet).watermark_and_filters.py— Наложение водяных знаков и комплексных графов фильтров черезMediaPipeline.stream_concat.py— Склейка медиафайлов через демультиплексор (demuxer) и фильтр объединения.hardware_acceleration.py— Автоматическое обнаружение GPU и кодирование с аппаратным ускорением.ytdlp_pipeline.py— Полный конвейер скачивания и последующей обработки сasync-yt-dlp.
Архитектура и документация
Подробная проектная документация доступна в каталоге docs/:
architecture.md— Системная архитектура, слои абстракции, управление процессами.api-design.md— Детальное описание публичного API и сигнатур.research.md— Исследование поведения FFmpeg CLI, протокола-progressи кодов возврата.pipeline.md— Руководство по работе сMediaPipeline.hardware.md— Конфигурация и использование аппаратного ускорения (GPU).integration.md— Взаимодействие с внешними загрузчиками иasync-yt-dlp.
Разработка и тестирование
# Установка dev-окружения
uv sync --extra dev
# Проверка форматирования и линтинга
uv run ruff check src/ tests/ examples/ docs/
uv run ruff format --check src/ tests/ examples/ docs/
# Проверка строгой статической типизации
uv run mypy src/
# Запуск тестов
uv run pytest tests/ -v
Лицензия
Распространяется под лицензией MIT.
Release files for aio-ffmpeg 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aio_ffmpeg-0.1.0.tar.gz | 308.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aio_ffmpeg-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 384.5 kB
Release files / aio_ffmpeg-0.1.0.tar.gz
| Download URL | aio_ffmpeg-0.1.0.tar.gz |
|---|---|
| Size | 308.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
726e2450815fd1eb53e466a6923701b66870bba614f17ebb32e16f43faca3aaa
|
|
BLAKE2b-256 checksum How to use checksums |
3ba16406f557bb252a2c0dd4cb15c090cf93be477a64168a625075a91c477784
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / aio_ffmpeg-0.1.0-py3-none-any.whl
| Download URL | aio_ffmpeg-0.1.0-py3-none-any.whl |
|---|---|
| Size | 76.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
891855209b7f9d51fc08b6e7a394c1194412c869651153c528fd54aec5e0ccf5
|
|
BLAKE2b-256 checksum How to use checksums |
819c1ad2e233db10eb45ced9a68e075529272d512af5740155ffb2bfc2b255c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|