better-ffmpeg-progress 6.0.0__tar.gz → 7.0.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.
- {better_ffmpeg_progress-6.0.0/better_ffmpeg_progress.egg-info → better_ffmpeg_progress-7.0.0}/PKG-INFO +72 -10
- better_ffmpeg_progress-6.0.0/PKG-INFO → better_ffmpeg_progress-7.0.0/README.md +56 -28
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/__init__.py +3 -3
- better_ffmpeg_progress-7.0.0/better_ffmpeg_progress/better_ffmpeg_progress.py +423 -0
- better_ffmpeg_progress-7.0.0/better_ffmpeg_progress/exceptions.py +38 -0
- better_ffmpeg_progress-7.0.0/better_ffmpeg_progress/progress_bars.py +197 -0
- better_ffmpeg_progress-7.0.0/better_ffmpeg_progress/terminate_process.py +70 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/utils.py +101 -69
- better_ffmpeg_progress-6.0.0/README.md → better_ffmpeg_progress-7.0.0/better_ffmpeg_progress.egg-info/PKG-INFO +90 -6
- better_ffmpeg_progress-7.0.0/better_ffmpeg_progress.egg-info/requires.txt +14 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/pyproject.toml +16 -3
- better_ffmpeg_progress-7.0.0/tests/test_ffmpeg_process.py +320 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/tests/test_utils.py +83 -14
- better_ffmpeg_progress-6.0.0/better_ffmpeg_progress/better_ffmpeg_progress.py +0 -281
- better_ffmpeg_progress-6.0.0/better_ffmpeg_progress/exceptions.py +0 -14
- better_ffmpeg_progress-6.0.0/better_ffmpeg_progress/progress_bars.py +0 -192
- better_ffmpeg_progress-6.0.0/better_ffmpeg_progress/terminate_process.py +0 -244
- better_ffmpeg_progress-6.0.0/better_ffmpeg_progress.egg-info/requires.txt +0 -6
- better_ffmpeg_progress-6.0.0/tests/test_ffmpeg_process.py +0 -152
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/LICENSE +0 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/enums.py +0 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/py.typed +0 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress.egg-info/SOURCES.txt +0 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress.egg-info/dependency_links.txt +0 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress.egg-info/top_level.txt +0 -0
- {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: better-ffmpeg-progress
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0
|
|
4
4
|
Summary: Run FFmpeg & see percentage progress + ETA.
|
|
5
5
|
Author-email: "GitHub.com/CrypticSignal" <theaudiophile@outlook.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -8,16 +8,28 @@ Project-URL: Homepage, https://github.com/CrypticSignal/better-ffmpeg-progress
|
|
|
8
8
|
Project-URL: Changelog, https://github.com/CrypticSignal/better-ffmpeg-progress/blob/main/CHANGELOG.md
|
|
9
9
|
Keywords: ffmpeg,progress
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Topic :: Multimedia :: Video :: Conversion
|
|
11
17
|
Classifier: Operating System :: OS Independent
|
|
12
18
|
Classifier: Typing :: Typed
|
|
13
|
-
Requires-Python: >=3.
|
|
19
|
+
Requires-Python: >=3.11
|
|
14
20
|
Description-Content-Type: text/markdown
|
|
15
21
|
License-File: LICENSE
|
|
16
|
-
Requires-Dist: psutil
|
|
17
22
|
Requires-Dist: rich
|
|
18
|
-
|
|
23
|
+
Provides-Extra: tqdm
|
|
24
|
+
Requires-Dist: tqdm; extra == "tqdm"
|
|
19
25
|
Provides-Extra: test
|
|
20
26
|
Requires-Dist: pytest; extra == "test"
|
|
27
|
+
Requires-Dist: tqdm; extra == "test"
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: better-ffmpeg-progress[test]; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff; extra == "dev"
|
|
32
|
+
Requires-Dist: types-tqdm; extra == "dev"
|
|
21
33
|
Dynamic: license-file
|
|
22
34
|
|
|
23
35
|
<div align="center">
|
|
@@ -141,28 +153,78 @@ An instance of `FfmpegProcess` accepts the following optional arguments:
|
|
|
141
153
|
* `duration_override` — Specify input file duration in seconds to use for progress calculation, instead of trying to detect this automatically with FFprobe. Default: `None`.
|
|
142
154
|
* `use_tqdm` — Use tqdm instead of Rich for the progress bar. Default: `False`.
|
|
143
155
|
* `overwrite` — What to do if the output file already exists: `True` overwrites it, `False` raises `FfmpegCommandError`, and `None` asks whether to overwrite it. Ignored if the command contains `-y` or `-n`. Default: `None`.
|
|
156
|
+
* `quiet` — Do not show a progress bar or status messages. Default: `False`.
|
|
157
|
+
* `progress_callback` — A function to call each time FFmpeg reports its progress. See [Progress callback](#progress-callback). Default: `None`.
|
|
158
|
+
* `delete_log_on_success` — Delete the FFmpeg log file if FFmpeg succeeds. Default: `False`.
|
|
159
|
+
|
|
160
|
+
Creating an `FfmpegProcess` only validates the command. FFprobe is run, and you are asked whether to overwrite an existing output file, when `run()` is called.
|
|
144
161
|
|
|
145
162
|
The `run` method accepts the following optional argument:
|
|
146
163
|
* `print_command` — Print the FFmpeg command being executed. Default: `False`.
|
|
147
164
|
|
|
148
165
|
## Using tqdm
|
|
149
|
-
By default, the [Rich](https://github.com/Textualize/rich) library is used to display a progress bar. [tqdm](https://github.com/tqdm/tqdm) can be used instead by passing `use_tqdm=True
|
|
166
|
+
By default, the [Rich](https://github.com/Textualize/rich) library is used to display a progress bar. [tqdm](https://github.com/tqdm/tqdm) can be used instead by passing `use_tqdm=True`. tqdm is an optional dependency, installed with:
|
|
167
|
+
```bash
|
|
168
|
+
pip install "better-ffmpeg-progress[tqdm]" --upgrade
|
|
169
|
+
```
|
|
150
170
|
```python
|
|
151
171
|
process = FfmpegProcess(command, use_tqdm=True)
|
|
152
172
|
process.run()
|
|
153
173
|
```
|
|
174
|
+
|
|
175
|
+
## Progress callback
|
|
176
|
+
To show progress in your own UI (e.g. a GUI or a web app), pass a function as `progress_callback`. It is called with the number of seconds processed, the expected output duration in seconds (`None` if it is unknown) and the current output size in MB. Combine it with `quiet=True` to hide the progress bar:
|
|
177
|
+
```python
|
|
178
|
+
def on_progress(secs: float, duration: float | None, size_mb: float) -> None:
|
|
179
|
+
if duration:
|
|
180
|
+
print(f"{secs / duration:.0%}")
|
|
181
|
+
|
|
182
|
+
FfmpegProcess(command, quiet=True, progress_callback=on_progress).run()
|
|
183
|
+
```
|
|
184
|
+
If the callback raises an exception, FFmpeg is stopped and the exception is propagated by `run()`.
|
|
185
|
+
|
|
186
|
+
## Errors
|
|
187
|
+
All exceptions raised by the package are subclasses of `FfmpegProcessError`, which has these attributes:
|
|
188
|
+
* `returncode` — FFmpeg's exit code, or `None` if FFmpeg was not started or had not exited.
|
|
189
|
+
* `log_file` — The path or file object that FFmpeg's log was written to.
|
|
190
|
+
|
|
191
|
+
Pressing Ctrl+C raises `FfmpegProcessInterruptedError`. FFmpeg is first asked to stop the way pressing `q` does, so it can finish writing the output file, e.g. an MP4 file stays playable. If it does not stop within 5 seconds, it is terminated.
|
|
192
|
+
|
|
193
|
+
## Logging
|
|
194
|
+
Warnings, such as when the input duration cannot be detected, are logged with the `logging` module using the `better_ffmpeg_progress` logger. Without any logging configuration, Python prints them to standard error. To hide them:
|
|
195
|
+
```python
|
|
196
|
+
import logging
|
|
197
|
+
|
|
198
|
+
logging.getLogger("better_ffmpeg_progress").setLevel(logging.ERROR)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Writing to standard output
|
|
202
|
+
On Linux and macOS, the output can be written to standard output, e.g. `-f mpegts -`, to pipe it to another program. The progress bar is then shown on standard error. This is not supported on Windows, where FFmpeg's progress is read from its standard output.
|
|
203
|
+
|
|
204
|
+
## Duration detection
|
|
205
|
+
FFprobe is looked for next to the FFmpeg executable first (e.g. `/opt/ffmpeg/bin/ffprobe` for `/opt/ffmpeg/bin/ffmpeg`), then in `PATH`. If it does not finish within 30 seconds, e.g. for an unresponsive URL, the duration is treated as unknown.
|
|
154
206
|
## Limitations
|
|
155
207
|
- Progress is calculated from the duration of the first input (the first `-i`).
|
|
156
208
|
- The last argument of the command is treated as the output file, e.g. when checking whether it already exists. With multiple outputs, only the last one is checked.
|
|
157
209
|
|
|
158
210
|
## Development
|
|
159
|
-
Install the package in editable mode with the
|
|
211
|
+
Install the package in editable mode with the development dependencies, then run the tests (FFmpeg and FFprobe must be installed):
|
|
160
212
|
```bash
|
|
161
|
-
pip install -e ".[
|
|
213
|
+
pip install -e ".[dev]"
|
|
162
214
|
```
|
|
163
215
|
```bash
|
|
164
216
|
pytest
|
|
165
217
|
```
|
|
218
|
+
Lint, format and type-check the code like CI does:
|
|
219
|
+
```bash
|
|
220
|
+
ruff check .
|
|
221
|
+
```
|
|
222
|
+
```bash
|
|
223
|
+
ruff format --check better_ffmpeg_progress tests test.py
|
|
224
|
+
```
|
|
225
|
+
```bash
|
|
226
|
+
mypy
|
|
227
|
+
```
|
|
166
228
|
`test.py` is a standalone example that encodes a test pattern and shows the progress bar.
|
|
167
229
|
|
|
168
230
|
## Publishing
|
|
@@ -170,7 +232,7 @@ Update `__version__` in `better_ffmpeg_progress/__init__.py` and add an entry to
|
|
|
170
232
|
|
|
171
233
|
One-time setup:
|
|
172
234
|
```bash
|
|
173
|
-
pip install --upgrade build twine pkginfo
|
|
235
|
+
python -m pip install --upgrade build twine pkginfo
|
|
174
236
|
```
|
|
175
237
|
|
|
176
238
|
Then, for each release:
|
|
@@ -181,8 +243,8 @@ rm -rf dist
|
|
|
181
243
|
python -m build
|
|
182
244
|
```
|
|
183
245
|
```bash
|
|
184
|
-
twine check dist/*
|
|
246
|
+
python -m twine check dist/*
|
|
185
247
|
```
|
|
186
248
|
```bash
|
|
187
|
-
twine upload dist/*
|
|
249
|
+
python -m twine upload dist/*
|
|
188
250
|
```
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: better-ffmpeg-progress
|
|
3
|
-
Version: 6.0.0
|
|
4
|
-
Summary: Run FFmpeg & see percentage progress + ETA.
|
|
5
|
-
Author-email: "GitHub.com/CrypticSignal" <theaudiophile@outlook.com>
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/CrypticSignal/better-ffmpeg-progress
|
|
8
|
-
Project-URL: Changelog, https://github.com/CrypticSignal/better-ffmpeg-progress/blob/main/CHANGELOG.md
|
|
9
|
-
Keywords: ffmpeg,progress
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Operating System :: OS Independent
|
|
12
|
-
Classifier: Typing :: Typed
|
|
13
|
-
Requires-Python: >=3.9
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
License-File: LICENSE
|
|
16
|
-
Requires-Dist: psutil
|
|
17
|
-
Requires-Dist: rich
|
|
18
|
-
Requires-Dist: tqdm
|
|
19
|
-
Provides-Extra: test
|
|
20
|
-
Requires-Dist: pytest; extra == "test"
|
|
21
|
-
Dynamic: license-file
|
|
22
|
-
|
|
23
1
|
<div align="center">
|
|
24
2
|
|
|
25
3
|
# Better FFmpeg Progress
|
|
@@ -141,28 +119,78 @@ An instance of `FfmpegProcess` accepts the following optional arguments:
|
|
|
141
119
|
* `duration_override` — Specify input file duration in seconds to use for progress calculation, instead of trying to detect this automatically with FFprobe. Default: `None`.
|
|
142
120
|
* `use_tqdm` — Use tqdm instead of Rich for the progress bar. Default: `False`.
|
|
143
121
|
* `overwrite` — What to do if the output file already exists: `True` overwrites it, `False` raises `FfmpegCommandError`, and `None` asks whether to overwrite it. Ignored if the command contains `-y` or `-n`. Default: `None`.
|
|
122
|
+
* `quiet` — Do not show a progress bar or status messages. Default: `False`.
|
|
123
|
+
* `progress_callback` — A function to call each time FFmpeg reports its progress. See [Progress callback](#progress-callback). Default: `None`.
|
|
124
|
+
* `delete_log_on_success` — Delete the FFmpeg log file if FFmpeg succeeds. Default: `False`.
|
|
125
|
+
|
|
126
|
+
Creating an `FfmpegProcess` only validates the command. FFprobe is run, and you are asked whether to overwrite an existing output file, when `run()` is called.
|
|
144
127
|
|
|
145
128
|
The `run` method accepts the following optional argument:
|
|
146
129
|
* `print_command` — Print the FFmpeg command being executed. Default: `False`.
|
|
147
130
|
|
|
148
131
|
## Using tqdm
|
|
149
|
-
By default, the [Rich](https://github.com/Textualize/rich) library is used to display a progress bar. [tqdm](https://github.com/tqdm/tqdm) can be used instead by passing `use_tqdm=True
|
|
132
|
+
By default, the [Rich](https://github.com/Textualize/rich) library is used to display a progress bar. [tqdm](https://github.com/tqdm/tqdm) can be used instead by passing `use_tqdm=True`. tqdm is an optional dependency, installed with:
|
|
133
|
+
```bash
|
|
134
|
+
pip install "better-ffmpeg-progress[tqdm]" --upgrade
|
|
135
|
+
```
|
|
150
136
|
```python
|
|
151
137
|
process = FfmpegProcess(command, use_tqdm=True)
|
|
152
138
|
process.run()
|
|
153
139
|
```
|
|
140
|
+
|
|
141
|
+
## Progress callback
|
|
142
|
+
To show progress in your own UI (e.g. a GUI or a web app), pass a function as `progress_callback`. It is called with the number of seconds processed, the expected output duration in seconds (`None` if it is unknown) and the current output size in MB. Combine it with `quiet=True` to hide the progress bar:
|
|
143
|
+
```python
|
|
144
|
+
def on_progress(secs: float, duration: float | None, size_mb: float) -> None:
|
|
145
|
+
if duration:
|
|
146
|
+
print(f"{secs / duration:.0%}")
|
|
147
|
+
|
|
148
|
+
FfmpegProcess(command, quiet=True, progress_callback=on_progress).run()
|
|
149
|
+
```
|
|
150
|
+
If the callback raises an exception, FFmpeg is stopped and the exception is propagated by `run()`.
|
|
151
|
+
|
|
152
|
+
## Errors
|
|
153
|
+
All exceptions raised by the package are subclasses of `FfmpegProcessError`, which has these attributes:
|
|
154
|
+
* `returncode` — FFmpeg's exit code, or `None` if FFmpeg was not started or had not exited.
|
|
155
|
+
* `log_file` — The path or file object that FFmpeg's log was written to.
|
|
156
|
+
|
|
157
|
+
Pressing Ctrl+C raises `FfmpegProcessInterruptedError`. FFmpeg is first asked to stop the way pressing `q` does, so it can finish writing the output file, e.g. an MP4 file stays playable. If it does not stop within 5 seconds, it is terminated.
|
|
158
|
+
|
|
159
|
+
## Logging
|
|
160
|
+
Warnings, such as when the input duration cannot be detected, are logged with the `logging` module using the `better_ffmpeg_progress` logger. Without any logging configuration, Python prints them to standard error. To hide them:
|
|
161
|
+
```python
|
|
162
|
+
import logging
|
|
163
|
+
|
|
164
|
+
logging.getLogger("better_ffmpeg_progress").setLevel(logging.ERROR)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Writing to standard output
|
|
168
|
+
On Linux and macOS, the output can be written to standard output, e.g. `-f mpegts -`, to pipe it to another program. The progress bar is then shown on standard error. This is not supported on Windows, where FFmpeg's progress is read from its standard output.
|
|
169
|
+
|
|
170
|
+
## Duration detection
|
|
171
|
+
FFprobe is looked for next to the FFmpeg executable first (e.g. `/opt/ffmpeg/bin/ffprobe` for `/opt/ffmpeg/bin/ffmpeg`), then in `PATH`. If it does not finish within 30 seconds, e.g. for an unresponsive URL, the duration is treated as unknown.
|
|
154
172
|
## Limitations
|
|
155
173
|
- Progress is calculated from the duration of the first input (the first `-i`).
|
|
156
174
|
- The last argument of the command is treated as the output file, e.g. when checking whether it already exists. With multiple outputs, only the last one is checked.
|
|
157
175
|
|
|
158
176
|
## Development
|
|
159
|
-
Install the package in editable mode with the
|
|
177
|
+
Install the package in editable mode with the development dependencies, then run the tests (FFmpeg and FFprobe must be installed):
|
|
160
178
|
```bash
|
|
161
|
-
pip install -e ".[
|
|
179
|
+
pip install -e ".[dev]"
|
|
162
180
|
```
|
|
163
181
|
```bash
|
|
164
182
|
pytest
|
|
165
183
|
```
|
|
184
|
+
Lint, format and type-check the code like CI does:
|
|
185
|
+
```bash
|
|
186
|
+
ruff check .
|
|
187
|
+
```
|
|
188
|
+
```bash
|
|
189
|
+
ruff format --check better_ffmpeg_progress tests test.py
|
|
190
|
+
```
|
|
191
|
+
```bash
|
|
192
|
+
mypy
|
|
193
|
+
```
|
|
166
194
|
`test.py` is a standalone example that encodes a test pattern and shows the progress bar.
|
|
167
195
|
|
|
168
196
|
## Publishing
|
|
@@ -170,7 +198,7 @@ Update `__version__` in `better_ffmpeg_progress/__init__.py` and add an entry to
|
|
|
170
198
|
|
|
171
199
|
One-time setup:
|
|
172
200
|
```bash
|
|
173
|
-
pip install --upgrade build twine pkginfo
|
|
201
|
+
python -m pip install --upgrade build twine pkginfo
|
|
174
202
|
```
|
|
175
203
|
|
|
176
204
|
Then, for each release:
|
|
@@ -181,8 +209,8 @@ rm -rf dist
|
|
|
181
209
|
python -m build
|
|
182
210
|
```
|
|
183
211
|
```bash
|
|
184
|
-
twine check dist/*
|
|
212
|
+
python -m twine check dist/*
|
|
185
213
|
```
|
|
186
214
|
```bash
|
|
187
|
-
twine upload dist/*
|
|
215
|
+
python -m twine upload dist/*
|
|
188
216
|
```
|
{better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/__init__.py
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
__version__ = "
|
|
1
|
+
__version__ = "7.0.0"
|
|
2
2
|
|
|
3
3
|
from .better_ffmpeg_progress import FfmpegProcess
|
|
4
4
|
from .enums import FfmpegLogLevel
|
|
5
5
|
from .exceptions import (
|
|
6
|
-
FfmpegProcessError,
|
|
7
6
|
FfmpegCommandError,
|
|
8
|
-
|
|
7
|
+
FfmpegProcessError,
|
|
9
8
|
FfmpegProcessInterruptedError,
|
|
9
|
+
FfmpegProcessUserCancelledError,
|
|
10
10
|
)
|
|
11
11
|
|
|
12
12
|
__all__ = [
|