better-ffmpeg-progress 3.2.0__tar.gz → 3.2.1__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.2.0
3
+ Version: 3.2.1
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
@@ -2,10 +2,11 @@ from enum import Enum
2
2
  import os
3
3
  from pathlib import Path
4
4
  import psutil
5
- from queue import Empty, Queue
5
+ from queue import Queue
6
6
  import shutil
7
7
  import subprocess
8
8
  from threading import Thread
9
+ from time import sleep
9
10
  from typing import List, Optional, Union
10
11
 
11
12
  from ffmpeg import probe
@@ -34,8 +35,6 @@ class FfmpegLogLevel(Enum):
34
35
 
35
36
 
36
37
  class FfmpegProcess:
37
- TIME_MS_PREFIX = "out_time_ms="
38
-
39
38
  @staticmethod
40
39
  def _read_pipe(pipe: subprocess.PIPE, queue: Queue, stdout: bool = False) -> None:
41
40
  """Read from pipe and put lines into queue."""
@@ -120,7 +119,7 @@ class FfmpegProcess:
120
119
  probe_data = probe(self._input_filepath)
121
120
  self._duration_secs = float(probe_data["format"]["duration"])
122
121
  if self._print_detected_duration:
123
- print(f"Detected duration: {self._duration_secs:.2f} seconds")
122
+ print(f"Detected duration: {self._duration_secs} seconds")
124
123
  except Exception:
125
124
  self._duration_secs = None
126
125
 
@@ -131,8 +130,6 @@ class FfmpegProcess:
131
130
  self._ffmpeg_log_level,
132
131
  "-progress",
133
132
  "pipe:1",
134
- "-stats_period",
135
- "0.1",
136
133
  "-nostats",
137
134
  *command[1:],
138
135
  ]
@@ -161,6 +158,7 @@ class FfmpegProcess:
161
158
  refresh_per_second=10,
162
159
  ) as progress_bar:
163
160
  task_id = None
161
+
164
162
  if self._duration_secs:
165
163
  task_id = progress_bar.add_task(
166
164
  f"Processing {self._input_filepath.name}",
@@ -168,39 +166,36 @@ class FfmpegProcess:
168
166
  )
169
167
 
170
168
  while process.poll() is None:
169
+ # FFmpeg only updates encoding progress/statistics every 0.5 seconds
170
+ sleep(0.5)
171
171
  # stdout
172
172
  if task_id is not None and not stdout_queue.empty():
173
+ line = stdout_queue.get()
173
174
  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:
175
+ value = int(line.split("=")[1]) / 1_000_000
176
+ if value <= self._duration_secs:
177
+ progress_bar.update(task_id, completed=value)
178
+ except ValueError:
183
179
  pass
184
-
185
180
  # stderr
186
181
  if not stderr_queue.empty():
187
- try:
188
- self._process_stderr(stderr_queue.get_nowait())
189
- except Empty:
190
- pass
182
+ self._process_stderr(stderr_queue.get())
183
+
184
+ if process.returncode == 0 and task_id is not None:
185
+ progress_bar.update(task_id, completed=self._duration_secs)
186
+ progress_bar.columns = (
187
+ TextColumn("[progress.description]{task.description}"),
188
+ BarColumn(),
189
+ TaskProgressColumn(),
190
+ )
191
+ progress_bar.update(
192
+ task_id,
193
+ description=f"✓ Processed {self._input_filepath.name}",
194
+ )
191
195
 
192
196
  # Process remaining stderr
193
197
  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
- )
198
+ self._process_stderr(stderr_queue.get())
204
199
 
205
200
  if process.returncode != 0:
206
201
  progress_bar.update(
@@ -209,11 +204,6 @@ class FfmpegProcess:
209
204
  )
210
205
  return 1
211
206
 
212
- progress_bar.update(
213
- task_id,
214
- description=f"✓ Processed {self._input_filepath.name}",
215
- )
216
-
217
207
  return 0
218
208
 
219
209
  def _use_tqdm(self, process, stdout_queue, stderr_queue) -> int:
@@ -230,33 +220,32 @@ class FfmpegProcess:
230
220
  )
231
221
 
232
222
  while process.poll() is None:
223
+ # FFmpeg only updates encoding progress/statistics every 0.5 seconds
224
+ sleep(0.5)
233
225
  # stdout
234
226
  if pbar and not stdout_queue.empty():
227
+ line = stdout_queue.get()
235
228
  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:
229
+ value = int(line.split("=")[1]) / 1_000_000
230
+ if value <= self._duration_secs:
231
+ pbar.n = value
232
+ pbar.refresh()
233
+ except ValueError:
246
234
  pass
247
235
  # stderr
248
236
  if not stderr_queue.empty():
249
- try:
250
- self._process_stderr(stderr_queue.get_nowait())
251
- except Empty:
252
- pass
237
+ self._process_stderr(stderr_queue.get())
238
+
239
+ if process.returncode == 0 and pbar:
240
+ pbar.n = self._duration_secs
241
+ pbar.set_description(f"✓ Processed {self._input_filepath.name}")
242
+
243
+ if pbar:
244
+ pbar.close()
253
245
 
254
246
  # Process remaining stderr
255
247
  while not stderr_queue.empty():
256
- try:
257
- self._process_stderr(stderr_queue.get_nowait())
258
- except Empty:
259
- break
248
+ self._process_stderr(stderr_queue.get())
260
249
 
261
250
  if process.returncode != 0:
262
251
  print(
@@ -264,13 +253,13 @@ class FfmpegProcess:
264
253
  )
265
254
  return 1
266
255
 
267
- pbar.set_description(f"✓ Processed {self._input_filepath.name}")
268
- if pbar:
269
- pbar.close()
270
-
271
256
  return 0
272
257
 
273
- def run(self, print_command: bool = False, use_tqdm: bool = False) -> int:
258
+ def run(
259
+ self,
260
+ print_command: bool = False,
261
+ use_tqdm: bool = False,
262
+ ) -> int:
274
263
  if hasattr(self, "return_code") and self.return_code != 0:
275
264
  return 1
276
265
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: better-ffmpeg-progress
3
- Version: 3.2.0
3
+ Version: 3.2.1
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
@@ -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.2.0",
8
+ version="3.2.1",
9
9
  author="GitHub.com/CrypticSignal",
10
10
  author_email="theaudiophile@outlook.com",
11
11
  description="Run FFmpeg & see percentage progress + ETA.",