aio-ffmpeg 0.1.0__py3-none-any.whl
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.
- aio_ffmpeg/__init__.py +10 -0
- aio_ffmpeg/py.typed +1 -0
- aio_ffmpeg-0.1.0.dist-info/METADATA +280 -0
- aio_ffmpeg-0.1.0.dist-info/RECORD +26 -0
- aio_ffmpeg-0.1.0.dist-info/WHEEL +4 -0
- aio_ffmpeg-0.1.0.dist-info/licenses/LICENSE +21 -0
- async_ffmpeg/__init__.py +227 -0
- async_ffmpeg/_compat.py +160 -0
- async_ffmpeg/_constants.py +31 -0
- async_ffmpeg/_discovery.py +298 -0
- async_ffmpeg/_logging.py +22 -0
- async_ffmpeg/_types.py +139 -0
- async_ffmpeg/client.py +1040 -0
- async_ffmpeg/command.py +531 -0
- async_ffmpeg/enums.py +71 -0
- async_ffmpeg/exceptions.py +196 -0
- async_ffmpeg/filters.py +736 -0
- async_ffmpeg/hardware.py +549 -0
- async_ffmpeg/integration/__init__.py +19 -0
- async_ffmpeg/integration/ytdlp.py +204 -0
- async_ffmpeg/models.py +255 -0
- async_ffmpeg/pipeline.py +921 -0
- async_ffmpeg/probe.py +529 -0
- async_ffmpeg/process.py +322 -0
- async_ffmpeg/progress.py +246 -0
- async_ffmpeg/py.typed +1 -0
aio_ffmpeg/__init__.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""aio-ffmpeg — асинхронная, строго типизированная библиотека-обёртка над FFmpeg и FFprobe.
|
|
2
|
+
|
|
3
|
+
Предоставляет полный доступ к API async_ffmpeg под псевдонимом aio_ffmpeg.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from async_ffmpeg import * # noqa: F403
|
|
7
|
+
from async_ffmpeg import __all__ as _async_ffmpeg_all
|
|
8
|
+
from async_ffmpeg import __version__
|
|
9
|
+
|
|
10
|
+
__all__ = [*_async_ffmpeg_all, "__version__"]
|
aio_ffmpeg/py.typed
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Marker file for PEP 561
|
|
@@ -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
|
+
[](https://github.com/baton-spb/AsyncFFmpeg/actions)
|
|
41
|
+
[](https://pypi.org/project/async-ffmpeg/)
|
|
42
|
+
[](https://www.python.org/downloads/)
|
|
43
|
+
[](https://peps.python.org/pep-0561/)
|
|
44
|
+
[](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).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
aio_ffmpeg/__init__.py,sha256=VlpXBYN6h0wDzEkecaSCL-J_rxyceL1NrZ3gh0sguSw,446
|
|
2
|
+
aio_ffmpeg/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
|
|
3
|
+
async_ffmpeg/__init__.py,sha256=wQATEsEBfU4q9j3K58Avx5L4sxXmbQzW8RqpXl0eB3E,5010
|
|
4
|
+
async_ffmpeg/_compat.py,sha256=FjTObKXamqrLVLlskBDthiA0yqT2A_CVbvA4BSCZA-4,6900
|
|
5
|
+
async_ffmpeg/_constants.py,sha256=M-FITKt6UfNaSvyztwRee2A66nLRXG2DYeZXhi1ikg4,1293
|
|
6
|
+
async_ffmpeg/_discovery.py,sha256=oUL1iQOKJPYN-e7SEVVDlRPNFLah4D0AjO9r5ttmUaA,11941
|
|
7
|
+
async_ffmpeg/_logging.py,sha256=_jl8-I-SQ-ItHOpAJbaALIDwxEF_BMId4tW1hdxz7eI,920
|
|
8
|
+
async_ffmpeg/_types.py,sha256=iGaQs61A5c9T73yezk6XPcqgVhacFtS09uzu8qQVPgI,3942
|
|
9
|
+
async_ffmpeg/client.py,sha256=rCxkpf1sPLRcFPhsp-5UG7E9Su_jLcJj3TenzBLWgqE,44594
|
|
10
|
+
async_ffmpeg/command.py,sha256=PV-zJXycprCxJB_kXatasssj_5UlFqhQDzQCP8VtKJ4,23425
|
|
11
|
+
async_ffmpeg/enums.py,sha256=xfVb5qmml3IJWKDDkETB5ICfBV9Zb9cPN-MeLJCRKGw,2430
|
|
12
|
+
async_ffmpeg/exceptions.py,sha256=Zx2MDHSOBxXiXwelmILcnALzYbyJxRkV_aHH8JuN_ps,9610
|
|
13
|
+
async_ffmpeg/filters.py,sha256=bZ56bKph9De-yMmXmQGwoqBH94fNjsJI8lrRSEXK2Hk,29281
|
|
14
|
+
async_ffmpeg/hardware.py,sha256=wzvaHVFtA-DIhmUQpWv7V0dmQL8IURm3d8bDIncKyus,22173
|
|
15
|
+
async_ffmpeg/models.py,sha256=gmeABYdxpO9eyCSp5qAVhZLO4aAccdfJ0GF4fdUWqWc,8875
|
|
16
|
+
async_ffmpeg/pipeline.py,sha256=zwMU3cWQC9HNzRRvUEPAlhCMqx32CNKz8nWnTq2WuhE,36245
|
|
17
|
+
async_ffmpeg/probe.py,sha256=cgjwVi7NmFiKE5URL5gCKfWs6nawXRhpwnPlayuX_Ig,22239
|
|
18
|
+
async_ffmpeg/process.py,sha256=RD8diOA32ik-LKH2W5CTuUwludlITpO1_voSoyE-8MI,15386
|
|
19
|
+
async_ffmpeg/progress.py,sha256=f3d4FtVcfkEk-Vqjrgg-lss430EKK2tyQbPj4UF7sFo,9689
|
|
20
|
+
async_ffmpeg/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
|
|
21
|
+
async_ffmpeg/integration/__init__.py,sha256=Eg0ZRBQYpJEeIjUnA2w86oMMPJ5TRNHQ46T-yP-_XGI,522
|
|
22
|
+
async_ffmpeg/integration/ytdlp.py,sha256=0OI6uaZTiNvm6Km0lyiq18w5MMG9PC_2FhNcaIekGF0,8195
|
|
23
|
+
aio_ffmpeg-0.1.0.dist-info/METADATA,sha256=55imeJb9RJpRondmXEvfvnjYS1taQzlFNizbnaG12hE,14855
|
|
24
|
+
aio_ffmpeg-0.1.0.dist-info/WHEEL,sha256=THafob7ofN-NsuMN7Mg4qZyHaQI7KkD-QlcQatYhXPo,87
|
|
25
|
+
aio_ffmpeg-0.1.0.dist-info/licenses/LICENSE,sha256=lVXDpAhI1dH29OZo-cKHnLqKbCgEwixrXcxUl3gG5dA,1082
|
|
26
|
+
aio_ffmpeg-0.1.0.dist-info/RECORD,,
|
|
@@ -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.
|
async_ffmpeg/__init__.py
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"""async-ffmpeg — асинхронная, строго типизированная библиотека-обёртка над FFmpeg и FFprobe."""
|
|
2
|
+
|
|
3
|
+
from async_ffmpeg._compat import (
|
|
4
|
+
escape_filter_path,
|
|
5
|
+
normalize_path_for_ffmpeg,
|
|
6
|
+
terminate_process_gracefully,
|
|
7
|
+
)
|
|
8
|
+
from async_ffmpeg._constants import (
|
|
9
|
+
DEFAULT_AUDIO_BITRATE,
|
|
10
|
+
DEFAULT_FFMPEG_EXECUTABLE,
|
|
11
|
+
DEFAULT_FFPROBE_EXECUTABLE,
|
|
12
|
+
DEFAULT_LOGLEVEL,
|
|
13
|
+
DEFAULT_MAX_CONCURRENT,
|
|
14
|
+
DEFAULT_STATS_PERIOD,
|
|
15
|
+
DEFAULT_VIDEO_CRF,
|
|
16
|
+
DEFAULT_VIDEO_PRESET,
|
|
17
|
+
__version__,
|
|
18
|
+
)
|
|
19
|
+
from async_ffmpeg._discovery import (
|
|
20
|
+
BinaryInfo,
|
|
21
|
+
clear_discovery_cache,
|
|
22
|
+
find_binary,
|
|
23
|
+
find_ffmpeg,
|
|
24
|
+
find_ffprobe,
|
|
25
|
+
get_binary_version,
|
|
26
|
+
get_binary_version_sync,
|
|
27
|
+
get_ffmpeg_info,
|
|
28
|
+
get_ffprobe_info,
|
|
29
|
+
)
|
|
30
|
+
from async_ffmpeg._logging import get_logger, logger
|
|
31
|
+
from async_ffmpeg._types import (
|
|
32
|
+
AudioCodec,
|
|
33
|
+
AudioFormat,
|
|
34
|
+
ConcatMethod,
|
|
35
|
+
DownloadResultProtocol,
|
|
36
|
+
LogLevel,
|
|
37
|
+
MediaInputProtocol,
|
|
38
|
+
PathLike,
|
|
39
|
+
ProgressCallback,
|
|
40
|
+
Resolution,
|
|
41
|
+
StderrCallback,
|
|
42
|
+
StreamType,
|
|
43
|
+
VideoCodec,
|
|
44
|
+
VideoContainer,
|
|
45
|
+
VideoPreset,
|
|
46
|
+
WatermarkPosition,
|
|
47
|
+
)
|
|
48
|
+
from async_ffmpeg.client import FFmpegClient
|
|
49
|
+
from async_ffmpeg.command import FFmpegCommand
|
|
50
|
+
from async_ffmpeg.exceptions import (
|
|
51
|
+
AsyncFFmpegError,
|
|
52
|
+
CodecNotFoundError,
|
|
53
|
+
CommandBuildError,
|
|
54
|
+
FFmpegCancelledError,
|
|
55
|
+
FFmpegNotFoundError,
|
|
56
|
+
FFmpegProcessError,
|
|
57
|
+
FFmpegTimeoutError,
|
|
58
|
+
FFprobeError,
|
|
59
|
+
FilterError,
|
|
60
|
+
InvalidInputError,
|
|
61
|
+
)
|
|
62
|
+
from async_ffmpeg.filters import (
|
|
63
|
+
ComplexFilterGraph,
|
|
64
|
+
Filter,
|
|
65
|
+
FilterChain,
|
|
66
|
+
FilterGraph,
|
|
67
|
+
afade,
|
|
68
|
+
amix,
|
|
69
|
+
anull,
|
|
70
|
+
aresample,
|
|
71
|
+
asetpts,
|
|
72
|
+
asplit,
|
|
73
|
+
atempo,
|
|
74
|
+
atrim,
|
|
75
|
+
concat,
|
|
76
|
+
crop,
|
|
77
|
+
drawtext,
|
|
78
|
+
escape_filter_param,
|
|
79
|
+
fps,
|
|
80
|
+
hflip,
|
|
81
|
+
loudnorm,
|
|
82
|
+
overlay,
|
|
83
|
+
pad,
|
|
84
|
+
pan,
|
|
85
|
+
rotate,
|
|
86
|
+
scale,
|
|
87
|
+
setpts,
|
|
88
|
+
split,
|
|
89
|
+
transpose,
|
|
90
|
+
vflip,
|
|
91
|
+
video_format,
|
|
92
|
+
volume,
|
|
93
|
+
vtrim,
|
|
94
|
+
)
|
|
95
|
+
from async_ffmpeg.hardware import (
|
|
96
|
+
DecoderInfo,
|
|
97
|
+
EncoderInfo,
|
|
98
|
+
HardwareAccel,
|
|
99
|
+
HardwareCapability,
|
|
100
|
+
HardwareVendor,
|
|
101
|
+
HWAccelConfig,
|
|
102
|
+
HWAccelType,
|
|
103
|
+
get_hwaccel_args,
|
|
104
|
+
)
|
|
105
|
+
from async_ffmpeg.models import (
|
|
106
|
+
AudioStream,
|
|
107
|
+
Chapter,
|
|
108
|
+
MediaFormat,
|
|
109
|
+
MediaInfo,
|
|
110
|
+
SilenceInterval,
|
|
111
|
+
StreamDisposition,
|
|
112
|
+
SubtitleStream,
|
|
113
|
+
VideoStream,
|
|
114
|
+
)
|
|
115
|
+
from async_ffmpeg.pipeline import MediaPipeline, WatermarkConfig
|
|
116
|
+
from async_ffmpeg.probe import FFprobe, parse_probe_json
|
|
117
|
+
from async_ffmpeg.process import ProcessResult, ProcessRunner
|
|
118
|
+
from async_ffmpeg.progress import ProgressInfo, ProgressParser, parse_progress_stream
|
|
119
|
+
|
|
120
|
+
__all__ = [
|
|
121
|
+
"DEFAULT_AUDIO_BITRATE",
|
|
122
|
+
"DEFAULT_FFMPEG_EXECUTABLE",
|
|
123
|
+
"DEFAULT_FFPROBE_EXECUTABLE",
|
|
124
|
+
"DEFAULT_LOGLEVEL",
|
|
125
|
+
"DEFAULT_MAX_CONCURRENT",
|
|
126
|
+
"DEFAULT_STATS_PERIOD",
|
|
127
|
+
"DEFAULT_VIDEO_CRF",
|
|
128
|
+
"DEFAULT_VIDEO_PRESET",
|
|
129
|
+
"AsyncFFmpegError",
|
|
130
|
+
"AudioCodec",
|
|
131
|
+
"AudioFormat",
|
|
132
|
+
"AudioStream",
|
|
133
|
+
"BinaryInfo",
|
|
134
|
+
"Chapter",
|
|
135
|
+
"CodecNotFoundError",
|
|
136
|
+
"CommandBuildError",
|
|
137
|
+
"ComplexFilterGraph",
|
|
138
|
+
"ConcatMethod",
|
|
139
|
+
"DecoderInfo",
|
|
140
|
+
"DownloadResultProtocol",
|
|
141
|
+
"EncoderInfo",
|
|
142
|
+
"FFmpegCancelledError",
|
|
143
|
+
"FFmpegClient",
|
|
144
|
+
"FFmpegCommand",
|
|
145
|
+
"FFmpegNotFoundError",
|
|
146
|
+
"FFmpegProcessError",
|
|
147
|
+
"FFmpegTimeoutError",
|
|
148
|
+
"FFprobe",
|
|
149
|
+
"FFprobeError",
|
|
150
|
+
"Filter",
|
|
151
|
+
"FilterChain",
|
|
152
|
+
"FilterError",
|
|
153
|
+
"FilterGraph",
|
|
154
|
+
"HWAccelConfig",
|
|
155
|
+
"HWAccelType",
|
|
156
|
+
"HardwareAccel",
|
|
157
|
+
"HardwareCapability",
|
|
158
|
+
"HardwareVendor",
|
|
159
|
+
"InvalidInputError",
|
|
160
|
+
"LogLevel",
|
|
161
|
+
"MediaFormat",
|
|
162
|
+
"MediaInfo",
|
|
163
|
+
"MediaInputProtocol",
|
|
164
|
+
"MediaPipeline",
|
|
165
|
+
"PathLike",
|
|
166
|
+
"ProcessResult",
|
|
167
|
+
"ProcessRunner",
|
|
168
|
+
"ProgressCallback",
|
|
169
|
+
"ProgressInfo",
|
|
170
|
+
"ProgressParser",
|
|
171
|
+
"Resolution",
|
|
172
|
+
"SilenceInterval",
|
|
173
|
+
"StderrCallback",
|
|
174
|
+
"StreamDisposition",
|
|
175
|
+
"StreamType",
|
|
176
|
+
"SubtitleStream",
|
|
177
|
+
"VideoCodec",
|
|
178
|
+
"VideoContainer",
|
|
179
|
+
"VideoPreset",
|
|
180
|
+
"VideoStream",
|
|
181
|
+
"WatermarkConfig",
|
|
182
|
+
"WatermarkPosition",
|
|
183
|
+
"__version__",
|
|
184
|
+
"afade",
|
|
185
|
+
"amix",
|
|
186
|
+
"anull",
|
|
187
|
+
"aresample",
|
|
188
|
+
"asetpts",
|
|
189
|
+
"asplit",
|
|
190
|
+
"atempo",
|
|
191
|
+
"atrim",
|
|
192
|
+
"clear_discovery_cache",
|
|
193
|
+
"concat",
|
|
194
|
+
"crop",
|
|
195
|
+
"drawtext",
|
|
196
|
+
"escape_filter_param",
|
|
197
|
+
"escape_filter_path",
|
|
198
|
+
"find_binary",
|
|
199
|
+
"find_ffmpeg",
|
|
200
|
+
"find_ffprobe",
|
|
201
|
+
"fps",
|
|
202
|
+
"get_binary_version",
|
|
203
|
+
"get_binary_version_sync",
|
|
204
|
+
"get_ffmpeg_info",
|
|
205
|
+
"get_ffprobe_info",
|
|
206
|
+
"get_hwaccel_args",
|
|
207
|
+
"get_logger",
|
|
208
|
+
"hflip",
|
|
209
|
+
"logger",
|
|
210
|
+
"loudnorm",
|
|
211
|
+
"normalize_path_for_ffmpeg",
|
|
212
|
+
"overlay",
|
|
213
|
+
"pad",
|
|
214
|
+
"pan",
|
|
215
|
+
"parse_probe_json",
|
|
216
|
+
"parse_progress_stream",
|
|
217
|
+
"rotate",
|
|
218
|
+
"scale",
|
|
219
|
+
"setpts",
|
|
220
|
+
"split",
|
|
221
|
+
"terminate_process_gracefully",
|
|
222
|
+
"transpose",
|
|
223
|
+
"vflip",
|
|
224
|
+
"video_format",
|
|
225
|
+
"volume",
|
|
226
|
+
"vtrim",
|
|
227
|
+
]
|