better-ffmpeg-progress 2.1.4__tar.gz → 2.1.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.
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/LICENSE +20 -20
- better_ffmpeg_progress-2.1.6/PKG-INFO +143 -0
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/README.md +126 -122
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/better_ffmpeg_progress/__init__.py +1 -1
- better_ffmpeg_progress-2.1.6/better_ffmpeg_progress/better_ffmpeg_progress.py +183 -0
- better_ffmpeg_progress-2.1.6/better_ffmpeg_progress.egg-info/PKG-INFO +143 -0
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/setup.py +24 -24
- better-ffmpeg-progress-2.1.4/PKG-INFO +0 -138
- better-ffmpeg-progress-2.1.4/better_ffmpeg_progress/better_ffmpeg_progress.py +0 -173
- better-ffmpeg-progress-2.1.4/better_ffmpeg_progress.egg-info/PKG-INFO +0 -138
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/better_ffmpeg_progress.egg-info/SOURCES.txt +0 -0
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/better_ffmpeg_progress.egg-info/dependency_links.txt +0 -0
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/better_ffmpeg_progress.egg-info/requires.txt +0 -0
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/better_ffmpeg_progress.egg-info/top_level.txt +0 -0
- {better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/setup.cfg +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2021 GitHub.com/CrypticSignal
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 GitHub.com/CrypticSignal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: better-ffmpeg-progress
|
|
3
|
+
Version: 2.1.6
|
|
4
|
+
Summary: Run FFmpeg & see percentage progress + ETA.
|
|
5
|
+
Home-page: https://github.com/CrypticSignal/better-ffmpeg-progress
|
|
6
|
+
Author: GitHub.com/CrypticSignal
|
|
7
|
+
Author-email: theaudiophile@outlook.com
|
|
8
|
+
Keywords: ffmpeg,progress
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.6
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: ffmpeg-python
|
|
16
|
+
Requires-Dist: tqdm
|
|
17
|
+
|
|
18
|
+
<div align="center">
|
|
19
|
+
|
|
20
|
+
[](https://pypistats.org/packages/pypistats)
|
|
21
|
+
[](https://pypistats.org/packages/pypistats)
|
|
22
|
+
[](LICENSE.txt)
|
|
23
|
+
|
|
24
|
+
# Better FFmpeg Progress
|
|
25
|
+
|
|
26
|
+
Runs an FFmpeg command and uses [tqdm](https://github.com/tqdm/tqdm) to show a progress bar.
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## Example:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
39%|███████████████████████████████████████████ | 23.6/60.2 [00:19<00:34, 1.07s/s]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Where:
|
|
37
|
+
|
|
38
|
+
- `39%` is the percentage progress.
|
|
39
|
+
- `23.6` seconds of the input file have been processed.
|
|
40
|
+
- `60.2` is the duration of the input file in seconds.
|
|
41
|
+
- `00:19` is the time elapsed since the FFmpeg process started.
|
|
42
|
+
- `00:34` is the estimated time required for the FFmpeg process to complete.
|
|
43
|
+
- `1.07` shows how many seconds of the input file are processed per second.
|
|
44
|
+
|
|
45
|
+
## Installation:
|
|
46
|
+
|
|
47
|
+
`pip3 install better-ffmpeg-progress --upgrade`
|
|
48
|
+
|
|
49
|
+
## Usage:
|
|
50
|
+
|
|
51
|
+
Create an instance of the `FfmpegProcess` class and supply a list of arguments like you would to `subprocess.run()`.
|
|
52
|
+
|
|
53
|
+
Simple Example:
|
|
54
|
+
|
|
55
|
+
```py
|
|
56
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
57
|
+
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
58
|
+
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
59
|
+
# Use the run method to run the FFmpeg command.
|
|
60
|
+
process.run()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Advanced Example:
|
|
64
|
+
|
|
65
|
+
```py
|
|
66
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
67
|
+
|
|
68
|
+
def handle_progress_info(percentage, speed, eta, estimated_filesize):
|
|
69
|
+
print(f"Estimated Output Filesize: {estimated_filesize / 1_000_000} MB")
|
|
70
|
+
|
|
71
|
+
def handle_success():
|
|
72
|
+
# Code to run if the FFmpeg process completes successfully.
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
def handle_error():
|
|
76
|
+
# Code to run if the FFmpeg process encounters an error.
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
80
|
+
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
81
|
+
|
|
82
|
+
ffmpeg_output_path = 'ffmpeg_output.txt'
|
|
83
|
+
|
|
84
|
+
# Use the run method to run the FFmpeg command.
|
|
85
|
+
process.run(progress_handler=handle_progress_info, ffmpeg_output_file=ffmpeg_output_path, success_handler=handle_success, error_handler=handle_error)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The `run` method takes the following **optional** arguments:
|
|
89
|
+
|
|
90
|
+
- `progress_handler`
|
|
91
|
+
|
|
92
|
+
- You can create a function if you would like to do something with the following values:
|
|
93
|
+
|
|
94
|
+
- Percentage progress. [float]
|
|
95
|
+
- Speed, e.g. `22.3x` which means that 22.3 seconds of the input are processed every second. [string]
|
|
96
|
+
- ETA in seconds. [float]
|
|
97
|
+
- Estimated output filesize in bytes. [float]
|
|
98
|
+
- _Note: This is not accurate. Please take the value with a grain of salt._
|
|
99
|
+
|
|
100
|
+
The values will be `None` if unknown. The function will receive the aforementioned metrics as arguments, about two times per second.
|
|
101
|
+
|
|
102
|
+
- `ffmpeg_output_file` - A string path to define where you want the output of FFmpeg to be saved. By default, this is saved in a folder named "ffmpeg_output", with the filename `[<input_filename>].txt`.
|
|
103
|
+
|
|
104
|
+
- `success_handler` - A function to run if the FFmpeg process completes successfully.
|
|
105
|
+
|
|
106
|
+
- `error_handler` - A function to run if the FFmpeg process encounters an error.
|
|
107
|
+
|
|
108
|
+
## Changelog:
|
|
109
|
+
|
|
110
|
+
[19/09/2022]
|
|
111
|
+
|
|
112
|
+
- Add the ability to specify a `success_handler` argument, a function to run if the FFmpeg process completes successfully.
|
|
113
|
+
- Add 0.001 to tqdm's `total` parameter to prevent the chance of getting `TqdmWarning: clamping frac to range [0, 1]`
|
|
114
|
+
|
|
115
|
+
[21/12/2022]
|
|
116
|
+
|
|
117
|
+
- [v2.0.7] Fix `'estimated_size' referenced before assignment` error.
|
|
118
|
+
- [v2.0.7] The progress bar now uses 1 decimal place for seconds processed and total duration.
|
|
119
|
+
|
|
120
|
+
[22/12/2022]
|
|
121
|
+
|
|
122
|
+
- [v2.0.8] Add the ability to specify an `error_handler` argument, a function to run if the FFmpeg process encounters an error.
|
|
123
|
+
- [v2.0.9] Fix a typo (commit [da45a84](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/da45a8416856ab7d3c7b748db5703fa3dbc65f60))
|
|
124
|
+
|
|
125
|
+
[07/02/2022]
|
|
126
|
+
|
|
127
|
+
- [v2.1.0] [Update function name](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/572fe8a0d71957d00b833134a4d35170630203fa) to fix `'process_complete_handler' is not defined` error.
|
|
128
|
+
|
|
129
|
+
[05/11/2023]
|
|
130
|
+
|
|
131
|
+
- [v2.1.2] [Do not exit the Python interpreter after the FFmpeg process is complete](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/0a358810773835297faae688689c6e0d8a5859ae)
|
|
132
|
+
|
|
133
|
+
[22/04/2024]
|
|
134
|
+
|
|
135
|
+
- [v2.1.3] Fix issue [#20](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/20)
|
|
136
|
+
|
|
137
|
+
[28/04/2024]
|
|
138
|
+
|
|
139
|
+
- [v2.1.4] Fix issue [#21](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/21)
|
|
140
|
+
|
|
141
|
+
[02/05/2024]
|
|
142
|
+
|
|
143
|
+
- [v2.1.5] Fix issue [#23](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/23) and make an error message more specific. [Here](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/a6ef7f26d080b684144021301f3b2aa5e0834dae) is the relevant commit.
|
|
@@ -1,122 +1,126 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
|
|
3
|
-
[](https://pypistats.org/packages/pypistats)
|
|
4
|
-
[](https://pypistats.org/packages/pypistats)
|
|
5
|
-
[](LICENSE.txt)
|
|
6
|
-
|
|
7
|
-
# Better FFmpeg Progress
|
|
8
|
-
|
|
9
|
-
Runs an FFmpeg command and uses [tqdm](https://github.com/tqdm/tqdm) to show a progress bar.
|
|
10
|
-
|
|
11
|
-
</div>
|
|
12
|
-
|
|
13
|
-
## Example:
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
39%|███████████████████████████████████████████ | 23.6/60.2 [00:19<00:34, 1.07s/s]
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Where:
|
|
20
|
-
|
|
21
|
-
- `39%` is the percentage progress.
|
|
22
|
-
- `23.6` seconds of the input file have been processed.
|
|
23
|
-
- `60.2` is the duration of the input file in seconds.
|
|
24
|
-
- `00:19` is the time elapsed since the FFmpeg process started.
|
|
25
|
-
- `00:34` is the estimated time required for the FFmpeg process to complete.
|
|
26
|
-
- `1.07` shows how many seconds of the input file are processed per second.
|
|
27
|
-
|
|
28
|
-
## Installation:
|
|
29
|
-
|
|
30
|
-
`pip3 install better-ffmpeg-progress --upgrade`
|
|
31
|
-
|
|
32
|
-
## Usage:
|
|
33
|
-
|
|
34
|
-
Create an instance of the `FfmpegProcess` class and supply a list of arguments like you would to `subprocess.run()`.
|
|
35
|
-
|
|
36
|
-
Simple Example:
|
|
37
|
-
|
|
38
|
-
```py
|
|
39
|
-
from better_ffmpeg_progress import FfmpegProcess
|
|
40
|
-
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
41
|
-
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
42
|
-
# Use the run method to run the FFmpeg command.
|
|
43
|
-
process.run()
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Advanced Example:
|
|
47
|
-
|
|
48
|
-
```py
|
|
49
|
-
from better_ffmpeg_progress import FfmpegProcess
|
|
50
|
-
|
|
51
|
-
def handle_progress_info(percentage, speed, eta, estimated_filesize):
|
|
52
|
-
print(f"Estimated Output Filesize: {estimated_filesize / 1_000_000} MB")
|
|
53
|
-
|
|
54
|
-
def handle_success():
|
|
55
|
-
# Code to run if the FFmpeg process completes successfully.
|
|
56
|
-
pass
|
|
57
|
-
|
|
58
|
-
def handle_error():
|
|
59
|
-
# Code to run if the FFmpeg process encounters an error.
|
|
60
|
-
pass
|
|
61
|
-
|
|
62
|
-
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
63
|
-
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
64
|
-
|
|
65
|
-
ffmpeg_output_path = 'ffmpeg_output.txt'
|
|
66
|
-
|
|
67
|
-
# Use the run method to run the FFmpeg command.
|
|
68
|
-
process.run(progress_handler=handle_progress_info, ffmpeg_output_file=ffmpeg_output_path, success_handler=handle_success, error_handler=handle_error)
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
The `run` method takes the following **optional** arguments:
|
|
72
|
-
|
|
73
|
-
- `progress_handler`
|
|
74
|
-
|
|
75
|
-
- You can create a function if you would like to do something with the following values:
|
|
76
|
-
|
|
77
|
-
- Percentage progress. [float]
|
|
78
|
-
- Speed, e.g. `22.3x` which means that 22.3 seconds of the input are processed every second. [string]
|
|
79
|
-
- ETA in seconds. [float]
|
|
80
|
-
- Estimated output filesize in bytes. [float]
|
|
81
|
-
- _Note: This is not accurate. Please take the value with a grain of salt._
|
|
82
|
-
|
|
83
|
-
The values will be `None` if unknown. The function will receive the aforementioned metrics as arguments, about two times per second.
|
|
84
|
-
|
|
85
|
-
- `ffmpeg_output_file` - A string path to define where you want the output of FFmpeg to be saved. By default, this is saved in a folder named "ffmpeg_output", with the filename `[<input_filename>].txt`.
|
|
86
|
-
|
|
87
|
-
- `success_handler` - A function to run if the FFmpeg process completes successfully.
|
|
88
|
-
|
|
89
|
-
- `error_handler` - A function to run if the FFmpeg process encounters an error.
|
|
90
|
-
|
|
91
|
-
## Changelog:
|
|
92
|
-
|
|
93
|
-
[19/09/2022]
|
|
94
|
-
|
|
95
|
-
- Add the ability to specify a `success_handler` argument, a function to run if the FFmpeg process completes successfully.
|
|
96
|
-
- Add 0.001 to tqdm's `total` parameter to prevent the chance of getting `TqdmWarning: clamping frac to range [0, 1]`
|
|
97
|
-
|
|
98
|
-
[21/12/2022]
|
|
99
|
-
|
|
100
|
-
- [v2.0.7] Fix `'estimated_size' referenced before assignment` error.
|
|
101
|
-
- [v2.0.7] The progress bar now uses 1 decimal place for seconds processed and total duration.
|
|
102
|
-
|
|
103
|
-
[22/12/2022]
|
|
104
|
-
|
|
105
|
-
- [v2.0.8] Add the ability to specify an `error_handler` argument, a function to run if the FFmpeg process encounters an error.
|
|
106
|
-
- [v2.0.9] Fix a typo (commit [da45a84](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/da45a8416856ab7d3c7b748db5703fa3dbc65f60))
|
|
107
|
-
|
|
108
|
-
[07/02/2022]
|
|
109
|
-
|
|
110
|
-
- [v2.1.0] [Update function name](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/572fe8a0d71957d00b833134a4d35170630203fa) to fix `'process_complete_handler' is not defined` error.
|
|
111
|
-
|
|
112
|
-
[05/11/2023]
|
|
113
|
-
|
|
114
|
-
- [v2.1.2] [Do not exit the Python interpreter after the FFmpeg process is complete](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/0a358810773835297faae688689c6e0d8a5859ae)
|
|
115
|
-
|
|
116
|
-
[22/04/2024]
|
|
117
|
-
|
|
118
|
-
- [v2.1.3] Fix issue [#20](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/20)
|
|
119
|
-
|
|
120
|
-
[28/04/2024]
|
|
121
|
-
|
|
122
|
-
- [v2.1.4] Fix issue [#21](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/21)
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
[](https://pypistats.org/packages/pypistats)
|
|
4
|
+
[](https://pypistats.org/packages/pypistats)
|
|
5
|
+
[](LICENSE.txt)
|
|
6
|
+
|
|
7
|
+
# Better FFmpeg Progress
|
|
8
|
+
|
|
9
|
+
Runs an FFmpeg command and uses [tqdm](https://github.com/tqdm/tqdm) to show a progress bar.
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
## Example:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
39%|███████████████████████████████████████████ | 23.6/60.2 [00:19<00:34, 1.07s/s]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Where:
|
|
20
|
+
|
|
21
|
+
- `39%` is the percentage progress.
|
|
22
|
+
- `23.6` seconds of the input file have been processed.
|
|
23
|
+
- `60.2` is the duration of the input file in seconds.
|
|
24
|
+
- `00:19` is the time elapsed since the FFmpeg process started.
|
|
25
|
+
- `00:34` is the estimated time required for the FFmpeg process to complete.
|
|
26
|
+
- `1.07` shows how many seconds of the input file are processed per second.
|
|
27
|
+
|
|
28
|
+
## Installation:
|
|
29
|
+
|
|
30
|
+
`pip3 install better-ffmpeg-progress --upgrade`
|
|
31
|
+
|
|
32
|
+
## Usage:
|
|
33
|
+
|
|
34
|
+
Create an instance of the `FfmpegProcess` class and supply a list of arguments like you would to `subprocess.run()`.
|
|
35
|
+
|
|
36
|
+
Simple Example:
|
|
37
|
+
|
|
38
|
+
```py
|
|
39
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
40
|
+
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
41
|
+
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
42
|
+
# Use the run method to run the FFmpeg command.
|
|
43
|
+
process.run()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Advanced Example:
|
|
47
|
+
|
|
48
|
+
```py
|
|
49
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
50
|
+
|
|
51
|
+
def handle_progress_info(percentage, speed, eta, estimated_filesize):
|
|
52
|
+
print(f"Estimated Output Filesize: {estimated_filesize / 1_000_000} MB")
|
|
53
|
+
|
|
54
|
+
def handle_success():
|
|
55
|
+
# Code to run if the FFmpeg process completes successfully.
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
def handle_error():
|
|
59
|
+
# Code to run if the FFmpeg process encounters an error.
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
63
|
+
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
64
|
+
|
|
65
|
+
ffmpeg_output_path = 'ffmpeg_output.txt'
|
|
66
|
+
|
|
67
|
+
# Use the run method to run the FFmpeg command.
|
|
68
|
+
process.run(progress_handler=handle_progress_info, ffmpeg_output_file=ffmpeg_output_path, success_handler=handle_success, error_handler=handle_error)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The `run` method takes the following **optional** arguments:
|
|
72
|
+
|
|
73
|
+
- `progress_handler`
|
|
74
|
+
|
|
75
|
+
- You can create a function if you would like to do something with the following values:
|
|
76
|
+
|
|
77
|
+
- Percentage progress. [float]
|
|
78
|
+
- Speed, e.g. `22.3x` which means that 22.3 seconds of the input are processed every second. [string]
|
|
79
|
+
- ETA in seconds. [float]
|
|
80
|
+
- Estimated output filesize in bytes. [float]
|
|
81
|
+
- _Note: This is not accurate. Please take the value with a grain of salt._
|
|
82
|
+
|
|
83
|
+
The values will be `None` if unknown. The function will receive the aforementioned metrics as arguments, about two times per second.
|
|
84
|
+
|
|
85
|
+
- `ffmpeg_output_file` - A string path to define where you want the output of FFmpeg to be saved. By default, this is saved in a folder named "ffmpeg_output", with the filename `[<input_filename>].txt`.
|
|
86
|
+
|
|
87
|
+
- `success_handler` - A function to run if the FFmpeg process completes successfully.
|
|
88
|
+
|
|
89
|
+
- `error_handler` - A function to run if the FFmpeg process encounters an error.
|
|
90
|
+
|
|
91
|
+
## Changelog:
|
|
92
|
+
|
|
93
|
+
[19/09/2022]
|
|
94
|
+
|
|
95
|
+
- Add the ability to specify a `success_handler` argument, a function to run if the FFmpeg process completes successfully.
|
|
96
|
+
- Add 0.001 to tqdm's `total` parameter to prevent the chance of getting `TqdmWarning: clamping frac to range [0, 1]`
|
|
97
|
+
|
|
98
|
+
[21/12/2022]
|
|
99
|
+
|
|
100
|
+
- [v2.0.7] Fix `'estimated_size' referenced before assignment` error.
|
|
101
|
+
- [v2.0.7] The progress bar now uses 1 decimal place for seconds processed and total duration.
|
|
102
|
+
|
|
103
|
+
[22/12/2022]
|
|
104
|
+
|
|
105
|
+
- [v2.0.8] Add the ability to specify an `error_handler` argument, a function to run if the FFmpeg process encounters an error.
|
|
106
|
+
- [v2.0.9] Fix a typo (commit [da45a84](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/da45a8416856ab7d3c7b748db5703fa3dbc65f60))
|
|
107
|
+
|
|
108
|
+
[07/02/2022]
|
|
109
|
+
|
|
110
|
+
- [v2.1.0] [Update function name](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/572fe8a0d71957d00b833134a4d35170630203fa) to fix `'process_complete_handler' is not defined` error.
|
|
111
|
+
|
|
112
|
+
[05/11/2023]
|
|
113
|
+
|
|
114
|
+
- [v2.1.2] [Do not exit the Python interpreter after the FFmpeg process is complete](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/0a358810773835297faae688689c6e0d8a5859ae)
|
|
115
|
+
|
|
116
|
+
[22/04/2024]
|
|
117
|
+
|
|
118
|
+
- [v2.1.3] Fix issue [#20](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/20)
|
|
119
|
+
|
|
120
|
+
[28/04/2024]
|
|
121
|
+
|
|
122
|
+
- [v2.1.4] Fix issue [#21](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/21)
|
|
123
|
+
|
|
124
|
+
[02/05/2024]
|
|
125
|
+
|
|
126
|
+
- [v2.1.5] Fix issue [#23](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/23) and make an error message more specific. [Here](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/a6ef7f26d080b684144021301f3b2aa5e0834dae) is the relevant commit.
|
{better-ffmpeg-progress-2.1.4 → better_ffmpeg_progress-2.1.6}/better_ffmpeg_progress/__init__.py
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
from .better_ffmpeg_progress import FfmpegProcess
|
|
1
|
+
from .better_ffmpeg_progress import FfmpegProcess
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from ffmpeg import probe
|
|
7
|
+
from tqdm import tqdm
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FfmpegProcess:
|
|
11
|
+
"""
|
|
12
|
+
Args:
|
|
13
|
+
command (list): A list of arguments to pass to FFmpeg.
|
|
14
|
+
|
|
15
|
+
ffmpeg_loglevel (str, optional): Desired FFmpeg log level. Default is "verbose".
|
|
16
|
+
|
|
17
|
+
Raises:
|
|
18
|
+
ValueError: If the list of arguments does not include "-i".
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, command, ffmpeg_loglevel="verbose"):
|
|
22
|
+
if "-i" not in command:
|
|
23
|
+
raise ValueError("FFmpeg command must include '-i'")
|
|
24
|
+
|
|
25
|
+
self._ffmpeg_args = command + ["-hide_banner", "-loglevel", ffmpeg_loglevel]
|
|
26
|
+
self._output_filepath = command[-1]
|
|
27
|
+
|
|
28
|
+
self._set_file_info()
|
|
29
|
+
|
|
30
|
+
self._estimated_size = None
|
|
31
|
+
self._eta = None
|
|
32
|
+
self._percentage_progress = 0
|
|
33
|
+
self._previous_seconds_processed = 0
|
|
34
|
+
self._progress_bar = None
|
|
35
|
+
self._seconds_processed = 0
|
|
36
|
+
self._speed = 0
|
|
37
|
+
self._current_size = 0
|
|
38
|
+
|
|
39
|
+
def _set_file_info(self):
|
|
40
|
+
index_of_filepath = self._ffmpeg_args.index("-i") + 1
|
|
41
|
+
self._filepath = self._ffmpeg_args[index_of_filepath]
|
|
42
|
+
self._can_get_duration = True
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
self._duration_secs = float(probe(self._filepath)["format"]["duration"])
|
|
46
|
+
print(
|
|
47
|
+
f"The duration of {self._filepath} has been detected as {self._duration_secs} seconds."
|
|
48
|
+
)
|
|
49
|
+
except Exception:
|
|
50
|
+
self._can_get_duration = False
|
|
51
|
+
|
|
52
|
+
if self._can_get_duration:
|
|
53
|
+
self._ffmpeg_args += ["-progress", "pipe:1", "-nostats"]
|
|
54
|
+
|
|
55
|
+
def _should_run_ffmpeg(self):
|
|
56
|
+
dirname = os.path.dirname(self._output_filepath)
|
|
57
|
+
self._dir_files = (
|
|
58
|
+
[file for file in os.listdir(dirname)] if dirname else [file for file in os.listdir()]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
if "-y" not in self._ffmpeg_args and self._output_filepath in self._dir_files:
|
|
62
|
+
choice = input(f"{self._output_filepath} already exists. Overwrite? [Y/N]: ").lower()
|
|
63
|
+
|
|
64
|
+
if choice != "y":
|
|
65
|
+
print(
|
|
66
|
+
"FFmpeg will not run as the output filename already exists, and you do not want it to be overwritten."
|
|
67
|
+
)
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
self._ffmpeg_args.insert(1, "-y")
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
return True
|
|
74
|
+
|
|
75
|
+
def _update_progress(self, ffmpeg_output, metric_name, value, progress_handler):
|
|
76
|
+
if progress_handler is None:
|
|
77
|
+
if metric_name == "out_time_ms":
|
|
78
|
+
seconds_processed = round(int(value) / 1_000_000, 1)
|
|
79
|
+
seconds_increase = seconds_processed - self._previous_seconds_processed
|
|
80
|
+
self._progress_bar.update(seconds_increase)
|
|
81
|
+
self._previous_seconds_processed = seconds_processed
|
|
82
|
+
|
|
83
|
+
else:
|
|
84
|
+
if metric_name == "total_size":
|
|
85
|
+
self._current_size = int(value)
|
|
86
|
+
|
|
87
|
+
elif metric_name == "out_time_ms":
|
|
88
|
+
self._seconds_processed = int(value) / 1_000_000
|
|
89
|
+
|
|
90
|
+
if self._can_get_duration:
|
|
91
|
+
self._percentage_progress = (
|
|
92
|
+
self._seconds_processed / self._duration_secs
|
|
93
|
+
) * 100
|
|
94
|
+
|
|
95
|
+
if self._current_size is not None and self._percentage_progress != 0.0:
|
|
96
|
+
self._estimated_size = self._current_size * (
|
|
97
|
+
100 / self._percentage_progress
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
elif metric_name == "speed":
|
|
101
|
+
speed_str = value[:-1]
|
|
102
|
+
|
|
103
|
+
if speed_str != "0":
|
|
104
|
+
self._speed = float(speed_str)
|
|
105
|
+
|
|
106
|
+
if self._can_get_duration:
|
|
107
|
+
self._eta = (self._duration_secs - self._seconds_processed) / self._speed
|
|
108
|
+
|
|
109
|
+
if ffmpeg_output == "progress=end":
|
|
110
|
+
self._percentage_progress = 100
|
|
111
|
+
self._eta = 0
|
|
112
|
+
|
|
113
|
+
progress_handler(
|
|
114
|
+
self._percentage_progress, self._speed, self._eta, self._estimated_size
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
def run(
|
|
118
|
+
self,
|
|
119
|
+
progress_handler=None,
|
|
120
|
+
ffmpeg_output_file=None,
|
|
121
|
+
success_handler=None,
|
|
122
|
+
error_handler=None,
|
|
123
|
+
):
|
|
124
|
+
if not self._should_run_ffmpeg():
|
|
125
|
+
return
|
|
126
|
+
|
|
127
|
+
print(f"Attempting to run: {' '.join(self._ffmpeg_args)}\n")
|
|
128
|
+
process = subprocess.Popen(self._ffmpeg_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
129
|
+
|
|
130
|
+
stdout = process.stdout.readline().decode()
|
|
131
|
+
stderr = process.stderr.readline().decode()
|
|
132
|
+
|
|
133
|
+
if "No such file" in stderr:
|
|
134
|
+
print(f"{stderr}It seems like the input filepath or filename is incorrect.")
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
if ffmpeg_output_file is None:
|
|
138
|
+
os.makedirs("ffmpeg_output", exist_ok=True)
|
|
139
|
+
ffmpeg_output_file = os.path.join("ffmpeg_output", f"[{Path(self._filepath).name}].txt")
|
|
140
|
+
|
|
141
|
+
with open(ffmpeg_output_file, "a") as f:
|
|
142
|
+
f.write(stdout)
|
|
143
|
+
|
|
144
|
+
if progress_handler is None and self._can_get_duration:
|
|
145
|
+
self._progress_bar = tqdm(
|
|
146
|
+
total=round(self._duration_secs, 1),
|
|
147
|
+
unit="s",
|
|
148
|
+
dynamic_ncols=True,
|
|
149
|
+
leave=False,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
while process.poll() is None:
|
|
153
|
+
stdout = process.stdout.readline().decode().strip()
|
|
154
|
+
|
|
155
|
+
if not stdout:
|
|
156
|
+
continue
|
|
157
|
+
|
|
158
|
+
metric_name = stdout.split("=")[0]
|
|
159
|
+
wanted_metrics = ["out_time_ms", "total_size", "speed"]
|
|
160
|
+
|
|
161
|
+
if metric_name not in wanted_metrics:
|
|
162
|
+
continue
|
|
163
|
+
|
|
164
|
+
value = stdout.split("=")[1].strip()
|
|
165
|
+
|
|
166
|
+
if not value or "N/A" in value:
|
|
167
|
+
continue
|
|
168
|
+
|
|
169
|
+
self._update_progress(stdout, metric_name, value, progress_handler)
|
|
170
|
+
|
|
171
|
+
if process.returncode != 0:
|
|
172
|
+
if error_handler:
|
|
173
|
+
error_handler()
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
print(
|
|
177
|
+
f"The FFmpeg process encountered an error. The output of FFmpeg can be found in {ffmpeg_output_file}"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
if success_handler:
|
|
181
|
+
success_handler()
|
|
182
|
+
|
|
183
|
+
print(f"\n\nDone! To see FFmpeg's output, check out {ffmpeg_output_file}")
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: better-ffmpeg-progress
|
|
3
|
+
Version: 2.1.6
|
|
4
|
+
Summary: Run FFmpeg & see percentage progress + ETA.
|
|
5
|
+
Home-page: https://github.com/CrypticSignal/better-ffmpeg-progress
|
|
6
|
+
Author: GitHub.com/CrypticSignal
|
|
7
|
+
Author-email: theaudiophile@outlook.com
|
|
8
|
+
Keywords: ffmpeg,progress
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.6
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: ffmpeg-python
|
|
16
|
+
Requires-Dist: tqdm
|
|
17
|
+
|
|
18
|
+
<div align="center">
|
|
19
|
+
|
|
20
|
+
[](https://pypistats.org/packages/pypistats)
|
|
21
|
+
[](https://pypistats.org/packages/pypistats)
|
|
22
|
+
[](LICENSE.txt)
|
|
23
|
+
|
|
24
|
+
# Better FFmpeg Progress
|
|
25
|
+
|
|
26
|
+
Runs an FFmpeg command and uses [tqdm](https://github.com/tqdm/tqdm) to show a progress bar.
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## Example:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
39%|███████████████████████████████████████████ | 23.6/60.2 [00:19<00:34, 1.07s/s]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Where:
|
|
37
|
+
|
|
38
|
+
- `39%` is the percentage progress.
|
|
39
|
+
- `23.6` seconds of the input file have been processed.
|
|
40
|
+
- `60.2` is the duration of the input file in seconds.
|
|
41
|
+
- `00:19` is the time elapsed since the FFmpeg process started.
|
|
42
|
+
- `00:34` is the estimated time required for the FFmpeg process to complete.
|
|
43
|
+
- `1.07` shows how many seconds of the input file are processed per second.
|
|
44
|
+
|
|
45
|
+
## Installation:
|
|
46
|
+
|
|
47
|
+
`pip3 install better-ffmpeg-progress --upgrade`
|
|
48
|
+
|
|
49
|
+
## Usage:
|
|
50
|
+
|
|
51
|
+
Create an instance of the `FfmpegProcess` class and supply a list of arguments like you would to `subprocess.run()`.
|
|
52
|
+
|
|
53
|
+
Simple Example:
|
|
54
|
+
|
|
55
|
+
```py
|
|
56
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
57
|
+
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
58
|
+
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
59
|
+
# Use the run method to run the FFmpeg command.
|
|
60
|
+
process.run()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Advanced Example:
|
|
64
|
+
|
|
65
|
+
```py
|
|
66
|
+
from better_ffmpeg_progress import FfmpegProcess
|
|
67
|
+
|
|
68
|
+
def handle_progress_info(percentage, speed, eta, estimated_filesize):
|
|
69
|
+
print(f"Estimated Output Filesize: {estimated_filesize / 1_000_000} MB")
|
|
70
|
+
|
|
71
|
+
def handle_success():
|
|
72
|
+
# Code to run if the FFmpeg process completes successfully.
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
def handle_error():
|
|
76
|
+
# Code to run if the FFmpeg process encounters an error.
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
80
|
+
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
81
|
+
|
|
82
|
+
ffmpeg_output_path = 'ffmpeg_output.txt'
|
|
83
|
+
|
|
84
|
+
# Use the run method to run the FFmpeg command.
|
|
85
|
+
process.run(progress_handler=handle_progress_info, ffmpeg_output_file=ffmpeg_output_path, success_handler=handle_success, error_handler=handle_error)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The `run` method takes the following **optional** arguments:
|
|
89
|
+
|
|
90
|
+
- `progress_handler`
|
|
91
|
+
|
|
92
|
+
- You can create a function if you would like to do something with the following values:
|
|
93
|
+
|
|
94
|
+
- Percentage progress. [float]
|
|
95
|
+
- Speed, e.g. `22.3x` which means that 22.3 seconds of the input are processed every second. [string]
|
|
96
|
+
- ETA in seconds. [float]
|
|
97
|
+
- Estimated output filesize in bytes. [float]
|
|
98
|
+
- _Note: This is not accurate. Please take the value with a grain of salt._
|
|
99
|
+
|
|
100
|
+
The values will be `None` if unknown. The function will receive the aforementioned metrics as arguments, about two times per second.
|
|
101
|
+
|
|
102
|
+
- `ffmpeg_output_file` - A string path to define where you want the output of FFmpeg to be saved. By default, this is saved in a folder named "ffmpeg_output", with the filename `[<input_filename>].txt`.
|
|
103
|
+
|
|
104
|
+
- `success_handler` - A function to run if the FFmpeg process completes successfully.
|
|
105
|
+
|
|
106
|
+
- `error_handler` - A function to run if the FFmpeg process encounters an error.
|
|
107
|
+
|
|
108
|
+
## Changelog:
|
|
109
|
+
|
|
110
|
+
[19/09/2022]
|
|
111
|
+
|
|
112
|
+
- Add the ability to specify a `success_handler` argument, a function to run if the FFmpeg process completes successfully.
|
|
113
|
+
- Add 0.001 to tqdm's `total` parameter to prevent the chance of getting `TqdmWarning: clamping frac to range [0, 1]`
|
|
114
|
+
|
|
115
|
+
[21/12/2022]
|
|
116
|
+
|
|
117
|
+
- [v2.0.7] Fix `'estimated_size' referenced before assignment` error.
|
|
118
|
+
- [v2.0.7] The progress bar now uses 1 decimal place for seconds processed and total duration.
|
|
119
|
+
|
|
120
|
+
[22/12/2022]
|
|
121
|
+
|
|
122
|
+
- [v2.0.8] Add the ability to specify an `error_handler` argument, a function to run if the FFmpeg process encounters an error.
|
|
123
|
+
- [v2.0.9] Fix a typo (commit [da45a84](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/da45a8416856ab7d3c7b748db5703fa3dbc65f60))
|
|
124
|
+
|
|
125
|
+
[07/02/2022]
|
|
126
|
+
|
|
127
|
+
- [v2.1.0] [Update function name](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/572fe8a0d71957d00b833134a4d35170630203fa) to fix `'process_complete_handler' is not defined` error.
|
|
128
|
+
|
|
129
|
+
[05/11/2023]
|
|
130
|
+
|
|
131
|
+
- [v2.1.2] [Do not exit the Python interpreter after the FFmpeg process is complete](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/0a358810773835297faae688689c6e0d8a5859ae)
|
|
132
|
+
|
|
133
|
+
[22/04/2024]
|
|
134
|
+
|
|
135
|
+
- [v2.1.3] Fix issue [#20](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/20)
|
|
136
|
+
|
|
137
|
+
[28/04/2024]
|
|
138
|
+
|
|
139
|
+
- [v2.1.4] Fix issue [#21](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/21)
|
|
140
|
+
|
|
141
|
+
[02/05/2024]
|
|
142
|
+
|
|
143
|
+
- [v2.1.5] Fix issue [#23](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/23) and make an error message more specific. [Here](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/a6ef7f26d080b684144021301f3b2aa5e0834dae) is the relevant commit.
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import setuptools
|
|
2
|
-
|
|
3
|
-
with open("README.md", "r", encoding="utf-8") as f:
|
|
4
|
-
long_description = f.read()
|
|
5
|
-
|
|
6
|
-
setuptools.setup(
|
|
7
|
-
name="better-ffmpeg-progress",
|
|
8
|
-
version="2.1.
|
|
9
|
-
author="GitHub.com/CrypticSignal",
|
|
10
|
-
author_email="theaudiophile@outlook.com",
|
|
11
|
-
description="Run FFmpeg & see percentage progress + ETA.",
|
|
12
|
-
long_description=long_description,
|
|
13
|
-
long_description_content_type="text/markdown",
|
|
14
|
-
url="https://github.com/CrypticSignal/better-ffmpeg-progress",
|
|
15
|
-
packages=["better_ffmpeg_progress"],
|
|
16
|
-
install_requires=["ffmpeg-python", "tqdm"],
|
|
17
|
-
python_requires=">=3.6",
|
|
18
|
-
keywords=["ffmpeg", "progress"],
|
|
19
|
-
classifiers=[
|
|
20
|
-
"Programming Language :: Python :: 3",
|
|
21
|
-
"License :: OSI Approved :: MIT License",
|
|
22
|
-
"Operating System :: OS Independent",
|
|
23
|
-
],
|
|
24
|
-
)
|
|
1
|
+
import setuptools
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as f:
|
|
4
|
+
long_description = f.read()
|
|
5
|
+
|
|
6
|
+
setuptools.setup(
|
|
7
|
+
name="better-ffmpeg-progress",
|
|
8
|
+
version="2.1.6",
|
|
9
|
+
author="GitHub.com/CrypticSignal",
|
|
10
|
+
author_email="theaudiophile@outlook.com",
|
|
11
|
+
description="Run FFmpeg & see percentage progress + ETA.",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/CrypticSignal/better-ffmpeg-progress",
|
|
15
|
+
packages=["better_ffmpeg_progress"],
|
|
16
|
+
install_requires=["ffmpeg-python", "tqdm"],
|
|
17
|
+
python_requires=">=3.6",
|
|
18
|
+
keywords=["ffmpeg", "progress"],
|
|
19
|
+
classifiers=[
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
],
|
|
24
|
+
)
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: better-ffmpeg-progress
|
|
3
|
-
Version: 2.1.4
|
|
4
|
-
Summary: Run FFmpeg & see percentage progress + ETA.
|
|
5
|
-
Home-page: https://github.com/CrypticSignal/better-ffmpeg-progress
|
|
6
|
-
Author: GitHub.com/CrypticSignal
|
|
7
|
-
Author-email: theaudiophile@outlook.com
|
|
8
|
-
License: UNKNOWN
|
|
9
|
-
Description: <div align="center">
|
|
10
|
-
|
|
11
|
-
[](https://pypistats.org/packages/pypistats)
|
|
12
|
-
[](https://pypistats.org/packages/pypistats)
|
|
13
|
-
[](LICENSE.txt)
|
|
14
|
-
|
|
15
|
-
# Better FFmpeg Progress
|
|
16
|
-
|
|
17
|
-
Runs an FFmpeg command and uses [tqdm](https://github.com/tqdm/tqdm) to show a progress bar.
|
|
18
|
-
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
## Example:
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
39%|███████████████████████████████████████████ | 23.6/60.2 [00:19<00:34, 1.07s/s]
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Where:
|
|
28
|
-
|
|
29
|
-
- `39%` is the percentage progress.
|
|
30
|
-
- `23.6` seconds of the input file have been processed.
|
|
31
|
-
- `60.2` is the duration of the input file in seconds.
|
|
32
|
-
- `00:19` is the time elapsed since the FFmpeg process started.
|
|
33
|
-
- `00:34` is the estimated time required for the FFmpeg process to complete.
|
|
34
|
-
- `1.07` shows how many seconds of the input file are processed per second.
|
|
35
|
-
|
|
36
|
-
## Installation:
|
|
37
|
-
|
|
38
|
-
`pip3 install better-ffmpeg-progress --upgrade`
|
|
39
|
-
|
|
40
|
-
## Usage:
|
|
41
|
-
|
|
42
|
-
Create an instance of the `FfmpegProcess` class and supply a list of arguments like you would to `subprocess.run()`.
|
|
43
|
-
|
|
44
|
-
Simple Example:
|
|
45
|
-
|
|
46
|
-
```py
|
|
47
|
-
from better_ffmpeg_progress import FfmpegProcess
|
|
48
|
-
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
49
|
-
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
50
|
-
# Use the run method to run the FFmpeg command.
|
|
51
|
-
process.run()
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Advanced Example:
|
|
55
|
-
|
|
56
|
-
```py
|
|
57
|
-
from better_ffmpeg_progress import FfmpegProcess
|
|
58
|
-
|
|
59
|
-
def handle_progress_info(percentage, speed, eta, estimated_filesize):
|
|
60
|
-
print(f"Estimated Output Filesize: {estimated_filesize / 1_000_000} MB")
|
|
61
|
-
|
|
62
|
-
def handle_success():
|
|
63
|
-
# Code to run if the FFmpeg process completes successfully.
|
|
64
|
-
pass
|
|
65
|
-
|
|
66
|
-
def handle_error():
|
|
67
|
-
# Code to run if the FFmpeg process encounters an error.
|
|
68
|
-
pass
|
|
69
|
-
|
|
70
|
-
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
71
|
-
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
72
|
-
|
|
73
|
-
ffmpeg_output_path = 'ffmpeg_output.txt'
|
|
74
|
-
|
|
75
|
-
# Use the run method to run the FFmpeg command.
|
|
76
|
-
process.run(progress_handler=handle_progress_info, ffmpeg_output_file=ffmpeg_output_path, success_handler=handle_success, error_handler=handle_error)
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
The `run` method takes the following **optional** arguments:
|
|
80
|
-
|
|
81
|
-
- `progress_handler`
|
|
82
|
-
|
|
83
|
-
- You can create a function if you would like to do something with the following values:
|
|
84
|
-
|
|
85
|
-
- Percentage progress. [float]
|
|
86
|
-
- Speed, e.g. `22.3x` which means that 22.3 seconds of the input are processed every second. [string]
|
|
87
|
-
- ETA in seconds. [float]
|
|
88
|
-
- Estimated output filesize in bytes. [float]
|
|
89
|
-
- _Note: This is not accurate. Please take the value with a grain of salt._
|
|
90
|
-
|
|
91
|
-
The values will be `None` if unknown. The function will receive the aforementioned metrics as arguments, about two times per second.
|
|
92
|
-
|
|
93
|
-
- `ffmpeg_output_file` - A string path to define where you want the output of FFmpeg to be saved. By default, this is saved in a folder named "ffmpeg_output", with the filename `[<input_filename>].txt`.
|
|
94
|
-
|
|
95
|
-
- `success_handler` - A function to run if the FFmpeg process completes successfully.
|
|
96
|
-
|
|
97
|
-
- `error_handler` - A function to run if the FFmpeg process encounters an error.
|
|
98
|
-
|
|
99
|
-
## Changelog:
|
|
100
|
-
|
|
101
|
-
[19/09/2022]
|
|
102
|
-
|
|
103
|
-
- Add the ability to specify a `success_handler` argument, a function to run if the FFmpeg process completes successfully.
|
|
104
|
-
- Add 0.001 to tqdm's `total` parameter to prevent the chance of getting `TqdmWarning: clamping frac to range [0, 1]`
|
|
105
|
-
|
|
106
|
-
[21/12/2022]
|
|
107
|
-
|
|
108
|
-
- [v2.0.7] Fix `'estimated_size' referenced before assignment` error.
|
|
109
|
-
- [v2.0.7] The progress bar now uses 1 decimal place for seconds processed and total duration.
|
|
110
|
-
|
|
111
|
-
[22/12/2022]
|
|
112
|
-
|
|
113
|
-
- [v2.0.8] Add the ability to specify an `error_handler` argument, a function to run if the FFmpeg process encounters an error.
|
|
114
|
-
- [v2.0.9] Fix a typo (commit [da45a84](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/da45a8416856ab7d3c7b748db5703fa3dbc65f60))
|
|
115
|
-
|
|
116
|
-
[07/02/2022]
|
|
117
|
-
|
|
118
|
-
- [v2.1.0] [Update function name](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/572fe8a0d71957d00b833134a4d35170630203fa) to fix `'process_complete_handler' is not defined` error.
|
|
119
|
-
|
|
120
|
-
[05/11/2023]
|
|
121
|
-
|
|
122
|
-
- [v2.1.2] [Do not exit the Python interpreter after the FFmpeg process is complete](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/0a358810773835297faae688689c6e0d8a5859ae)
|
|
123
|
-
|
|
124
|
-
[22/04/2024]
|
|
125
|
-
|
|
126
|
-
- [v2.1.3] Fix issue [#20](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/20)
|
|
127
|
-
|
|
128
|
-
[28/04/2024]
|
|
129
|
-
|
|
130
|
-
- [v2.1.4] Fix issue [#21](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/21)
|
|
131
|
-
|
|
132
|
-
Keywords: ffmpeg,progress
|
|
133
|
-
Platform: UNKNOWN
|
|
134
|
-
Classifier: Programming Language :: Python :: 3
|
|
135
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
136
|
-
Classifier: Operating System :: OS Independent
|
|
137
|
-
Requires-Python: >=3.6
|
|
138
|
-
Description-Content-Type: text/markdown
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
import subprocess
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
from ffmpeg import probe
|
|
7
|
-
from tqdm import tqdm
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class FfmpegProcess:
|
|
11
|
-
"""
|
|
12
|
-
Args:
|
|
13
|
-
command (list): A list of arguments to pass to FFmpeg.
|
|
14
|
-
|
|
15
|
-
ffmpeg_loglevel (str, optional): Desired FFmpeg log level. Default is "verbose".
|
|
16
|
-
|
|
17
|
-
Raises:
|
|
18
|
-
ValueError: If the list of arguments does not include "-i".
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
def __init__(self, command, ffmpeg_loglevel="verbose"):
|
|
22
|
-
if "-i" not in command:
|
|
23
|
-
raise ValueError("FFmpeg command must include '-i'")
|
|
24
|
-
|
|
25
|
-
self._ffmpeg_args = command + ["-hide_banner", "-loglevel", ffmpeg_loglevel]
|
|
26
|
-
self._output_filepath = command[-1]
|
|
27
|
-
|
|
28
|
-
self._set_file_info()
|
|
29
|
-
|
|
30
|
-
self._estimated_size = None
|
|
31
|
-
self._eta = None
|
|
32
|
-
self._percentage_progress = 0
|
|
33
|
-
self._previous_seconds_processed = 0
|
|
34
|
-
self._progress_bar = None
|
|
35
|
-
self._seconds_processed = 0
|
|
36
|
-
self._speed = 0
|
|
37
|
-
self._current_size = 0
|
|
38
|
-
|
|
39
|
-
def _set_file_info(self):
|
|
40
|
-
index_of_filepath = self._ffmpeg_args.index("-i") + 1
|
|
41
|
-
self._filepath = self._ffmpeg_args[index_of_filepath]
|
|
42
|
-
self._can_get_duration = True
|
|
43
|
-
|
|
44
|
-
try:
|
|
45
|
-
self._duration_secs = float(probe(self._filepath)["format"]["duration"])
|
|
46
|
-
print(
|
|
47
|
-
f"The duration of {self._filepath} has been detected as {self._duration_secs} seconds."
|
|
48
|
-
)
|
|
49
|
-
except Exception:
|
|
50
|
-
self._can_get_duration = False
|
|
51
|
-
|
|
52
|
-
if self._can_get_duration:
|
|
53
|
-
self._ffmpeg_args += ["-progress", "pipe:1", "-nostats"]
|
|
54
|
-
|
|
55
|
-
def _should_run_ffmpeg(self):
|
|
56
|
-
dirname = os.path.dirname(self._output_filepath)
|
|
57
|
-
self._dir_files = (
|
|
58
|
-
[file for file in os.listdir(dirname)] if dirname else [file for file in os.listdir()]
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
if "-y" not in self._ffmpeg_args and self._output_filepath in self._dir_files:
|
|
62
|
-
choice = input(f"{self._output_filepath} already exists. Overwrite? [Y/N]: ").lower()
|
|
63
|
-
|
|
64
|
-
if choice != "y":
|
|
65
|
-
print(
|
|
66
|
-
"FFmpeg will not run as the output filename already exists, and you do not want it to be overwritten."
|
|
67
|
-
)
|
|
68
|
-
return False
|
|
69
|
-
|
|
70
|
-
self._ffmpeg_args.insert(1, "-y")
|
|
71
|
-
return True
|
|
72
|
-
|
|
73
|
-
return True
|
|
74
|
-
|
|
75
|
-
def _update_progress(self, ffmpeg_output, progress_handler):
|
|
76
|
-
if ffmpeg_output:
|
|
77
|
-
value = ffmpeg_output.split("=")[1].strip()
|
|
78
|
-
|
|
79
|
-
if progress_handler is None:
|
|
80
|
-
if "out_time_ms" in ffmpeg_output:
|
|
81
|
-
seconds_processed = round(int(value) / 1_000_000, 1)
|
|
82
|
-
seconds_increase = seconds_processed - self._previous_seconds_processed
|
|
83
|
-
self._progress_bar.update(seconds_increase)
|
|
84
|
-
self._previous_seconds_processed = seconds_processed
|
|
85
|
-
|
|
86
|
-
else:
|
|
87
|
-
if "total_size" in ffmpeg_output and "N/A" not in value:
|
|
88
|
-
self._current_size = int(value)
|
|
89
|
-
|
|
90
|
-
elif "out_time_ms" in ffmpeg_output:
|
|
91
|
-
self._seconds_processed = int(value) / 1_000_000
|
|
92
|
-
|
|
93
|
-
if self._can_get_duration:
|
|
94
|
-
self._percentage_progress = (
|
|
95
|
-
self._seconds_processed / self._duration_secs
|
|
96
|
-
) * 100
|
|
97
|
-
|
|
98
|
-
if self._current_size is not None and self._percentage_progress != 0.0:
|
|
99
|
-
self._estimated_size = self._current_size * (
|
|
100
|
-
100 / self._percentage_progress
|
|
101
|
-
)
|
|
102
|
-
|
|
103
|
-
elif "speed" in ffmpeg_output:
|
|
104
|
-
speed_str = value[:-1]
|
|
105
|
-
|
|
106
|
-
if speed_str != "0" and "N/A" not in value:
|
|
107
|
-
self._speed = float(speed_str)
|
|
108
|
-
|
|
109
|
-
if self._can_get_duration:
|
|
110
|
-
self._eta = (
|
|
111
|
-
self._duration_secs - self._seconds_processed
|
|
112
|
-
) / self._speed
|
|
113
|
-
|
|
114
|
-
if ffmpeg_output == "progress=end":
|
|
115
|
-
self._percentage_progress = 100
|
|
116
|
-
self._eta = 0
|
|
117
|
-
|
|
118
|
-
progress_handler(
|
|
119
|
-
self._percentage_progress, self._speed, self._eta, self._estimated_size
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
def run(
|
|
123
|
-
self,
|
|
124
|
-
progress_handler=None,
|
|
125
|
-
ffmpeg_output_file=None,
|
|
126
|
-
success_handler=None,
|
|
127
|
-
error_handler=None,
|
|
128
|
-
):
|
|
129
|
-
if not self._should_run_ffmpeg():
|
|
130
|
-
return
|
|
131
|
-
|
|
132
|
-
if ffmpeg_output_file is None:
|
|
133
|
-
os.makedirs("ffmpeg_output", exist_ok=True)
|
|
134
|
-
ffmpeg_output_file = os.path.join("ffmpeg_output", f"[{Path(self._filepath).name}].txt")
|
|
135
|
-
|
|
136
|
-
with open(ffmpeg_output_file, "a") as f:
|
|
137
|
-
process = subprocess.Popen(self._ffmpeg_args, stdout=subprocess.PIPE, stderr=f)
|
|
138
|
-
print(f"\nRunning: {' '.join(self._ffmpeg_args)}\n")
|
|
139
|
-
|
|
140
|
-
if progress_handler is None and self._can_get_duration:
|
|
141
|
-
self._progress_bar = tqdm(
|
|
142
|
-
total=round(self._duration_secs, 1),
|
|
143
|
-
unit="s",
|
|
144
|
-
dynamic_ncols=True,
|
|
145
|
-
leave=False,
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
try:
|
|
149
|
-
while process.poll() is None:
|
|
150
|
-
ffmpeg_output = process.stdout.readline().decode().strip()
|
|
151
|
-
self._update_progress(ffmpeg_output, progress_handler)
|
|
152
|
-
|
|
153
|
-
if process.returncode != 0:
|
|
154
|
-
if error_handler:
|
|
155
|
-
error_handler()
|
|
156
|
-
return
|
|
157
|
-
|
|
158
|
-
print(
|
|
159
|
-
f"The FFmpeg process encountered an error. The output of FFmpeg can be found in {ffmpeg_output_file}"
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
if success_handler:
|
|
163
|
-
success_handler()
|
|
164
|
-
|
|
165
|
-
print(f"\n\nDone! To see FFmpeg's output, check out {ffmpeg_output_file}")
|
|
166
|
-
|
|
167
|
-
except KeyboardInterrupt:
|
|
168
|
-
self._progress_bar.close()
|
|
169
|
-
print("[KeyboardInterrupt] FFmpeg process killed.")
|
|
170
|
-
sys.exit()
|
|
171
|
-
|
|
172
|
-
except Exception as e:
|
|
173
|
-
print(f"[Better FFmpeg Process] {e}")
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: better-ffmpeg-progress
|
|
3
|
-
Version: 2.1.4
|
|
4
|
-
Summary: Run FFmpeg & see percentage progress + ETA.
|
|
5
|
-
Home-page: https://github.com/CrypticSignal/better-ffmpeg-progress
|
|
6
|
-
Author: GitHub.com/CrypticSignal
|
|
7
|
-
Author-email: theaudiophile@outlook.com
|
|
8
|
-
License: UNKNOWN
|
|
9
|
-
Description: <div align="center">
|
|
10
|
-
|
|
11
|
-
[](https://pypistats.org/packages/pypistats)
|
|
12
|
-
[](https://pypistats.org/packages/pypistats)
|
|
13
|
-
[](LICENSE.txt)
|
|
14
|
-
|
|
15
|
-
# Better FFmpeg Progress
|
|
16
|
-
|
|
17
|
-
Runs an FFmpeg command and uses [tqdm](https://github.com/tqdm/tqdm) to show a progress bar.
|
|
18
|
-
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
## Example:
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
39%|███████████████████████████████████████████ | 23.6/60.2 [00:19<00:34, 1.07s/s]
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Where:
|
|
28
|
-
|
|
29
|
-
- `39%` is the percentage progress.
|
|
30
|
-
- `23.6` seconds of the input file have been processed.
|
|
31
|
-
- `60.2` is the duration of the input file in seconds.
|
|
32
|
-
- `00:19` is the time elapsed since the FFmpeg process started.
|
|
33
|
-
- `00:34` is the estimated time required for the FFmpeg process to complete.
|
|
34
|
-
- `1.07` shows how many seconds of the input file are processed per second.
|
|
35
|
-
|
|
36
|
-
## Installation:
|
|
37
|
-
|
|
38
|
-
`pip3 install better-ffmpeg-progress --upgrade`
|
|
39
|
-
|
|
40
|
-
## Usage:
|
|
41
|
-
|
|
42
|
-
Create an instance of the `FfmpegProcess` class and supply a list of arguments like you would to `subprocess.run()`.
|
|
43
|
-
|
|
44
|
-
Simple Example:
|
|
45
|
-
|
|
46
|
-
```py
|
|
47
|
-
from better_ffmpeg_progress import FfmpegProcess
|
|
48
|
-
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
49
|
-
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
50
|
-
# Use the run method to run the FFmpeg command.
|
|
51
|
-
process.run()
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Advanced Example:
|
|
55
|
-
|
|
56
|
-
```py
|
|
57
|
-
from better_ffmpeg_progress import FfmpegProcess
|
|
58
|
-
|
|
59
|
-
def handle_progress_info(percentage, speed, eta, estimated_filesize):
|
|
60
|
-
print(f"Estimated Output Filesize: {estimated_filesize / 1_000_000} MB")
|
|
61
|
-
|
|
62
|
-
def handle_success():
|
|
63
|
-
# Code to run if the FFmpeg process completes successfully.
|
|
64
|
-
pass
|
|
65
|
-
|
|
66
|
-
def handle_error():
|
|
67
|
-
# Code to run if the FFmpeg process encounters an error.
|
|
68
|
-
pass
|
|
69
|
-
|
|
70
|
-
# Pass a list of FFmpeg arguments, like you would if using subprocess.run()
|
|
71
|
-
process = FfmpegProcess(["ffmpeg", "-i", "input.mp4", "-c:a", "libmp3lame", "output.mp3"])
|
|
72
|
-
|
|
73
|
-
ffmpeg_output_path = 'ffmpeg_output.txt'
|
|
74
|
-
|
|
75
|
-
# Use the run method to run the FFmpeg command.
|
|
76
|
-
process.run(progress_handler=handle_progress_info, ffmpeg_output_file=ffmpeg_output_path, success_handler=handle_success, error_handler=handle_error)
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
The `run` method takes the following **optional** arguments:
|
|
80
|
-
|
|
81
|
-
- `progress_handler`
|
|
82
|
-
|
|
83
|
-
- You can create a function if you would like to do something with the following values:
|
|
84
|
-
|
|
85
|
-
- Percentage progress. [float]
|
|
86
|
-
- Speed, e.g. `22.3x` which means that 22.3 seconds of the input are processed every second. [string]
|
|
87
|
-
- ETA in seconds. [float]
|
|
88
|
-
- Estimated output filesize in bytes. [float]
|
|
89
|
-
- _Note: This is not accurate. Please take the value with a grain of salt._
|
|
90
|
-
|
|
91
|
-
The values will be `None` if unknown. The function will receive the aforementioned metrics as arguments, about two times per second.
|
|
92
|
-
|
|
93
|
-
- `ffmpeg_output_file` - A string path to define where you want the output of FFmpeg to be saved. By default, this is saved in a folder named "ffmpeg_output", with the filename `[<input_filename>].txt`.
|
|
94
|
-
|
|
95
|
-
- `success_handler` - A function to run if the FFmpeg process completes successfully.
|
|
96
|
-
|
|
97
|
-
- `error_handler` - A function to run if the FFmpeg process encounters an error.
|
|
98
|
-
|
|
99
|
-
## Changelog:
|
|
100
|
-
|
|
101
|
-
[19/09/2022]
|
|
102
|
-
|
|
103
|
-
- Add the ability to specify a `success_handler` argument, a function to run if the FFmpeg process completes successfully.
|
|
104
|
-
- Add 0.001 to tqdm's `total` parameter to prevent the chance of getting `TqdmWarning: clamping frac to range [0, 1]`
|
|
105
|
-
|
|
106
|
-
[21/12/2022]
|
|
107
|
-
|
|
108
|
-
- [v2.0.7] Fix `'estimated_size' referenced before assignment` error.
|
|
109
|
-
- [v2.0.7] The progress bar now uses 1 decimal place for seconds processed and total duration.
|
|
110
|
-
|
|
111
|
-
[22/12/2022]
|
|
112
|
-
|
|
113
|
-
- [v2.0.8] Add the ability to specify an `error_handler` argument, a function to run if the FFmpeg process encounters an error.
|
|
114
|
-
- [v2.0.9] Fix a typo (commit [da45a84](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/da45a8416856ab7d3c7b748db5703fa3dbc65f60))
|
|
115
|
-
|
|
116
|
-
[07/02/2022]
|
|
117
|
-
|
|
118
|
-
- [v2.1.0] [Update function name](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/572fe8a0d71957d00b833134a4d35170630203fa) to fix `'process_complete_handler' is not defined` error.
|
|
119
|
-
|
|
120
|
-
[05/11/2023]
|
|
121
|
-
|
|
122
|
-
- [v2.1.2] [Do not exit the Python interpreter after the FFmpeg process is complete](https://github.com/CrypticSignal/better-ffmpeg-progress/commit/0a358810773835297faae688689c6e0d8a5859ae)
|
|
123
|
-
|
|
124
|
-
[22/04/2024]
|
|
125
|
-
|
|
126
|
-
- [v2.1.3] Fix issue [#20](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/20)
|
|
127
|
-
|
|
128
|
-
[28/04/2024]
|
|
129
|
-
|
|
130
|
-
- [v2.1.4] Fix issue [#21](https://github.com/CrypticSignal/better-ffmpeg-progress/issues/21)
|
|
131
|
-
|
|
132
|
-
Keywords: ffmpeg,progress
|
|
133
|
-
Platform: UNKNOWN
|
|
134
|
-
Classifier: Programming Language :: Python :: 3
|
|
135
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
136
|
-
Classifier: Operating System :: OS Independent
|
|
137
|
-
Requires-Python: >=3.6
|
|
138
|
-
Description-Content-Type: text/markdown
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|