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.
Files changed (26) hide show
  1. {better_ffmpeg_progress-6.0.0/better_ffmpeg_progress.egg-info → better_ffmpeg_progress-7.0.0}/PKG-INFO +72 -10
  2. better_ffmpeg_progress-6.0.0/PKG-INFO → better_ffmpeg_progress-7.0.0/README.md +56 -28
  3. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/__init__.py +3 -3
  4. better_ffmpeg_progress-7.0.0/better_ffmpeg_progress/better_ffmpeg_progress.py +423 -0
  5. better_ffmpeg_progress-7.0.0/better_ffmpeg_progress/exceptions.py +38 -0
  6. better_ffmpeg_progress-7.0.0/better_ffmpeg_progress/progress_bars.py +197 -0
  7. better_ffmpeg_progress-7.0.0/better_ffmpeg_progress/terminate_process.py +70 -0
  8. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/utils.py +101 -69
  9. better_ffmpeg_progress-6.0.0/README.md → better_ffmpeg_progress-7.0.0/better_ffmpeg_progress.egg-info/PKG-INFO +90 -6
  10. better_ffmpeg_progress-7.0.0/better_ffmpeg_progress.egg-info/requires.txt +14 -0
  11. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/pyproject.toml +16 -3
  12. better_ffmpeg_progress-7.0.0/tests/test_ffmpeg_process.py +320 -0
  13. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/tests/test_utils.py +83 -14
  14. better_ffmpeg_progress-6.0.0/better_ffmpeg_progress/better_ffmpeg_progress.py +0 -281
  15. better_ffmpeg_progress-6.0.0/better_ffmpeg_progress/exceptions.py +0 -14
  16. better_ffmpeg_progress-6.0.0/better_ffmpeg_progress/progress_bars.py +0 -192
  17. better_ffmpeg_progress-6.0.0/better_ffmpeg_progress/terminate_process.py +0 -244
  18. better_ffmpeg_progress-6.0.0/better_ffmpeg_progress.egg-info/requires.txt +0 -6
  19. better_ffmpeg_progress-6.0.0/tests/test_ffmpeg_process.py +0 -152
  20. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/LICENSE +0 -0
  21. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/enums.py +0 -0
  22. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress/py.typed +0 -0
  23. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress.egg-info/SOURCES.txt +0 -0
  24. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress.egg-info/dependency_links.txt +0 -0
  25. {better_ffmpeg_progress-6.0.0 → better_ffmpeg_progress-7.0.0}/better_ffmpeg_progress.egg-info/top_level.txt +0 -0
  26. {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: 6.0.0
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.9
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
- Requires-Dist: tqdm
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 test dependencies, then run the tests (FFmpeg and FFprobe must be installed):
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 ".[test]"
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 test dependencies, then run the tests (FFmpeg and FFprobe must be installed):
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 ".[test]"
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
  ```
@@ -1,12 +1,12 @@
1
- __version__ = "6.0.0"
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
- FfmpegProcessUserCancelledError,
7
+ FfmpegProcessError,
9
8
  FfmpegProcessInterruptedError,
9
+ FfmpegProcessUserCancelledError,
10
10
  )
11
11
 
12
12
  __all__ = [