aio-ffmpeg
Строго типизированная асинхронная обёртка над ffmpeg и ffprobe для Python 3.11+.
Процессы запускаются через asyncio.create_subprocess_exec(). Нет зависимостей времени выполнения — только стандартная библиотека Python.
Сравнение с аналогами
| Возможность | aio-ffmpeg |
ffmpeg-python |
moviepy |
subprocess |
|---|---|---|---|---|
Асинхронность (asyncio) |
Да | Нет | Нет | Ручная реализация |
| Зависимости runtime | 0 (stdlib) | 2 | 10+ | 0 |
Строгая типизация (mypy --strict) |
Да | Нет | Частичная | Нет |
| Парсинг прогресса | Да (-progress pipe:1) |
Нет | Tqdm | Ручной |
| Graceful shutdown | Да (q\n → SIGINT) |
Нет | Нет | Нет |
| Автоопределение GPU | Да (NVENC/AMF/QSV/VideoToolbox) | Нет | Нет | Нет |
Возможности
- Асинхронный запуск процессов:
asyncio.create_subprocess_exec(), контроль конкурентности черезasyncio.Semaphore. - Типизация: frozen dataclass-модели со
slots=True, PEP 561py.typed,mypy --strict. - Прогресс: потоковый разбор протокола
-progress pipe:1(кадры, время, битрейт, скорость, процент). - Graceful shutdown: отправка
qв stdin перед системными сигналами завершения. Предотвращает повреждение заголовков MP4. - Три уровня API:
FFmpegClient— готовые методы для типовых задач.MediaPipeline— декларативный конвейер цепочек обработки.FFmpegCommand— построитель аргументов CLI с валидацией.
- FFprobe: типизированный разбор контейнеров, видео/аудио/субтитр-потоков, глав и метаданных.
- Аппаратное ускорение: автоопределение NVENC, AMF, QSV, D3D11VA, VideoToolbox.
- Интеграция с
async-yt-dlp: конвейер загрузки и постобработки медиафайлов.
Методы FFmpegClient
| Метод | Назначение |
|---|---|
transcode(...) |
Перекодирование с контролем кодеков, битрейта, разрешения, FPS и фильтров |
two_pass_transcode(...) |
Двухпроходное кодирование с контролем битрейта |
extract_audio(...) |
Извлечение аудиодорожки (-vn) в AAC, MP3, FLAC, OPUS, WAV |
trim(...) |
Обрезка по меткам времени (stream copy или перекодирование) |
concat(...) |
Склейка файлов через demuxer или граф фильтров |
convert(...) |
Смена контейнера (remuxing, stream copy) |
scale(...) |
Масштабирование видео |
normalize_audio(...) |
Двухпроходная нормализация по EBU R128 (фильтр loudnorm) |
screenshot(...) |
Извлечение кадра по временной метке |
thumbnails(...) |
Генерация миниатюр по интервалу, количеству или частоте кадров |
create_contact_sheet(...) |
Раскадровка — сетка миниатюр (tile) |
detect_silence(...) |
Обнаружение тишины и пауз (SilenceInterval) |
probe(...) |
Анализ метаданных файла → типизированный MediaInfo |
pipeline(...) |
Создание MediaPipeline для декларативной обработки |
Установка
Требуется Python 3.11+, установленные в системе ffmpeg и ffprobe (в PATH или через аргументы клиента / переменную FFMPEG_PATH).
# Базовая установка (без runtime-зависимостей):
pip install aio-ffmpeg
# С интеграцией с async-yt-dlp:
pip install "aio-ffmpeg[ytdlp]"
Или через uv:
uv add aio-ffmpeg
Быстрый старт
1. Анализ медиафайла
import asyncio
from aio_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 aio_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 aio_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 aio_ffmpeg import FFmpegClient
from aio_ffmpeg.integration import process_download_result
async def main() -> None:
client = FFmpegClient()
# download_result — объект с протоколом DownloadResultProtocol
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/ — готовые примеры:
simple_transcode.py— перекодирование с прогрессомextract_audio.py— извлечение звуковых дорожекvideo_thumbnails.py— скриншоты, миниатюры, раскадровкаwatermark_and_filters.py— водяные знаки и фильтры черезMediaPipelinestream_concat.py— склейка медиафайловhardware_acceleration.py— кодирование с аппаратным ускорениемytdlp_pipeline.py— конвейер сasync-yt-dlp
Разработка
# Dev-окружение
uv sync --extra dev
# Линтинг
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/
# Типизация
uv run mypy src/
# Тесты
uv run pytest tests/ -v
Лицензия
Распространяется под лицензией MIT.
Release files for aio-ffmpeg 0.1.2
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.2.tar.gz | 307.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aio_ffmpeg-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 383.0 kB
Release files / aio_ffmpeg-0.1.2.tar.gz
| Download URL | aio_ffmpeg-0.1.2.tar.gz |
|---|---|
| Size | 307.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0dcc58c80792e443eee6b4baaf211e5465929f494481f2305d8ac16a6c86bffc
|
|
BLAKE2b-256 checksum How to use checksums |
3686814a0d6a9b710bb87cad39d467833d2736446ea04fb0650b614dc6aaee61
|
| 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.2-py3-none-any.whl
| Download URL | aio_ffmpeg-0.1.2-py3-none-any.whl |
|---|---|
| Size | 75.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8646d8bc223211e797e3500db7138c50e25a17ef372300e7b6f7a2d9af4f59e4
|
|
BLAKE2b-256 checksum How to use checksums |
35c5918885ee896a2aeb9d1b28d21e530e2a782077a2bf938c67695c39037e74
|
| 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}
|