better-ffmpeg-progress 5.3.0__tar.gz → 5.4.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-5.3.0 → better_ffmpeg_progress-5.4.1}/PKG-INFO +24 -1
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/README.md +23 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/better_ffmpeg_progress.py +14 -22
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/utils.py +12 -12
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress.egg-info/PKG-INFO +24 -1
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/setup.py +1 -1
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/LICENSE +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/__init__.py +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/enums.py +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/exceptions.py +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/progress_bars.py +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/terminate_process.py +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress.egg-info/SOURCES.txt +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress.egg-info/dependency_links.txt +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress.egg-info/requires.txt +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress.egg-info/top_level.txt +0 -0
- {better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: better-ffmpeg-progress
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.4.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
|
|
@@ -108,6 +108,29 @@ process = FfmpegProcess(
|
|
|
108
108
|
process.run()
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
## Generated (lavfi) Inputs
|
|
112
|
+
Inputs generated by FFmpeg's [lavfi](https://ffmpeg.org/ffmpeg-devices.html#lavfi) device, such as test patterns, are supported. FFprobe cannot detect the duration of these inputs, so provide it with `duration_override`:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
116
|
+
|
|
117
|
+
command = [
|
|
118
|
+
"ffmpeg",
|
|
119
|
+
"-f",
|
|
120
|
+
"lavfi",
|
|
121
|
+
"-i",
|
|
122
|
+
"testsrc2=duration=30:size=1920x1080:rate=30",
|
|
123
|
+
"-c:v",
|
|
124
|
+
"libx264",
|
|
125
|
+
"output.mp4",
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
process = FfmpegProcess(command, duration_override=30)
|
|
129
|
+
process.run()
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
By default, the FFmpeg log file is named after the source, e.g. `lavfi_testsrc2_ffmpeg_log.txt`.
|
|
133
|
+
|
|
111
134
|
## Optional Arguments
|
|
112
135
|
An instance of `FfmpegProcess` accepts the following optional arguments:
|
|
113
136
|
* `ffmpeg_log_level` — Set a value for FFmpeg's `-loglevel` option. Default: `"verbose"`.
|
|
@@ -89,6 +89,29 @@ process = FfmpegProcess(
|
|
|
89
89
|
process.run()
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
+
## Generated (lavfi) Inputs
|
|
93
|
+
Inputs generated by FFmpeg's [lavfi](https://ffmpeg.org/ffmpeg-devices.html#lavfi) device, such as test patterns, are supported. FFprobe cannot detect the duration of these inputs, so provide it with `duration_override`:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
97
|
+
|
|
98
|
+
command = [
|
|
99
|
+
"ffmpeg",
|
|
100
|
+
"-f",
|
|
101
|
+
"lavfi",
|
|
102
|
+
"-i",
|
|
103
|
+
"testsrc2=duration=30:size=1920x1080:rate=30",
|
|
104
|
+
"-c:v",
|
|
105
|
+
"libx264",
|
|
106
|
+
"output.mp4",
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
process = FfmpegProcess(command, duration_override=30)
|
|
110
|
+
process.run()
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
By default, the FFmpeg log file is named after the source, e.g. `lavfi_testsrc2_ffmpeg_log.txt`.
|
|
114
|
+
|
|
92
115
|
## Optional Arguments
|
|
93
116
|
An instance of `FfmpegProcess` accepts the following optional arguments:
|
|
94
117
|
* `ffmpeg_log_level` — Set a value for FFmpeg's `-loglevel` option. Default: `"verbose"`.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import math
|
|
2
2
|
import os
|
|
3
|
+
import re
|
|
4
|
+
import shlex
|
|
3
5
|
from pathlib import Path
|
|
4
6
|
import subprocess
|
|
5
7
|
from sys import exit
|
|
@@ -16,7 +18,7 @@ from .utils import (
|
|
|
16
18
|
validate_ffmpeg_command,
|
|
17
19
|
get_media_duration,
|
|
18
20
|
get_expected_output_duration,
|
|
19
|
-
|
|
21
|
+
is_lavfi_input,
|
|
20
22
|
)
|
|
21
23
|
from .terminate_process import terminate_ffmpeg_process
|
|
22
24
|
from .progress_bars import use_rich, use_tqdm
|
|
@@ -112,7 +114,14 @@ class FfmpegProcess:
|
|
|
112
114
|
self._output_filepath = Path(command[-1])
|
|
113
115
|
|
|
114
116
|
if ffmpeg_log_file is None:
|
|
115
|
-
|
|
117
|
+
if is_lavfi_input(command, input_file_index):
|
|
118
|
+
# A filtergraph such as "testsrc2=size=1920x1080" can contain characters that
|
|
119
|
+
# are not valid in filenames (e.g. ":" on Windows), so name the log after the
|
|
120
|
+
# source instead.
|
|
121
|
+
source_name = re.sub(r"[^\w.,-]", "_", input_file_path_str.split("=", 1)[0])
|
|
122
|
+
self._ffmpeg_log_file = Path(f"lavfi_{source_name}_ffmpeg_log.txt")
|
|
123
|
+
else:
|
|
124
|
+
self._ffmpeg_log_file = Path(f"{self._input_filepath.name}_ffmpeg_log.txt")
|
|
116
125
|
elif isinstance(ffmpeg_log_file, (str, os.PathLike)):
|
|
117
126
|
self._ffmpeg_log_file = Path(ffmpeg_log_file)
|
|
118
127
|
else:
|
|
@@ -182,22 +191,7 @@ class FfmpegProcess:
|
|
|
182
191
|
print_command: bool = False,
|
|
183
192
|
) -> None:
|
|
184
193
|
if print_command:
|
|
185
|
-
|
|
186
|
-
" ".join(self._ffmpeg_command)
|
|
187
|
-
if isinstance(self._ffmpeg_command, list)
|
|
188
|
-
else self._ffmpeg_command
|
|
189
|
-
)
|
|
190
|
-
print(f"Executing: {cmd_str}")
|
|
191
|
-
|
|
192
|
-
self._shell_needed = check_shell_needed_for_command(
|
|
193
|
-
self._ffmpeg_command
|
|
194
|
-
if isinstance(self._ffmpeg_command, list)
|
|
195
|
-
else [self._ffmpeg_command]
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
current_ffmpeg_command = self._ffmpeg_command
|
|
199
|
-
if self._shell_needed and isinstance(current_ffmpeg_command, list):
|
|
200
|
-
current_ffmpeg_command = " ".join(current_ffmpeg_command)
|
|
194
|
+
print(f"Executing: {shlex.join(self._ffmpeg_command)}")
|
|
201
195
|
|
|
202
196
|
try:
|
|
203
197
|
creationflags = 0
|
|
@@ -212,16 +206,14 @@ class FfmpegProcess:
|
|
|
212
206
|
encoding="utf-8",
|
|
213
207
|
) as f:
|
|
214
208
|
self._process = subprocess.Popen(
|
|
215
|
-
|
|
216
|
-
shell=self._shell_needed,
|
|
209
|
+
self._ffmpeg_command,
|
|
217
210
|
stdout=subprocess.PIPE,
|
|
218
211
|
stderr=f,
|
|
219
212
|
creationflags=creationflags,
|
|
220
213
|
)
|
|
221
214
|
else:
|
|
222
215
|
self._process = subprocess.Popen(
|
|
223
|
-
|
|
224
|
-
shell=self._shell_needed,
|
|
216
|
+
self._ffmpeg_command,
|
|
225
217
|
stdout=subprocess.PIPE,
|
|
226
218
|
stderr=self._ffmpeg_log_file,
|
|
227
219
|
creationflags=creationflags,
|
{better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/utils.py
RENAMED
|
@@ -15,6 +15,14 @@ _BYTES_PER_MB = 1024 * 1024
|
|
|
15
15
|
_MULTIPLIER = 1e-6
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
def is_lavfi_input(command: List[str], input_flag_pos: int) -> bool:
|
|
19
|
+
"""
|
|
20
|
+
Returns True if the input at input_flag_pos is preceded by "-f lavfi", meaning it is a
|
|
21
|
+
filtergraph (e.g. "testsrc2=duration=30") generated by FFmpeg rather than a file or URL.
|
|
22
|
+
"""
|
|
23
|
+
return command[max(input_flag_pos - 2, 0) : input_flag_pos] == ["-f", "lavfi"]
|
|
24
|
+
|
|
25
|
+
|
|
18
26
|
def validate_ffmpeg_command(command: List[str]) -> None:
|
|
19
27
|
"""
|
|
20
28
|
Validates the FFmpeg command.
|
|
@@ -54,8 +62,10 @@ def validate_ffmpeg_command(command: List[str]) -> None:
|
|
|
54
62
|
f"Input file path '{input_file}' looks like an option flag. Please check your command."
|
|
55
63
|
)
|
|
56
64
|
|
|
57
|
-
# Validate input file/URL
|
|
58
|
-
if
|
|
65
|
+
# Validate input file/URL. lavfi inputs are generated by FFmpeg, so there is nothing to check.
|
|
66
|
+
if is_lavfi_input(command, input_flag_pos):
|
|
67
|
+
pass
|
|
68
|
+
elif input_file.startswith("http://") or input_file.startswith("https://"):
|
|
59
69
|
try:
|
|
60
70
|
response = requests.head(input_file, timeout=5, allow_redirects=True)
|
|
61
71
|
response.raise_for_status()
|
|
@@ -107,16 +117,6 @@ def get_media_duration(input_file: str) -> Optional[float]:
|
|
|
107
117
|
return None
|
|
108
118
|
|
|
109
119
|
|
|
110
|
-
def check_shell_needed_for_command(command: List[str]) -> bool:
|
|
111
|
-
"""
|
|
112
|
-
Checks if any part of the command contains shell operators,
|
|
113
|
-
indicating that shell=True might be needed for subprocess.Popen.
|
|
114
|
-
This is a basic check and might not cover all edge cases.
|
|
115
|
-
"""
|
|
116
|
-
shell_operators = {"|", ">", "<", ">>", "&&", "||"} # Basic set
|
|
117
|
-
return any(op in item for item in command for op in shell_operators)
|
|
118
|
-
|
|
119
|
-
|
|
120
120
|
def parse_ffmpeg_progress_line(
|
|
121
121
|
line: bytes, total_duration_secs: Optional[float]
|
|
122
122
|
) -> Optional[float]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: better-ffmpeg-progress
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.4.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
|
|
@@ -108,6 +108,29 @@ process = FfmpegProcess(
|
|
|
108
108
|
process.run()
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
## Generated (lavfi) Inputs
|
|
112
|
+
Inputs generated by FFmpeg's [lavfi](https://ffmpeg.org/ffmpeg-devices.html#lavfi) device, such as test patterns, are supported. FFprobe cannot detect the duration of these inputs, so provide it with `duration_override`:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
116
|
+
|
|
117
|
+
command = [
|
|
118
|
+
"ffmpeg",
|
|
119
|
+
"-f",
|
|
120
|
+
"lavfi",
|
|
121
|
+
"-i",
|
|
122
|
+
"testsrc2=duration=30:size=1920x1080:rate=30",
|
|
123
|
+
"-c:v",
|
|
124
|
+
"libx264",
|
|
125
|
+
"output.mp4",
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
process = FfmpegProcess(command, duration_override=30)
|
|
129
|
+
process.run()
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
By default, the FFmpeg log file is named after the source, e.g. `lavfi_testsrc2_ffmpeg_log.txt`.
|
|
133
|
+
|
|
111
134
|
## Optional Arguments
|
|
112
135
|
An instance of `FfmpegProcess` accepts the following optional arguments:
|
|
113
136
|
* `ffmpeg_log_level` — Set a value for FFmpeg's `-loglevel` option. Default: `"verbose"`.
|
|
@@ -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="5.
|
|
8
|
+
version="5.4.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
|
{better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/__init__.py
RENAMED
|
File without changes
|
{better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/enums.py
RENAMED
|
File without changes
|
{better_ffmpeg_progress-5.3.0 → better_ffmpeg_progress-5.4.1}/better_ffmpeg_progress/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|