better-ffmpeg-progress 3.0.0__tar.gz → 3.2.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: better-ffmpeg-progress
3
- Version: 3.0.0
3
+ Version: 3.2.0
4
4
  Summary: Run FFmpeg & see percentage progress + ETA.
5
5
  Home-page: https://github.com/CrypticSignal/better-ffmpeg-progress
6
6
  Author: GitHub.com/CrypticSignal
@@ -15,6 +15,7 @@ License-File: LICENSE
15
15
  Requires-Dist: ffmpeg-python
16
16
  Requires-Dist: psutil
17
17
  Requires-Dist: rich
18
+ Requires-Dist: tqdm
18
19
 
19
20
  <div align="center">
20
21
 
@@ -25,6 +26,8 @@ Requires-Dist: rich
25
26
 
26
27
  # Better FFmpeg Progress
27
28
  Runs an FFmpeg command and shows a progress bar with percentage progress, time elapsed and ETA.
29
+
30
+ The [Rich](https://github.com/Textualize/rich) library is used for the progress bar by default, [tqdm](https://github.com/tqdm/tqdm) will be used if you pass `use_tqdm=True` to the `run` method.
28
31
  </div>
29
32
 
30
33
  FFmpeg outputs something like:
@@ -38,7 +41,7 @@ Better FFmpeg Progress outputs something like:
38
41
  Where:
39
42
  - `Processing abc.webm` is the description of the progresss bar.
40
43
  - `23%` is the percentage progress.
41
- - `0:00:04` is the time (H:MM:SS) elapsed.
44
+ - `0:00:04` is the time elapsed.
42
45
  - `00:15` is the estimated time until the FFmpeg process completes.
43
46
 
44
47
  As you can see, the output of Better FFmpeg Progress is much more useful.
@@ -56,24 +59,17 @@ Here's a simple example:
56
59
  from better_ffmpeg_progress import FfmpegProcess
57
60
 
58
61
  process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:v", "libx265", "output.mp4"])
59
-
60
- # return_code will be 0 if the process was successful
62
+ # return_code will be 0 if the process completed successfully, otherwise it will be 1
61
63
  return_code = process.run()
62
-
63
- if return_code == 0:
64
- # Code to run if the process was successful
65
- pass
66
- else:
67
- # Code to run if the process was unsuccessful
68
- pass
69
64
  ```
70
65
  ## Optional Arguments
71
66
  An instance of the `FfmpegProcess` class takes the following **optional** arguments:
72
67
 
73
68
  - `ffmpeg_log_level` - Desired FFmpeg log level. Default: `"verbose"`
74
- - `ffmpeg_log_file` - The filepath to save the FFmpeg log to.
75
- - `print_detected_duration` - Print the detected duration of the input file. Default: `True`
69
+ - `ffmpeg_log_file` - The filepath to save the FFmpeg log to. Default: `<input filename>_log.txt`
70
+ - `print_detected_duration` - Print the detected duration of the input file. Default: `False`
76
71
  - `print_stderr_new_line` - If better progress information cannot be shown, print FFmpeg stderr in a new line instead of replacing the current line in the terminal. Default: `False`
77
72
 
78
- The `run` method takes the following **optional** argument:
73
+ The `run` method takes the following **optional** arguments:
79
74
  - `print_command` - Print the FFmpeg command being executed. Default: `False`
75
+ - `use_tqdm` - Use [tqdm](https://github.com/tqdm/tqdm) instead of [Rich](https://github.com/Textualize/rich) for the progress bar. Default: `False`
@@ -7,6 +7,8 @@
7
7
 
8
8
  # Better FFmpeg Progress
9
9
  Runs an FFmpeg command and shows a progress bar with percentage progress, time elapsed and ETA.
10
+
11
+ The [Rich](https://github.com/Textualize/rich) library is used for the progress bar by default, [tqdm](https://github.com/tqdm/tqdm) will be used if you pass `use_tqdm=True` to the `run` method.
10
12
  </div>
11
13
 
12
14
  FFmpeg outputs something like:
@@ -20,7 +22,7 @@ Better FFmpeg Progress outputs something like:
20
22
  Where:
21
23
  - `Processing abc.webm` is the description of the progresss bar.
22
24
  - `23%` is the percentage progress.
23
- - `0:00:04` is the time (H:MM:SS) elapsed.
25
+ - `0:00:04` is the time elapsed.
24
26
  - `00:15` is the estimated time until the FFmpeg process completes.
25
27
 
26
28
  As you can see, the output of Better FFmpeg Progress is much more useful.
@@ -38,24 +40,17 @@ Here's a simple example:
38
40
  from better_ffmpeg_progress import FfmpegProcess
39
41
 
40
42
  process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:v", "libx265", "output.mp4"])
41
-
42
- # return_code will be 0 if the process was successful
43
+ # return_code will be 0 if the process completed successfully, otherwise it will be 1
43
44
  return_code = process.run()
44
-
45
- if return_code == 0:
46
- # Code to run if the process was successful
47
- pass
48
- else:
49
- # Code to run if the process was unsuccessful
50
- pass
51
45
  ```
52
46
  ## Optional Arguments
53
47
  An instance of the `FfmpegProcess` class takes the following **optional** arguments:
54
48
 
55
49
  - `ffmpeg_log_level` - Desired FFmpeg log level. Default: `"verbose"`
56
- - `ffmpeg_log_file` - The filepath to save the FFmpeg log to.
57
- - `print_detected_duration` - Print the detected duration of the input file. Default: `True`
50
+ - `ffmpeg_log_file` - The filepath to save the FFmpeg log to. Default: `<input filename>_log.txt`
51
+ - `print_detected_duration` - Print the detected duration of the input file. Default: `False`
58
52
  - `print_stderr_new_line` - If better progress information cannot be shown, print FFmpeg stderr in a new line instead of replacing the current line in the terminal. Default: `False`
59
53
 
60
- The `run` method takes the following **optional** argument:
61
- - `print_command` - Print the FFmpeg command being executed. Default: `False`
54
+ The `run` method takes the following **optional** arguments:
55
+ - `print_command` - Print the FFmpeg command being executed. Default: `False`
56
+ - `use_tqdm` - Use [tqdm](https://github.com/tqdm/tqdm) instead of [Rich](https://github.com/Textualize/rich) for the progress bar. Default: `False`
@@ -18,6 +18,7 @@ from rich.progress import (
18
18
  TimeElapsedColumn,
19
19
  SpinnerColumn,
20
20
  )
21
+ from tqdm import tqdm
21
22
 
22
23
 
23
24
  class FfmpegLogLevel(Enum):
@@ -149,7 +150,127 @@ class FfmpegProcess:
149
150
  print(f"Error writing to log file: {e}")
150
151
  self.return_code = 1
151
152
 
152
- def run(self, print_command: bool = False) -> int:
153
+ def _use_rich(self, process, stdout_queue, stderr_queue) -> int:
154
+ with Progress(
155
+ SpinnerColumn(),
156
+ TextColumn("[progress.description]{task.description}"),
157
+ BarColumn(),
158
+ TaskProgressColumn(),
159
+ TimeElapsedColumn(),
160
+ TimeRemainingColumn(compact=True),
161
+ refresh_per_second=10,
162
+ ) as progress_bar:
163
+ task_id = None
164
+ if self._duration_secs:
165
+ task_id = progress_bar.add_task(
166
+ f"Processing {self._input_filepath.name}",
167
+ total=self._duration_secs,
168
+ )
169
+
170
+ while process.poll() is None:
171
+ # stdout
172
+ if task_id is not None and not stdout_queue.empty():
173
+ try:
174
+ line = stdout_queue.get_nowait()
175
+ if line.startswith(self.TIME_MS_PREFIX):
176
+ try:
177
+ value = int(line.split("=")[1]) / 1_000_000
178
+ if value <= self._duration_secs:
179
+ progress_bar.update(task_id, completed=value)
180
+ except ValueError:
181
+ pass
182
+ except Empty:
183
+ pass
184
+
185
+ # stderr
186
+ if not stderr_queue.empty():
187
+ try:
188
+ self._process_stderr(stderr_queue.get_nowait())
189
+ except Empty:
190
+ pass
191
+
192
+ # Process remaining stderr
193
+ while not stderr_queue.empty():
194
+ try:
195
+ self._process_stderr(stderr_queue.get_nowait())
196
+ except Empty:
197
+ break
198
+
199
+ progress_bar.columns = (
200
+ TextColumn("[progress.description]{task.description}"),
201
+ BarColumn(),
202
+ TaskProgressColumn(),
203
+ )
204
+
205
+ if process.returncode != 0:
206
+ progress_bar.update(
207
+ task_id,
208
+ description=f"The FFmpeg process did not complete successfully. Check out {self._ffmpeg_log_file} for details.",
209
+ )
210
+ return 1
211
+
212
+ progress_bar.update(
213
+ task_id,
214
+ description=f"✓ Processed {self._input_filepath.name}",
215
+ )
216
+
217
+ return 0
218
+
219
+ def _use_tqdm(self, process, stdout_queue, stderr_queue) -> int:
220
+ pbar = None
221
+ width, _ = os.get_terminal_size()
222
+
223
+ if self._duration_secs:
224
+ pbar = tqdm(
225
+ total=self._duration_secs,
226
+ desc=f"Processing {self._input_filepath.name}",
227
+ ncols=80,
228
+ dynamic_ncols=True if width < 80 else False,
229
+ bar_format="{desc} {bar} {percentage:.1f}% {elapsed} {remaining}",
230
+ )
231
+
232
+ while process.poll() is None:
233
+ # stdout
234
+ if pbar and not stdout_queue.empty():
235
+ try:
236
+ line = stdout_queue.get_nowait()
237
+ if line.startswith(self.TIME_MS_PREFIX):
238
+ try:
239
+ value = int(line.split("=")[1]) / 1_000_000
240
+ if value <= self._duration_secs:
241
+ pbar.n = value
242
+ pbar.refresh()
243
+ except ValueError:
244
+ pass
245
+ except Empty:
246
+ pass
247
+ # stderr
248
+ if not stderr_queue.empty():
249
+ try:
250
+ self._process_stderr(stderr_queue.get_nowait())
251
+ except Empty:
252
+ pass
253
+
254
+ # Process remaining stderr
255
+ while not stderr_queue.empty():
256
+ try:
257
+ self._process_stderr(stderr_queue.get_nowait())
258
+ except Empty:
259
+ break
260
+
261
+ if process.returncode != 0:
262
+ print(
263
+ f"The FFmpeg process did not complete successfully. Check out {self._ffmpeg_log_file} for details."
264
+ )
265
+ return 1
266
+
267
+ pbar.set_description(f"✓ Processed {self._input_filepath.name}")
268
+ if pbar:
269
+ pbar.close()
270
+
271
+ return 0
272
+
273
+ def run(self, print_command: bool = False, use_tqdm: bool = False) -> int:
153
274
  if hasattr(self, "return_code") and self.return_code != 0:
154
275
  return 1
155
276
 
@@ -206,61 +327,13 @@ class FfmpegProcess:
206
327
  ).start()
207
328
 
208
329
  try:
209
- with Progress(
210
- SpinnerColumn(),
211
- TextColumn("[progress.description]{task.description}"),
212
- BarColumn(),
213
- TaskProgressColumn(),
214
- TimeElapsedColumn(),
215
- TimeRemainingColumn(compact=True),
216
- refresh_per_second=10,
217
- ) as progress_bar:
218
- task_id = None
219
- if self._duration_secs:
220
- task_id = progress_bar.add_task(
221
- f"Processing {self._input_filepath.name}",
222
- total=self._duration_secs,
223
- )
224
-
225
- while process.poll() is None:
226
- # stdout
227
- if task_id is not None and not stdout_queue.empty():
228
- try:
229
- line = stdout_queue.get_nowait()
230
- if line.startswith(self.TIME_MS_PREFIX):
231
- try:
232
- value = int(line.split("=")[1]) / 1_000_000
233
- if value <= self._duration_secs:
234
- progress_bar.update(task_id, completed=value)
235
- except ValueError:
236
- pass
237
- except Empty:
238
- pass
239
-
240
- # stderr
241
- if not stderr_queue.empty():
242
- try:
243
- self._process_stderr(stderr_queue.get_nowait())
244
- except Empty:
245
- pass
246
-
247
- # Process remaining stderr
248
- while not stderr_queue.empty():
249
- try:
250
- self._process_stderr(stderr_queue.get_nowait())
251
- except Empty:
252
- break
253
-
254
- if process.returncode == 0 and task_id is not None:
255
- progress_bar.update(
256
- task_id, description=f"✓ Processed {self._input_filepath.name}"
257
- )
258
-
330
+ if use_tqdm:
331
+ return self._use_tqdm(process, stdout_queue, stderr_queue)
332
+ else:
333
+ return self._use_rich(process, stdout_queue, stderr_queue)
259
334
  except KeyboardInterrupt:
260
335
  try:
261
336
  psutil.Process(process.pid).terminate()
262
337
  except psutil.NoSuchProcess:
263
338
  pass
264
339
  return 1
265
-
266
- return 0 if process.returncode == 0 else 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: better-ffmpeg-progress
3
- Version: 3.0.0
3
+ Version: 3.2.0
4
4
  Summary: Run FFmpeg & see percentage progress + ETA.
5
5
  Home-page: https://github.com/CrypticSignal/better-ffmpeg-progress
6
6
  Author: GitHub.com/CrypticSignal
@@ -15,6 +15,7 @@ License-File: LICENSE
15
15
  Requires-Dist: ffmpeg-python
16
16
  Requires-Dist: psutil
17
17
  Requires-Dist: rich
18
+ Requires-Dist: tqdm
18
19
 
19
20
  <div align="center">
20
21
 
@@ -25,6 +26,8 @@ Requires-Dist: rich
25
26
 
26
27
  # Better FFmpeg Progress
27
28
  Runs an FFmpeg command and shows a progress bar with percentage progress, time elapsed and ETA.
29
+
30
+ The [Rich](https://github.com/Textualize/rich) library is used for the progress bar by default, [tqdm](https://github.com/tqdm/tqdm) will be used if you pass `use_tqdm=True` to the `run` method.
28
31
  </div>
29
32
 
30
33
  FFmpeg outputs something like:
@@ -38,7 +41,7 @@ Better FFmpeg Progress outputs something like:
38
41
  Where:
39
42
  - `Processing abc.webm` is the description of the progresss bar.
40
43
  - `23%` is the percentage progress.
41
- - `0:00:04` is the time (H:MM:SS) elapsed.
44
+ - `0:00:04` is the time elapsed.
42
45
  - `00:15` is the estimated time until the FFmpeg process completes.
43
46
 
44
47
  As you can see, the output of Better FFmpeg Progress is much more useful.
@@ -56,24 +59,17 @@ Here's a simple example:
56
59
  from better_ffmpeg_progress import FfmpegProcess
57
60
 
58
61
  process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:v", "libx265", "output.mp4"])
59
-
60
- # return_code will be 0 if the process was successful
62
+ # return_code will be 0 if the process completed successfully, otherwise it will be 1
61
63
  return_code = process.run()
62
-
63
- if return_code == 0:
64
- # Code to run if the process was successful
65
- pass
66
- else:
67
- # Code to run if the process was unsuccessful
68
- pass
69
64
  ```
70
65
  ## Optional Arguments
71
66
  An instance of the `FfmpegProcess` class takes the following **optional** arguments:
72
67
 
73
68
  - `ffmpeg_log_level` - Desired FFmpeg log level. Default: `"verbose"`
74
- - `ffmpeg_log_file` - The filepath to save the FFmpeg log to.
75
- - `print_detected_duration` - Print the detected duration of the input file. Default: `True`
69
+ - `ffmpeg_log_file` - The filepath to save the FFmpeg log to. Default: `<input filename>_log.txt`
70
+ - `print_detected_duration` - Print the detected duration of the input file. Default: `False`
76
71
  - `print_stderr_new_line` - If better progress information cannot be shown, print FFmpeg stderr in a new line instead of replacing the current line in the terminal. Default: `False`
77
72
 
78
- The `run` method takes the following **optional** argument:
73
+ The `run` method takes the following **optional** arguments:
79
74
  - `print_command` - Print the FFmpeg command being executed. Default: `False`
75
+ - `use_tqdm` - Use [tqdm](https://github.com/tqdm/tqdm) instead of [Rich](https://github.com/Textualize/rich) for the progress bar. Default: `False`
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as f:
5
5
 
6
6
  setuptools.setup(
7
7
  name="better-ffmpeg-progress",
8
- version="3.0.0",
8
+ version="3.2.0",
9
9
  author="GitHub.com/CrypticSignal",
10
10
  author_email="theaudiophile@outlook.com",
11
11
  description="Run FFmpeg & see percentage progress + ETA.",
@@ -13,7 +13,7 @@ setuptools.setup(
13
13
  long_description_content_type="text/markdown",
14
14
  url="https://github.com/CrypticSignal/better-ffmpeg-progress",
15
15
  packages=["better_ffmpeg_progress"],
16
- install_requires=["ffmpeg-python", "psutil", "rich"],
16
+ install_requires=["ffmpeg-python", "psutil", "rich", "tqdm"],
17
17
  python_requires=">=3.7",
18
18
  keywords=["ffmpeg", "progress"],
19
19
  classifiers=[