aio-ffmpeg 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. aio_ffmpeg-0.1.0/.gitea/workflows/ci.yml +55 -0
  2. aio_ffmpeg-0.1.0/.gitea/workflows/release.yml +52 -0
  3. aio_ffmpeg-0.1.0/.gitignore +74 -0
  4. aio_ffmpeg-0.1.0/CHANGELOG.md +23 -0
  5. aio_ffmpeg-0.1.0/CONTRIBUTING.md +77 -0
  6. aio_ffmpeg-0.1.0/LICENSE +21 -0
  7. aio_ffmpeg-0.1.0/PKG-INFO +280 -0
  8. aio_ffmpeg-0.1.0/README.md +243 -0
  9. aio_ffmpeg-0.1.0/docs/FFPROBE_JSON_REPORT.md +859 -0
  10. aio_ffmpeg-0.1.0/docs/api-design.md +551 -0
  11. aio_ffmpeg-0.1.0/docs/architecture.md +541 -0
  12. aio_ffmpeg-0.1.0/docs/builder.md +107 -0
  13. aio_ffmpeg-0.1.0/docs/client.md +74 -0
  14. aio_ffmpeg-0.1.0/docs/examples/probe_media.py +55 -0
  15. aio_ffmpeg-0.1.0/docs/examples/progress_cli.py +48 -0
  16. aio_ffmpeg-0.1.0/docs/examples/transcode.py +44 -0
  17. aio_ffmpeg-0.1.0/docs/examples/watermark.py +37 -0
  18. aio_ffmpeg-0.1.0/docs/filters.md +84 -0
  19. aio_ffmpeg-0.1.0/docs/hardware.md +70 -0
  20. aio_ffmpeg-0.1.0/docs/integration.md +87 -0
  21. aio_ffmpeg-0.1.0/docs/pipeline.md +91 -0
  22. aio_ffmpeg-0.1.0/docs/progress.md +98 -0
  23. aio_ffmpeg-0.1.0/docs/quickstart.md +160 -0
  24. aio_ffmpeg-0.1.0/docs/reference/ffmpeg_Documentation.html +4087 -0
  25. aio_ffmpeg-0.1.0/docs/research.md +658 -0
  26. aio_ffmpeg-0.1.0/examples/extract_audio.py +98 -0
  27. aio_ffmpeg-0.1.0/examples/hardware_acceleration.py +64 -0
  28. aio_ffmpeg-0.1.0/examples/simple_transcode.py +118 -0
  29. aio_ffmpeg-0.1.0/examples/stream_concat.py +85 -0
  30. aio_ffmpeg-0.1.0/examples/video_thumbnails.py +81 -0
  31. aio_ffmpeg-0.1.0/examples/watermark_and_filters.py +106 -0
  32. aio_ffmpeg-0.1.0/examples/ytdlp_pipeline.py +75 -0
  33. aio_ffmpeg-0.1.0/pyproject.toml +115 -0
  34. aio_ffmpeg-0.1.0/src/aio_ffmpeg/__init__.py +10 -0
  35. aio_ffmpeg-0.1.0/src/aio_ffmpeg/py.typed +1 -0
  36. aio_ffmpeg-0.1.0/src/async_ffmpeg/__init__.py +227 -0
  37. aio_ffmpeg-0.1.0/src/async_ffmpeg/_compat.py +160 -0
  38. aio_ffmpeg-0.1.0/src/async_ffmpeg/_constants.py +31 -0
  39. aio_ffmpeg-0.1.0/src/async_ffmpeg/_discovery.py +298 -0
  40. aio_ffmpeg-0.1.0/src/async_ffmpeg/_logging.py +22 -0
  41. aio_ffmpeg-0.1.0/src/async_ffmpeg/_types.py +139 -0
  42. aio_ffmpeg-0.1.0/src/async_ffmpeg/client.py +1040 -0
  43. aio_ffmpeg-0.1.0/src/async_ffmpeg/command.py +531 -0
  44. aio_ffmpeg-0.1.0/src/async_ffmpeg/enums.py +71 -0
  45. aio_ffmpeg-0.1.0/src/async_ffmpeg/exceptions.py +196 -0
  46. aio_ffmpeg-0.1.0/src/async_ffmpeg/filters.py +736 -0
  47. aio_ffmpeg-0.1.0/src/async_ffmpeg/hardware.py +549 -0
  48. aio_ffmpeg-0.1.0/src/async_ffmpeg/integration/__init__.py +19 -0
  49. aio_ffmpeg-0.1.0/src/async_ffmpeg/integration/ytdlp.py +204 -0
  50. aio_ffmpeg-0.1.0/src/async_ffmpeg/models.py +255 -0
  51. aio_ffmpeg-0.1.0/src/async_ffmpeg/pipeline.py +921 -0
  52. aio_ffmpeg-0.1.0/src/async_ffmpeg/probe.py +529 -0
  53. aio_ffmpeg-0.1.0/src/async_ffmpeg/process.py +322 -0
  54. aio_ffmpeg-0.1.0/src/async_ffmpeg/progress.py +246 -0
  55. aio_ffmpeg-0.1.0/src/async_ffmpeg/py.typed +1 -0
  56. aio_ffmpeg-0.1.0/tests/conftest.py +9 -0
  57. aio_ffmpeg-0.1.0/tests/integration/test_pipeline_e2e.py +115 -0
  58. aio_ffmpeg-0.1.0/tests/performance/test_concurrent.py +78 -0
  59. aio_ffmpeg-0.1.0/tests/unit/test_advanced.py +146 -0
  60. aio_ffmpeg-0.1.0/tests/unit/test_client.py +283 -0
  61. aio_ffmpeg-0.1.0/tests/unit/test_command.py +144 -0
  62. aio_ffmpeg-0.1.0/tests/unit/test_compat.py +63 -0
  63. aio_ffmpeg-0.1.0/tests/unit/test_constants.py +19 -0
  64. aio_ffmpeg-0.1.0/tests/unit/test_discovery.py +100 -0
  65. aio_ffmpeg-0.1.0/tests/unit/test_exceptions.py +98 -0
  66. aio_ffmpeg-0.1.0/tests/unit/test_filters.py +230 -0
  67. aio_ffmpeg-0.1.0/tests/unit/test_hardware.py +207 -0
  68. aio_ffmpeg-0.1.0/tests/unit/test_init.py +22 -0
  69. aio_ffmpeg-0.1.0/tests/unit/test_integration.py +122 -0
  70. aio_ffmpeg-0.1.0/tests/unit/test_logging.py +68 -0
  71. aio_ffmpeg-0.1.0/tests/unit/test_models.py +123 -0
  72. aio_ffmpeg-0.1.0/tests/unit/test_params_validation.py +176 -0
  73. aio_ffmpeg-0.1.0/tests/unit/test_pipeline.py +346 -0
  74. aio_ffmpeg-0.1.0/tests/unit/test_probe.py +192 -0
  75. aio_ffmpeg-0.1.0/tests/unit/test_process.py +147 -0
  76. aio_ffmpeg-0.1.0/tests/unit/test_progress.py +175 -0
  77. aio_ffmpeg-0.1.0/tests/unit/test_types.py +50 -0
  78. aio_ffmpeg-0.1.0/uv.lock +556 -0
@@ -0,0 +1,55 @@
1
+ name: CI Pipeline
2
+
3
+ on:
4
+ push:
5
+ branches: [main, develop]
6
+ pull_request:
7
+ branches: [main, develop]
8
+
9
+ jobs:
10
+ lint-and-test:
11
+ name: Lint, Type Check and Tests
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - name: Checkout repository
15
+ uses: actions/checkout@v4
16
+
17
+ - name: Set up Python 3.14
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.14"
21
+
22
+ - name: Install FFmpeg
23
+ run: |
24
+ sudo apt-get update
25
+ sudo apt-get install -y ffmpeg
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@v3
29
+ with:
30
+ enable-cache: true
31
+
32
+ - name: Install dependencies
33
+ run: |
34
+ uv sync --extra dev
35
+
36
+ - name: Check code formatting (Ruff)
37
+ run: |
38
+ uv run ruff format --check src/ tests/ docs/
39
+
40
+ - name: Lint codebase (Ruff)
41
+ run: |
42
+ uv run ruff check src/ tests/ docs/
43
+
44
+ - name: Type check (Mypy)
45
+ run: |
46
+ uv run mypy src/
47
+
48
+ - name: Run unit & integration tests with coverage
49
+ run: |
50
+ uv run coverage run -m pytest tests/ -v
51
+ uv run coverage report -m
52
+
53
+ - name: Build distribution packages (Wheel & Sdist)
54
+ run: |
55
+ uv build
@@ -0,0 +1,52 @@
1
+ name: Release Pipeline
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build-and-release:
10
+ name: Build and Verify Release Artifacts
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout repository
14
+ uses: actions/checkout@v4
15
+
16
+ - name: Set up Python 3.14
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.14"
20
+
21
+ - name: Install FFmpeg
22
+ run: |
23
+ sudo apt-get update
24
+ sudo apt-get install -y ffmpeg
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v3
28
+ with:
29
+ enable-cache: true
30
+
31
+ - name: Install dependencies
32
+ run: |
33
+ uv sync --extra dev
34
+
35
+ - name: Lint and Typecheck
36
+ run: |
37
+ uv run ruff check src/ tests/ examples/
38
+ uv run mypy src/
39
+
40
+ - name: Run test suite
41
+ run: |
42
+ uv run pytest tests/ -v
43
+
44
+ - name: Build distribution packages (Wheel & Sdist)
45
+ run: |
46
+ uv build
47
+
48
+ - name: Upload distribution packages as artifacts
49
+ uses: actions/upload-artifact@v4
50
+ with:
51
+ name: dist-packages
52
+ path: dist/*
@@ -0,0 +1,74 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ .Python
8
+ build/
9
+ develop-eggs/
10
+ dist/
11
+ downloads/
12
+ eggs/
13
+ .eggs/
14
+ lib/
15
+ lib64/
16
+ parts/
17
+ sdist/
18
+ var/
19
+ wheels/
20
+ share/python-wheels/
21
+ *.egg-info/
22
+ .installed.cfg
23
+ *.egg
24
+ MANIFEST
25
+
26
+ # Virtual environments
27
+ .venv/
28
+ env/
29
+ venv/
30
+ ENV/
31
+ env.bak/
32
+ venv.bak/
33
+
34
+ # Testing & Linting
35
+ .pytest_cache/
36
+ .ruff_cache/
37
+ .mypy_cache/
38
+ .coverage
39
+ .coverage.*
40
+ coverage.xml
41
+ htmlcov/
42
+
43
+ # Graphify output directory
44
+ graphify-out/
45
+
46
+ # Media temporary files and test artifacts
47
+ *.mp4
48
+ *.mkv
49
+ *.avi
50
+ *.mp3
51
+ *.aac
52
+ *.wav
53
+ *.flac
54
+ *.m4a
55
+ *.webm
56
+ *.ogg
57
+ *.ts
58
+ *.srt
59
+ *.vtt
60
+ *.log
61
+ *.txt
62
+ !requirements*.txt
63
+ !docs/**/*.txt
64
+ output_examples/
65
+
66
+ # IDE / Editor
67
+ .idea/
68
+ .vscode/
69
+ *.swp
70
+ *.swo
71
+
72
+ # OS generated
73
+ .DS_Store
74
+ Thumbs.db
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ Все заметные изменения в проекте `async-ffmpeg` документируются в этом файле.
4
+
5
+ Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.0.0/),
6
+ и проект придерживается [Семантического версионирования](https://semver.org/lang/ru/).
7
+
8
+ ---
9
+
10
+ ## [0.1.0] - 2026-09-19
11
+
12
+ ### Добавлено
13
+ - **Высокоуровневый клиент (`FFmpegClient`)**: единый фасад с методами `transcode`, `extract_audio`, `trim`, `concat`, `screenshot`, `thumbnails`, `convert`, `normalize_audio`, `scale`, `two_pass_transcode`, `create_contact_sheet`, `detect_silence` и `probe`.
14
+ - **Конструктор команд (`FFmpegCommand`)**: строго упорядоченный fluent-builder аргументов FFmpeg CLI (глобальные опции -> входные параметры -> фильтры -> выходные параметры) с автоматической валидацией конфликтующих флагов.
15
+ - **Декларативный конвейер медиа (`MediaPipeline`)**: пошаговое построение цепочек обработки (trim, scale, watermark, audio normalization) с компиляцией в единый процесс FFmpeg и валидацией на этапе сборки.
16
+ - **Клиент инспекции (`FFprobe`) и строгие модели данных**: асинхронный запуск `ffprobe` с разбором JSON-вывода в типизированные frozen dataclass-модели (`MediaInfo`, `VideoStream`, `AudioStream`, `SubtitleStream`, `Chapter`, `StreamDisposition`).
17
+ - **Модуль аппаратного ускорения (`HardwareAccel`)**: автоматическое обнаружение доступных GPU-ускорителей (CUDA/NVENC, AMD AMF, Intel QSV, D3D11VA, Apple VideoToolbox) и подбор оптимальных кодеков.
18
+ - **Диспетчер процессов (`ProcessRunner`)**: асинхронное управление жизненным циклом подпроцессов через `asyncio.create_subprocess_exec()`, ограничение параллельности через `asyncio.Semaphore`, поддержка таймаутов и graceful shutdown (`q\n` -> SIGINT -> SIGKILL).
19
+ - **Машиночитаемый парсер прогресса (`ProgressParser`)**: разбор протокола `-progress pipe:1` в реальном времени с вычислением процента выполнения, времени, FPS, битрейта и скорости кодирования.
20
+ - **Объектно-ориентированный граф фильтров (`Filter`, `FilterChain`, `FilterGraph`, `ComplexFilterGraph`)**: фабричные функции для видео- и аудиофильтров (`scale`, `fps`, `crop`, `pad`, `rotate`, `overlay`, `drawtext`, `loudnorm`, `volume`, `amix`, `concat` и др.).
21
+ - **Модуль интеграции с `async-yt-dlp` (`async_ffmpeg.integration`)**: функции `process_download_result`, `transcode_download`, `extract_download_audio` и класс `DownloadPostProcessor` на базе слабосвязанного протокола `DownloadResultProtocol`.
22
+ - **Комплекс интерактивных примеров (`examples/`)**: 7 готовых сценариев (`simple_transcode`, `extract_audio`, `video_thumbnails`, `watermark_and_filters`, `stream_concat`, `hardware_acceleration`, `ytdlp_pipeline`).
23
+ - **Инфраструктура и качество**: 118 автоматических тестов с 100% прохождением, поддержка Python 3.14+, строгая статическая типизация `mypy --strict` без единого `Any`, zero runtime dependencies (только стандартная библиотека Python).
@@ -0,0 +1,77 @@
1
+ # Руководство по внесению вклада (Contributing)
2
+
3
+ Приветствуются любые улучшения, исправления ошибок и предложения новых функциональных возможностей в `async-ffmpeg`.
4
+
5
+ ---
6
+
7
+ ## 1. Стратегия ветвления (Branching Strategy)
8
+
9
+ В репозитории используется модель Git Flow с двумя долгоживущими ветками:
10
+
11
+ - **`main`**: стабильная (production) ветка. Содержит исключительно готовые к релизу версии кода. Прямые коммиты запрещены. Слияния осуществляются только из `develop` перед выпуском новой версии с созданием аннотированного тега (`vX.Y.Z`).
12
+ - **`develop`**: ветка активной разработки. В неё интегрируются новые возможности и исправления через Pull Requests.
13
+ - **Вспомогательные ветки**:
14
+ - `feature/<название>`: разработка новой функциональности (создаются от `develop`, сливаются в `develop`).
15
+ - `fix/<описание>` или `bugfix/<описание>`: устранение ошибок (создаются от `develop`, сливаются в `develop`).
16
+ - `hotfix/<описание>`: неотложные исправления для продакшна (создаются от `main`, сливаются в `main` и `develop`).
17
+
18
+ ---
19
+
20
+ ## 2. Процесс разработки
21
+
22
+ 1. Склонировать репозиторий:
23
+ ```bash
24
+ git clone ssh://git@localhost:2222/6aton/AsyncFFmpeg.git
25
+ cd AsyncFFmpeg
26
+ ```
27
+ 2. Создать рабочую ветку от актуального состояния `develop`:
28
+ ```bash
29
+ git checkout develop
30
+ git pull origin develop
31
+ git checkout -b feature/my-feature
32
+ ```
33
+ 3. Установить зависимости для разработки через менеджер `uv`:
34
+ ```bash
35
+ uv sync --extra dev
36
+ ```
37
+ 4. Внести изменения, соблюдая архитектурные принципы проекта.
38
+ 5. Написать модульные или интеграционные тесты в каталоге `tests/`.
39
+ 6. Убедиться в успешном прохождении всех локальных проверок качества.
40
+ 7. Зафиксировать изменения с понятными сообщениями коммитов и отправить ветку в удалённый репозиторий.
41
+
42
+ ---
43
+
44
+ ## 3. Стандарты качества кода
45
+
46
+ Перед отправкой изменений обязательно выполнение всех автоматических проверок:
47
+
48
+ ```bash
49
+ # Проверка форматирования и линтинга
50
+ uv run ruff check src/ tests/ examples/ docs/
51
+ uv run ruff format --check src/ tests/ examples/ docs/
52
+
53
+ # Проверка строгой статической типизации (Zero Any policy)
54
+ uv run mypy src/
55
+
56
+ # Запуск полного набора тестов с анализом покрытия
57
+ uv run pytest tests/ -v
58
+ ```
59
+
60
+ ---
61
+
62
+ ## 4. Архитектурные правила и ограничения
63
+
64
+ 1. **Zero Runtime Dependencies**:
65
+ - В секции `dependencies` файла `pyproject.toml` не допускаются внешние пакеты.
66
+ - Разрешено использование исключительно стандартной библиотеки Python 3.14+.
67
+ - Внешние интеграции (например, `async-yt-dlp`) оформляются как опциональные зависимости (`optional-dependencies`).
68
+ 2. **Строгая статическая типизация**:
69
+ - Политика `Zero Any`: использование типа `Any` строго запрещено во всех публичных и внутренних сигнатурах.
70
+ - Для всех моделей данных используются frozen dataclass со `slots=True` (`@dataclass(frozen=True, slots=True)`).
71
+ - Обязательно указание типов всех аргументов и возвращаемых значений (`-> None` для процедур).
72
+ 3. **Языковая политика**:
73
+ - Все docstrings, комментарии к коду и документация составляются на русском языке в нейтральной форме (инфинитивы, безличные конструкции, 3-е лицо; без использования местоимений первого и второго лица).
74
+ - Все идентификаторы (имена модулей, классов, методов, функций, переменных) именуются на английском языке по стандарту PEP 8.
75
+ 4. **Кроссплатформенность**:
76
+ - Пути к файлам нормализуются через `normalize_path_for_ffmpeg()` из `_compat.py`.
77
+ - Запуск подпроцессов учитывает специфику платформ (флаг `CREATE_NO_WINDOW` для Windows, сигналы завершения для POSIX).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 async-ffmpeg contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,280 @@
1
+ Metadata-Version: 2.5
2
+ Name: aio-ffmpeg
3
+ Version: 0.1.0
4
+ Summary: Production-ready, strictly typed async wrapper for FFmpeg and FFprobe
5
+ Project-URL: Homepage, https://github.com/baton-spb/AsyncFFmpeg
6
+ Project-URL: Documentation, https://github.com/baton-spb/AsyncFFmpeg#readme
7
+ Project-URL: Repository, https://github.com/baton-spb/AsyncFFmpeg.git
8
+ Project-URL: Issues, https://github.com/baton-spb/AsyncFFmpeg/issues
9
+ Author: async-ffmpeg contributors
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: aio,async,asyncio,audio,ffmpeg,ffprobe,streaming,transcode,video
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Framework :: AsyncIO
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Multimedia :: Sound/Audio
24
+ Classifier: Topic :: Multimedia :: Video
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.11
28
+ Provides-Extra: dev
29
+ Requires-Dist: coverage>=7.6.0; extra == 'dev'
30
+ Requires-Dist: mypy>=1.13.0; extra == 'dev'
31
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
34
+ Provides-Extra: ytdlp
35
+ Requires-Dist: async-yt-dlp>=0.1.0; extra == 'ytdlp'
36
+ Description-Content-Type: text/markdown
37
+
38
+ # async-ffmpeg
39
+
40
+ [![CI](https://github.com/baton-spb/AsyncFFmpeg/actions/workflows/ci.yml/badge.svg)](https://github.com/baton-spb/AsyncFFmpeg/actions)
41
+ [![PyPI version](https://img.shields.io/pypi/v/async-ffmpeg.svg)](https://pypi.org/project/async-ffmpeg/)
42
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
43
+ [![Typing: Typed](https://img.shields.io/badge/typing-typed-green.svg)](https://peps.python.org/pep-0561/)
44
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
45
+
46
+ **async-ffmpeg** — современная, строго типизированная, production-ready асинхронная библиотека-обёртка над `ffmpeg` и `ffprobe` для Python 3.11+.
47
+
48
+ Она построена непосредственно поверх `asyncio.create_subprocess_exec()` без сторонних C-библиотек, без устаревших binding-ов и с **нулевыми зависимостями времени выполнения** (zero runtime dependencies, только стандартная библиотека Python).
49
+
50
+ ---
51
+
52
+ ## Сравнение с аналогами
53
+
54
+ | Возможность | `async-ffmpeg` | `ffmpeg-python` | `moviepy` | `subprocess` (ручной) |
55
+ |:---|:---:|:---:|:---:|:---:|
56
+ | **Нативная асинхронность (`asyncio`)** | **Да** | Нет | Нет | Требует ручной реализации |
57
+ | **Зависимости времени выполнения** | **0 (только stdlib)** | 2 | 10+ (тяжёлые) | 0 |
58
+ | **Строгая типизация (`mypy --strict`)** | **100% (Zero Any)** | Нет типов | Частичная | Нет |
59
+ | **Парсинг прогресса в реальном времени** | **Да (`-progress pipe:1`)** | Нет | Tqdm (базовый) | Ручной парсинг |
60
+ | **Безопасная остановка (Graceful Shutdown)** | **Да (`q\n` -> SIGINT)** | Нет | Нет | Нет |
61
+ | **Многоуровневый API (Facade / Pipeline / Builder)** | **Да** | Только builder | Только facade | Нет |
62
+ | **Автоопределение GPU (CUDA/AMF/QSV/Toolbox)** | **Да** | Нет | Нет | Нет |
63
+ | **Поддержка современного Python 3.14+** | **Да** | Заброшен | Медленный | Да |
64
+
65
+ ---
66
+
67
+ ## Ключевые возможности
68
+
69
+ - **Полноценная асинхронность**: неблокирующий запуск процессов через `asyncio.create_subprocess_exec()`, контроль конкурентности через `asyncio.Semaphore`.
70
+ - **Строгая типизация**: 100% соответствие `mypy --strict` и `Zero Any policy`, frozen dataclass-модели со `slots=True`, маркер PEP 561 (`py.typed`).
71
+ - **Машиночитаемый прогресс**: чтение и потоковый разбор протокола `-progress pipe:1` (кадры, время, битрейт, скорость кодирования, процент выполнения).
72
+ - **Graceful Shutdown**: предотвращение повреждения медиафайлов (битых заголовков MP4 / unclosed `moov` atom) путём отправки `q` в stdin перед отправкой системных сигналов завершения.
73
+ - **Трёхуровневый API**:
74
+ - **Facade (`FFmpegClient`)**: готовые методы для решения 95% повседневных задач.
75
+ - **Pipeline (`MediaPipeline`)**: декларативный конвейер цепочек обработки видео и аудио.
76
+ - **Command Builder (`FFmpegCommand`)**: строгий конструктор аргументов CLI с контролем порядка и валидацией конфликтов.
77
+ - **Типизированный FFprobe**: детальный разбор контейнеров, видео/аудио/субтитр-потоков, глав и метаданных.
78
+ - **Аппаратное ускорение**: автоопределение и конфигурация NVENC, AMF, QSV, D3D11VA, VideoToolbox.
79
+ - **Интеграция с `async-yt-dlp`**: бесшовный конвейер загрузки и последующей обработки медиафайлов.
80
+
81
+ ---
82
+
83
+ ## Методы высокоуровневого клиента (`FFmpegClient`)
84
+
85
+ | Метод | Назначение |
86
+ |:---|:---|
87
+ | `transcode(...)` | Универсальное перекодирование с контролем кодеков, битрейта, разрешения, FPS и фильтров. |
88
+ | `extract_audio(...)` | Извлечение аудиодорожки (`-vn`) с конвертацией в AAC, MP3, FLAC, OPUS или WAV. |
89
+ | `trim(...)` | Быстрая обрезка медиафрагментов по меткам времени (со stream copy или перекодированием). |
90
+ | `concat(...)` | Склейка нескольких файлов без перекодирования (demuxer) или через граф фильтров. |
91
+ | `screenshot(...)` | Извлечение одного кадра в указанной временной метке в высоком качестве. |
92
+ | `thumbnails(...)` | Серийная генерация миниатюр по фиксированному интервалу, общему числу или частоте кадров. |
93
+ | `convert(...)` | Быстрая смена контейнера (remuxing, например MKV -> MP4) со stream copy. |
94
+ | `normalize_audio(...)` | Двухпроходная нормализация громкости по вещательному стандарту EBU R128 (`loudnorm`). |
95
+ | `scale(...)` | Масштабирование видеоряда с сохранением исходной аудиодорожки без перекодирования. |
96
+ | `two_pass_transcode(...)` | Двухпроходное кодирование с контролем битрейта и автоматической очисткой временных логов. |
97
+ | `create_contact_sheet(...)` | Сборка раскадровки (storyboard/contact sheet) в виде сетки миниатюр (`tile`). |
98
+ | `detect_silence(...)` | Детектирование тишины и пауз в аудиодорожке с получением интервалов (`SilenceInterval`). |
99
+ | `probe(...)` | Детальный анализ метаданных файла или потока с возвратом типизированного `MediaInfo`. |
100
+
101
+ ---
102
+
103
+ ## Установка
104
+
105
+ ```bash
106
+ # Базовая установка (zero external dependencies)
107
+ uv add async-ffmpeg
108
+
109
+ # Или через pip:
110
+ pip install async-ffmpeg
111
+
112
+ # С опциональной поддержкой интеграции с async-yt-dlp
113
+ pip install "async-ffmpeg[ytdlp]"
114
+ ```
115
+
116
+ Требования:
117
+ - Python >= 3.14
118
+ - Установленный в системе `ffmpeg` и `ffprobe` (в `PATH` или указанный через аргументы клиента / переменную `FFMPEG_PATH`)
119
+
120
+ ---
121
+
122
+ ## Быстрый старт
123
+
124
+ ### 1. Анализ медиафайла (`FFprobe`)
125
+
126
+ ```python
127
+ import asyncio
128
+ from async_ffmpeg import FFmpegClient
129
+
130
+
131
+ async def main() -> None:
132
+ client = FFmpegClient()
133
+ info = await client.probe("video.mp4")
134
+
135
+ print(f"Формат: {info.format.format_long_name}")
136
+ print(f"Длительность: {info.duration} сек")
137
+
138
+ if info.primary_video:
139
+ v = info.primary_video
140
+ print(f"Видео: {v.codec_name}, {v.width}x{v.height} @ {v.frame_rate:.2f} fps")
141
+
142
+ if info.primary_audio:
143
+ a = info.primary_audio
144
+ print(f"Аудио: {a.codec_name}, {a.sample_rate} Hz, каналов: {a.channels}")
145
+
146
+
147
+ asyncio.run(main())
148
+ ```
149
+
150
+ ### 2. Транскодирование с отслеживанием прогресса
151
+
152
+ ```python
153
+ import asyncio
154
+ from async_ffmpeg import FFmpegClient, ProgressInfo
155
+
156
+
157
+ async def main() -> None:
158
+ client = FFmpegClient()
159
+
160
+ async def on_progress(p: ProgressInfo) -> None:
161
+ print(f"Прогресс: {p.percent:.1f}% | Скорость: {p.speed} | FPS: {p.fps:.1f}")
162
+
163
+ result = await client.transcode(
164
+ input="input.mp4",
165
+ output="output_720p.mp4",
166
+ video_codec="libx264",
167
+ crf=23,
168
+ resolution=(1280, 720),
169
+ audio_codec="aac",
170
+ audio_bitrate="128k",
171
+ on_progress=on_progress,
172
+ )
173
+ print(f"Готово за {result.duration_seconds:.2f} сек!")
174
+
175
+
176
+ asyncio.run(main())
177
+ ```
178
+
179
+ ### 3. Декларативный конвейер (`MediaPipeline`)
180
+
181
+ ```python
182
+ import asyncio
183
+ from async_ffmpeg import FFmpegClient
184
+
185
+
186
+ async def main() -> None:
187
+ client = FFmpegClient()
188
+
189
+ # Цепочка: обрезка -> масштабирование -> нормализация звука -> вывод
190
+ await (
191
+ client.pipeline("input.mp4")
192
+ .trim(start=10, duration=60)
193
+ .scale(1280, 720)
194
+ .normalize_audio(target_lufs=-16.0)
195
+ .output("highlight_720p.mp4")
196
+ .run()
197
+ )
198
+
199
+
200
+ asyncio.run(main())
201
+ ```
202
+
203
+ ### 4. Интеграция с загрузчиком (`async-yt-dlp`)
204
+
205
+ ```python
206
+ import asyncio
207
+ from async_ffmpeg import FFmpegClient
208
+ from async_ffmpeg.integration import process_download_result
209
+
210
+
211
+ async def main() -> None:
212
+ # Загрузка через yt-dlp (или совместимый объект с протоколом DownloadResultProtocol)
213
+ # Предположим, результат загрузки сохранён в download_result
214
+ client = FFmpegClient()
215
+
216
+ # Автоматическое извлечение аудиодорожки или конвертация
217
+ post_result = await process_download_result(
218
+ download_result,
219
+ action="extract_audio",
220
+ client=client,
221
+ audio_format="mp3",
222
+ audio_bitrate="320k",
223
+ )
224
+ print(f"Обработано: {post_result.output_path}")
225
+
226
+
227
+ asyncio.run(main())
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Примеры использования (`examples/`)
233
+
234
+ В каталоге [`examples/`](examples/) содержатся готовые исполняемые сценарии:
235
+
236
+ 1. [`simple_transcode.py`](examples/simple_transcode.py) — Базовое перекодирование с отслеживанием прогресса в реальном времени.
237
+ 2. [`extract_audio.py`](examples/extract_audio.py) — Извлечение звуковых дорожек в форматах MP3, AAC, FLAC и нормализация звука.
238
+ 3. [`video_thumbnails.py`](examples/video_thumbnails.py) — Снятие скриншотов, серийная генерация миниатюр и раскадровка (contact sheet).
239
+ 4. [`watermark_and_filters.py`](examples/watermark_and_filters.py) — Наложение водяных знаков и комплексных графов фильтров через `MediaPipeline`.
240
+ 5. [`stream_concat.py`](examples/stream_concat.py) — Склейка медиафайлов через демультиплексор (demuxer) и фильтр объединения.
241
+ 6. [`hardware_acceleration.py`](examples/hardware_acceleration.py) — Автоматическое обнаружение GPU и кодирование с аппаратным ускорением.
242
+ 7. [`ytdlp_pipeline.py`](examples/ytdlp_pipeline.py) — Полный конвейер скачивания и последующей обработки с `async-yt-dlp`.
243
+
244
+ ---
245
+
246
+ ## Архитектура и документация
247
+
248
+ Подробная проектная документация доступна в каталоге [`docs/`](docs/):
249
+
250
+ - [`architecture.md`](docs/architecture.md) — Системная архитектура, слои абстракции, управление процессами.
251
+ - [`api-design.md`](docs/api-design.md) — Детальное описание публичного API и сигнатур.
252
+ - [`research.md`](docs/research.md) — Исследование поведения FFmpeg CLI, протокола `-progress` и кодов возврата.
253
+ - [`pipeline.md`](docs/pipeline.md) — Руководство по работе с `MediaPipeline`.
254
+ - [`hardware.md`](docs/hardware.md) — Конфигурация и использование аппаратного ускорения (GPU).
255
+ - [`integration.md`](docs/integration.md) — Взаимодействие с внешними загрузчиками и `async-yt-dlp`.
256
+
257
+ ---
258
+
259
+ ## Разработка и тестирование
260
+
261
+ ```bash
262
+ # Установка dev-окружения
263
+ uv sync --extra dev
264
+
265
+ # Проверка форматирования и линтинга
266
+ uv run ruff check src/ tests/ examples/ docs/
267
+ uv run ruff format --check src/ tests/ examples/ docs/
268
+
269
+ # Проверка строгой статической типизации
270
+ uv run mypy src/
271
+
272
+ # Запуск тестов
273
+ uv run pytest tests/ -v
274
+ ```
275
+
276
+ ---
277
+
278
+ ## Лицензия
279
+
280
+ Распространяется под лицензией [MIT](LICENSE).