Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add estimated file size #3

Closed
jmraker opened this issue Nov 25, 2021 · 6 comments
Closed

Feature: Add estimated file size #3

jmraker opened this issue Nov 25, 2021 · 6 comments
Labels
enhancement New feature or request

Comments

@jmraker
Copy link

jmraker commented Nov 25, 2021

I was able to add an estimated file size that seems to estimate okay after a few progress updates. It checks for changes because ffmpeg sporadically writes to disk and it's probably the most accurate when it writes.

                totalSize = 0;
                prevTotalSize = 0;
                etaSize = "unknown"
                                                if "total_size" in ffmpeg_output:
                                                        totalSize = int(ffmpeg_output.split("=")[1]);
                                                        if(percentage != "unknown" and percentage > 0):
                                                                if(totalSize != prevTotalSize):
                                                                        prevTotalSize = totalSize;
                                                                        etaSize = int(totalSize * (100 / percentage))
                                                                        if(etaSize > (1024*1024*1024)):
                                                                                etaSize = str(round(etaSize / (1024*1024*1024), 2)) + "G";
                                                                        elif(etaSize > (1024*1024)):
                                                                                etaSize = str(round(etaSize / (1024*1024), 2)) + "M";
                                                                        elif(etaSize > 1024):
                                                                                etaSize = str(round(etaSize / (1024), 2)) + "K";

                                                elif "out_time_ms" in ffmpeg_output:
                                                        microseconds = int(ffmpeg_output[12:])
                                                        secs = microseconds / 1_000_000
                                                        if file_duration is not None:
                                                                percentage = round((secs / file_duration) * 100, 1)

                                                elif "speed" in ffmpeg_output:
                                                        speed = ffmpeg_output.split("=")[1].strip()
                                                        speed = 0 if " " in speed or "N/A" in speed else float(speed[:-1])
                                                        if speed != 0:
                                                                eta = (file_duration - secs) / speed
                                                                seconds = round(eta % 60)
                                                                minutes = int(eta / 60)
                                                                hours = int(minutes / 60)
                                                                minutes = round(minutes % 60)
                                                                eta_string = f"{hours}:{minutes:02d}:{seconds:02d}"

                                                        if progress_handler is None:
                                                                print(f"Progress: {percentage}% | Speed: {speed}x | ETA: {eta_string} | Estimated Size: {etaSize}    ", end="\r")
                                                        else:
                                                                progress_handler(percentage, f"{speed}x", eta)
@CrypticSignal
Copy link
Owner

CrypticSignal commented Nov 27, 2021

Better FFmpeg Progress no longer shows a progress string but rather a tqdm progress bar. I do not wish to clog up the progress bar with the estimated filesize.

However, what you can do is send the estimated filesize as an additional argument to progress_handler (right now, only the percentage progress, speed and ETA are passed as arguments). This would allow the user to use the estimated filesize in a custom progress handler.

If you decide to implement this, please submit a pull request rather than opening an issue as the former is more appropriate.

A few things to note:

  • This is a Python project, where snake_case is the norm rather than camelCase. Variable names such as etaSize should be changed to their snake case equivalent, e.g. eta_size.

  • I've noticed that some of your conditions are wrapped in a pair of brackets. In python, conditons are not wrapped in a pair of brackets, so lines such as if(totalSize != prevTotalSize): need to be changed to if total_size != prev_total_size:.

  • Lines of code should not terminate with a semi colon.

  • Use 1000 rather than 1024 as the norm for filesizes are kilobytes (KB), megabytes (MB) and gigabytes (GB) rather than kibibytes (KiB), mebibytes (MiB) and gibibytes (GiB).

@CrypticSignal CrypticSignal added the enhancement New feature or request label Nov 27, 2021
@jmraker
Copy link
Author

jmraker commented Dec 6, 2021

I followed some 90 step guide on how to do a pull request and seen a mention of my edit on https://github.com/CrypticSignal/better-ffmpeg-progress/pulls but when I checked again it was gone. No email or mention here. If there was a problem with it, I'm sure you can do the change yourself.

jmraker@ab3e53a
https://github.com/jmraker/better-ffmpeg-progress/blob/new_branch/better_ffmpeg_progress/better_ffmpeg_progress.py

@CrypticSignal
Copy link
Owner

CrypticSignal commented Dec 6, 2021

I've been testing the file size estimator and I'm not sure if I want to implement it. It only provides a good estimate when the process has essentially finished. Here is the output when transcoding a one-minute-long video to H.264 using libx264 at the default preset of medium. The data is in the format percentage progress, total_size (MB), estimated size (MB) and the filesize of the output video is 26.5 MB:

4 0.003556 0.0889                                                                                                                                         
24 1.572864 6.5536
32 3.407872 10.6496
33 3.670016 11.12126
35 4.194304 11.983725
43 6.5536 15.24093
47 7.602176 16.174842
53 8.650752 16.322173
59 9.961472 16.88385
62 11.010048 17.758141
71 13.369344 18.830061
80 14.942208 18.67776
85 15.990784 18.812687
93 17.301504 18.603767
99 25.948329 26.210433

Even when the conversion was 93% complete, it was about 7 MB off the final filesize which is more than 25% off the mark.

@CrypticSignal
Copy link
Owner

Why regards to being unable to submit a pull request, it takes a few clicks so I'm surprised a 90-step guide exists. In case you're wondering, I did not see any pull requests so I certainly haven't discarded a pull request from you.

Don't worry about trying to submit a pull request as I correctly implemented the output filesize estimator myself for testing purposes, but I have refrained from pushing the code to GitHub because as shown in my previous comment, the accuracy is not good enough for my liking until the process is 99% complete.

With that being said, I might add the estimator with a disclaimer that the estimate is not very accurate and should be taken with a grain of salt.

@jmraker
Copy link
Author

jmraker commented Dec 7, 2021

I've only used it when encoding several 40 minute tv show episodes (h265 to h264). It starts off not too accurate but at around 2% it's accuracy improves enough to closely predict the final size. It does fluctuate up and down a few megs to the end because of the variable bit rate.

@CrypticSignal
Copy link
Owner

CrypticSignal commented Dec 8, 2021

@jmraker The progress_handler function now receives the estimated output filesize, in bytes. See aacadb0.

Of course you will need to update the version of better-ffmpeg-progress that you have installed, using pip3 install better-ffmpeg-progress --upgrade.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants