better-ffmpeg-progress 3.2.4__tar.gz → 3.2.6__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.4
3
+ Version: 3.2.6
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
@@ -3,7 +3,6 @@ import os
3
3
  from pathlib import Path
4
4
  import psutil
5
5
  import shutil
6
- from signal import CTRL_BREAK_EVENT
7
6
  import subprocess
8
7
  from typing import List, Optional, Union
9
8
 
@@ -62,27 +61,26 @@ class FfmpegProcess:
62
61
  return True
63
62
 
64
63
  def _should_overwrite(self):
65
- if self._output_filepath.exists() and "-y" not in self._ffmpeg_command:
66
- try:
67
- if (
68
- input(
69
- f"{self._output_filepath} already exists. Overwrite? [Y/N]: "
70
- ).lower()
71
- != "y"
72
- ):
73
- print(
74
- "FFmpeg process cancelled. Output file exists and overwrite declined."
75
- )
76
- return False
77
- except EOFError:
78
- print("Input error. FFmpeg process cancelled.")
79
- return False
80
- except KeyboardInterrupt:
81
- print("[KeyboardInterrupt] FFmpeg process cancelled.")
64
+ try:
65
+ if (
66
+ input(
67
+ f"{self._output_filepath} already exists. Overwrite? [Y/N]: "
68
+ ).lower()
69
+ != "y"
70
+ ):
71
+ print(
72
+ "FFmpeg process cancelled. Output file exists and overwrite declined."
73
+ )
82
74
  return False
75
+ except EOFError:
76
+ print("Input error. FFmpeg process cancelled.")
77
+ return False
78
+ except KeyboardInterrupt:
79
+ print("[KeyboardInterrupt] FFmpeg process cancelled.")
80
+ return False
83
81
 
84
- self._ffmpeg_command.insert(1, "-y")
85
- return True
82
+ self._ffmpeg_command.insert(1, "-y")
83
+ return True
86
84
 
87
85
  @staticmethod
88
86
  def _get_duration(filepath: Path) -> Optional[float]:
@@ -156,9 +154,9 @@ class FfmpegProcess:
156
154
  ]
157
155
  self._ffmpeg_command.extend(command[1:])
158
156
 
159
- if not self._should_overwrite():
160
- self._return_code = 1
161
- return
157
+ if self._output_filepath.exists() and "-y" not in self._ffmpeg_command:
158
+ if not self._should_overwrite():
159
+ self._return_code = 1
162
160
 
163
161
  def _use_rich(self, process) -> int:
164
162
  task_id = None
@@ -302,13 +300,10 @@ class FfmpegProcess:
302
300
  else self._use_rich(self._process)
303
301
  )
304
302
  except KeyboardInterrupt:
305
- print("\n[KeyboardInterrupt] Terminating FFmpeg process...")
303
+ print("\n[KeyboardInterrupt] Terminating the FFmpeg process...")
306
304
  self._terminate()
307
- print("Done!")
305
+ print("Exiting Better FFmpeg Progress.")
308
306
  return 1
309
- finally:
310
- if self._process and self._process.poll() is None:
311
- self._terminate()
312
307
 
313
308
  def _terminate(self):
314
309
  if not self._process or self._process.poll() is not None:
@@ -316,35 +311,60 @@ class FfmpegProcess:
316
311
 
317
312
  try:
318
313
  proc = psutil.Process(self._process.pid)
319
- children = proc.children(recursive=True)
320
-
321
- # Windows. Use CTRL_BREAK_EVENT to terminate entire process group
322
- if os.name == "nt":
323
- if self._shell_needed:
324
- # If running under a shell, terminate shell first
325
- proc.terminate()
326
- else:
327
- # Send CTRL_BREAK_EVENT to entire process group
328
- os.kill(self._process.pid, CTRL_BREAK_EVENT)
329
- # Unix
330
- else:
331
- for child in children:
332
- try:
333
- child.terminate()
334
- except psutil.NoSuchProcess:
335
- pass
314
+ except (psutil.NoSuchProcess, psutil.ZombieProcess):
315
+ return
316
+
317
+ children = proc.children(recursive=True)
318
+ if children:
319
+ print(f"Found {len(children)} child process(es).")
320
+
321
+ # Windows
322
+ if os.name == "nt":
323
+ try:
324
+ # On Windows, terminate() and kill() are equivalent
336
325
  proc.terminate()
326
+ except psutil.NoSuchProcess:
327
+ return
328
+ except psutil.AccessDenied:
329
+ print("Permission error when trying to terminate the FFmpeg process.")
330
+ return
331
+
332
+ # Unix/Linux/macOS
333
+ from signal import SIGTERM, SIGKILL
334
+
335
+ try:
336
+ pgid = os.getpgid(self._process.pid)
337
+ print(f"Sending SIGTERM to process group {pgid}...")
338
+ os.killpg(pgid, SIGTERM)
339
+ except OSError:
340
+ print("Failed to send SIGTERM to process group.")
337
341
 
338
- # Wait up to 1 second for processes to exit gracefully
339
- gone, still_alive = psutil.wait_procs(children + [proc], timeout=1)
342
+ try:
343
+ proc.wait(timeout=0.5)
344
+ except subprocess.TimeoutExpired:
345
+ print(
346
+ "The FFmpeg process did not exit within 0.5s after SIGTERM, sending SIGKILL..."
347
+ )
348
+ try:
349
+ os.killpg(pgid, SIGKILL)
350
+ except OSError:
351
+ print("Failed to send SIGKILL to process group.")
340
352
 
341
- # Force kill any remaining processes
342
- for p in still_alive:
353
+ for child in children:
354
+ if child.is_running():
355
+ print(f"Force killing child process {child.pid}...")
343
356
  try:
344
- p.kill()
357
+ child.kill()
345
358
  except psutil.NoSuchProcess:
346
359
  pass
360
+ except psutil.AccessDenied:
361
+ print("Permission error when trying to kill the FFmpeg process.")
347
362
 
348
- except (psutil.NoSuchProcess, ProcessLookupError, KeyboardInterrupt):
349
- # As a last resort, force kill the main process
350
- self._process.kill()
363
+ if self._process.poll() is None:
364
+ print("Force killing the FFmpeg process...")
365
+ try:
366
+ proc.kill()
367
+ except psutil.NoSuchProcess:
368
+ pass
369
+ except psutil.AccessDenied:
370
+ print("Permission error when trying to kill the FFmpeg process.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: better-ffmpeg-progress
3
- Version: 3.2.4
3
+ Version: 3.2.6
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.4",
8
+ version="3.2.6",
9
9
  author="GitHub.com/CrypticSignal",
10
10
  author_email="theaudiophile@outlook.com",
11
11
  description="Run FFmpeg & see percentage progress + ETA.",