slhck/ffmpeg-quality-metrics

[Windows/CMD] Colored prompts not working with ANSI-Escape Sequences in CMD-Shell

e-d-n-a opened this issue · 5 comments

I saw you're using raw ANSI escape sequences for coloring the tags in you "print_error", "print_warning" and "print_info" functions.
While most modern shells support them, CMD-Shell on Windows is still around and doesn't.

In Python the package colorama is an easy fix for that.
It wraps the std-outputs and translates escape sequences to Win32-API-Calls or drops them for redirects, if necessary.
It is cross-platfom, still maintained and simple to use.

Simplest solution is to import it and initialize it in "main()" via "colorama.init()".

slhck commented

This is a good suggestion.

Initializing colorama in main itself will not suffice; it should be initialized in the library directly, because you may want to import it and use some functions directly. (Ideally the functions should not exit themselves and not print stuff, but that is something for a v1.x.)

Please check whether the new commit works for you.

Sorry, I still noticed an issue with the use of colorama here, that I now investigated!

"colorama" always wraps both output streams (STDOUT, STDERR) or neither.
This is a problem as it doesn't support redirecting content from STDOUT into a file, while coloring STDERR properly.

See these issues of colorama, that I found:
Windows: Style.RESET_ALL does not work if stdout is redirected.
stderr isn't reset on exit
Provide possibility to wrap separately either stdout or stderr

So there is also a problem with the exit code in this case.

If I try to run something like this:

ffmpeg_quality_metrics 480p_0-5s.mp4 1080p_0-5s.mp4 -n -of json > NUL

or simpler, as a test, something like this:

python -c "import colorama as c, sys; c.init(); print(c.Fore.GREEN+'Hello'+c.Fore.RESET, file=sys.stderr)" > NUL

...then the console text stays colored (when using your hardcoded reset) or it gets reset to black (when using "Fore.RESET").
Btw, coloroma uses code 39 to reset the foreground color (see ansi.py)

So I suggest reopening this issue, as "colorama" doesn't seem to do the job for this application/issue atm.

slhck commented

Hmm, that's too bad. I'm not sure we actually need color support, so I simply removed the ANSI escape sequences altogether. If you have a more stable solution feel free to provide a PR for it! (I'd then also happily add cross-platform color support to all other CLI tools that I've written.)

(I still hope there will be some day where Python stuff "just works" under Windows.)

Well, Windows 10 will get the new Windows Terminal that suppots ANSI escape codes and is closer to a CLI for Linux.

So I guess, it's just not worth the trouble supporting older OSes and shells.
I thought, colorama was in a usable state, but it seems to have these basic issues open for years now.
So, it's best to check for ANSI-support and maybe omit the codes, if it's not supported.
(e.g. wrap the strings with a helper-function like: "colored('INFO' ,color.BLUE)", that adds or omits the ANSI codes based on detected platfom)

Also at colorama issues people like to have an option to switch off colors via an environment variable:

https://github.com/tartley/colorama/issues/268
Suggestion: supporting NO_COLOR environment variable

https://no-color.org/

colorama also seems to have various issues on Windows 10:

https://github.com/tartley/colorama/issues/104
Support for Windows 10 built-in ANSI cmd

https://github.com/tartley/colorama/issues/265
Colors STOPPED showing in Windows 10, latest update.

https://github.com/tartley/colorama/issues/296
Some colors and styles are not working properly on Windows 10 with Python 3.9.1

https://github.com/tartley/colorama/issues/234
Colorama not working with input() in python 3.7.3, windows 10 build 17763.805

https://github.com/tartley/colorama/issues/48
Escape sequences are unprocessed on Windows with TERM set

https://github.com/tartley/colorama/issues/79
On Python 3.5: Colorama does not recognize Windows environment

https://github.com/tartley/colorama/issues/49
ANSI reset code is printed on Windows on program exit
slhck commented

Closing this for the time being, falling back to a normal logger. PRs to add support are welcome but I think this is a non-essential feature.