-
Notifications
You must be signed in to change notification settings - Fork 857
Add background_color option to gifv #907
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
Conversation
7cb7ac5 to
c2ecc75
Compare
|
It would be nice if the option was documented :P |
|
@masom haha, yes, totally agree. I'll work on that now. |
|
As noted in docs, latest release of ffmpeg breaks things. I'll see if I can pin the ffmpeg verion in the travis.yml |
fde4a79 to
4b473d1
Compare
|
@masom I ended up having to build ffmpeg from source, those ppas won't work for 12.04 unfortunately. Also, 12.04 get EOL'ed in 10 days ... so we might want to consider testing on 14.04 or better. |
|
@scorphus @andreaugusto Any thoughts on this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's just incredible, @okor. I mean, look at the docs you've added! That's pretty amazing! Thank you so much!
Apart from the aforementioned changes requested below, are you done with it or willing to write tests for optimze? 😃
docs/gifv.rst
Outdated
|
|
||
| The gifv optimizer is able to convert gifs to mp4 or webm videos, often resulting in dramatically smaller sized files. | ||
|
|
||
| **Gifv is categorized as experimental and should be used with caution.** It uses ffmpeg to convert gifs to videos and so it's sensetive to changes with ffmpeg. It's recommended to lock your ffmpeg version with a fixed version (chef, docker, etc) and if updating make sure to check that the update doesn't break gifv. **FFmpeg version 3.2.4 is the current recommended version.** Later version, such as 3.3 will break the proper conversion of gif delays to frame durations in videos ... meaning videos will not be the same length as equivelant gifs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a small typo here: s/sensetive/sensitive/
Also, “Later versions, such as 3.3, will break” reads best IMHO.
docs/gifv.rst
Outdated
| 'thumbor.optimizers.gifv', | ||
| ] | ||
| Once activated, you must add the ``gifv()`` option to your filters list. And example request might look like this: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/And/An/ I guess?
thumbor/optimizers/gifv.py
Outdated
| if color_string and bg_color_hex is None: | ||
| logger.error("background_color value could not be parsed") | ||
|
|
||
| return bg_color_hex |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be simplified a bit:
def normalize_color_to_hex(self, color_string):
try:
return webcolors.normalize_hex("#" + color_string)
except ValueError:
pass
try:
return webcolors.name_to_hex(color_string)
except ValueError:
pass
try:
return webcolors.normalize_hex(color_string)
except ValueError:
pass
if color_string:
logger.error('background_color value could not be parsed')|
@okor, I forgot to mention: good work with the gifv optimizer also! |
|
@scorphus Hey, you can merge this now if you want but I'm going to add some more robust tests for gifv either way. |
|
@scorphus It occurs to me that it might be faster to pipe buffers into and out of ffmpeg, instead of using files. Are |
|
Actually looks like |
|
Just in time: This PR looks great! Nothing to add to the discussion. :) |
|
Ok, we all seem to be good with this. Gonna' merge. @scorphus What version do you think this should be bumped to? |
'reverse' complex filter has to buffer entire video content in memory before next filter can chop off last frame. In case of long big gif inputs, amount of memory could exceed few gigabytes. If thumbor server at the same time tries to optimize 2 gifv files, it's likely to run out of memory and be killed with OOM killer. When ffmpeg process killed, optimizer throws exception, but due to the fact thumbor misuses futures, exception is never retrieved, so request waits until timeout happens. There is a high chance that many requests will hang at the same time, effectively exhausting open files limit and rendering service interruption. Reverse filter needed to overcome issue with ffmpeg dropping last frame duration when used with overlay filter, which, in turn, was used to add color-background for input gifs with transparency. Turns out, that ffmpeg's gif decoder can be supplied with -trans_color parameter, which does exactly that, but on decoding stage. This allows to remove memory-heavy reverse filter and overlay all together. As a side effect, previously broken ffmpeg 3.3 should also work fine. see thumbor#907
'reverse' complex filter has to buffer entire video content in memory before next filter can chop off last frame. In case of long big gif inputs, amount of memory could exceed few gigabytes. If thumbor server at the same time tries to optimize 2 gifv files, it's likely to run out of memory and be killed with OOM killer. When ffmpeg process killed, optimizer throws exception, but due to the fact thumbor misuses futures, exception is never retrieved, so request waits until timeout happens. There is a high chance that many requests will hang at the same time, effectively exhausting open files limit and rendering service interruption. Reverse filter needed to overcome issue with ffmpeg dropping last frame duration when used with overlay filter, which, in turn, was used to add color-background for input gifs with transparency. Turns out, that ffmpeg's gif decoder can be supplied with -trans_color parameter, which does exactly that, but on decoding stage. This allows to remove memory-heavy reverse filter and overlay all together. As a side effect, previously broken ffmpeg 3.3 should also work fine. see #907
This PR:
background_coloroption which only works with gifvThe reason we need the background color option is that some gifs contain transparency. These transparent regions will be converted to
whiteby default. But white isn't always the correct color for a websites design. ffmpeg has no simple option to change the background as far as I could tell so we use this complex filter. Since ffmpeg will fill transparency with white every time and this new command is just as fast as the old one (benchmarked locally) we just use the same command every time even if no background option is specified - we just use white like default ffmpeg would. If a background_color is specified we use that color. Web applications will need to keep track and use the appropriate color for their design. ffmpeg is a bit pickier about colors - it doesn't allow hex short code for instance. So I addedwebcolorsand a clumsy but robust logic for extracting colors while maintaining color format compatibility with the color options used in thebackground_colorandfillfilters that work with pngs. There may be a better way to do this, let me know if that's the case.We also reintroduce the scale option to ffmpeg as well with the complex filter. Both the scale and canvas (background color) filters are performed at the same time to avoid extra passes / processing time. This simplifies maintenance of thumbor because we only have a single command.
background_coloroption to normal gifs. If present the option will simply be ignored.background_colorinstead offillbecause the latter implies that all transparency should be filled but as mentioned this will mess up a gif with overlaying frame where a later frame doesn't take up 100% of the size of the image canvas or should appear to float over previous frames. This is a true background color option.This PR has been tested against ffmpeg version
3.2.4There are known issues with using these filters with later releases such as 3.3 but earlier version may work as well. See open ffmpeg issue: https://trac.ffmpeg.org/ticket/6294 Since the gifv filter is still categorized as experimental I think it's ok to exclude some versions of ffmpeg. Hopefully ffmpeg will fix their bugs in the next release.Example requests with identical output:
http://localhost:8888/unsafe/500x0/filters:gifv():background_color(ff00ff)/http://localhost/top_pin_wide.gifhttp://localhost:8888/unsafe/500x0/filters:gifv():background_color(f0f)/http://localhost/top_pin_wide.gifhttp://localhost:8888/unsafe/500x0/filters:gifv():background_color(magenta)/http://localhost/top_pin_wide.gifhttp://localhost:8888/unsafe/500x0/filters:gifv():background_color(Magenta)/http://localhost/top_pin_wide.gifhttp://localhost:8888/unsafe/500x0/filters:gifv():background_color(MaGeNTa)/http://localhost/top_pin_wide.gifExample input with transparency:

Example output (mp4 converted back to gif manually, no mp4s supported in GH markdown)
