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.
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/PKG-INFO +1 -1
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress/better_ffmpeg_progress.py +47 -58
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress.egg-info/PKG-INFO +1 -1
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/setup.py +1 -1
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/LICENSE +0 -0
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/README.md +0 -0
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress/__init__.py +0 -0
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress/utils.py +0 -0
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress.egg-info/SOURCES.txt +0 -0
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress.egg-info/dependency_links.txt +0 -0
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress.egg-info/requires.txt +0 -0
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress.egg-info/top_level.txt +0 -0
- {better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/setup.cfg +0 -0
|
@@ -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
|
|
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
|
|
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
|
-
|
|
175
|
-
if
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
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
|
-
|
|
237
|
-
if
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
|
@@ -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.
|
|
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.",
|
|
File without changes
|
|
File without changes
|
{better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress/__init__.py
RENAMED
|
File without changes
|
{better_ffmpeg_progress-3.2.0 → better_ffmpeg_progress-3.2.1}/better_ffmpeg_progress/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|