Closed ghost closed 3 years ago
for comparison, when I convert the same video to GIF using ffmpeg, the output is: I have a batch file for doing this with ffmpeg:
set width=-1
set length=-1
set x=0
set y=0
set /p width= "Enter width max size (empty to ignore): "
set /p length= "Enter length max size (empty to ignore): "
set /p x= "Enter x crop (empty to ignore): "
set /p y= "Enter y crop (empty to ignore): "
echo width is %width%
echo length is %length%
echo y crop is %y%
echo x crop is %x%
pause
setlocal enabledelayedexpansion
for %%A IN (*.mp4, *.mkv, *.webm) DO (
ffmpeg -i "%%A" -vf fps=24,crop=iw-%x%*2:ih-%y%*2:%x%:%y%,scale=%width%:%length%,palettegen "1/%%A.png"
ffmpeg -i "%%A" -i "1/%%A.png" -filter_complex "fps=24,crop=iw-%x%*2:ih-%y%*2:%x%:%y%,scale=%width%:%length%[a];[a][1:v]paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle" "1/%%A.gif"
)
pause
this outputs very high quality GIFs
I also kinda want to know why it's all grainy. It seems to be taking the palette of the first frame and then applying that to the remaining frames. Here's a webm and GIF comparison of something I just did with it. Gif: https://files.catbox.moe/7260eb.gif Webm: https://files.catbox.moe/lkqsqk.webm
When I do palettegen and paletteuse in ffmpeg and generate it manually: Gif: https://files.catbox.moe/41kuoo.gif
I built a fresh mpv
with mpv-player/mpv-build to try this. Weirdly enough, this time mpv's default output looks better than ffmpeg's default. This is comparing the mpv
and the ffmpeg
binaries coming from the same build inside mpv-build
. I still prefer the ffmpeg default, as the file size of the mpv
gif was more than 2x the size for my test input, 3 MB vs 8 MB.
mpv command:
./mpv/build/mpv input.webm --ovc=gif --o=output_mpv.gif
ffmpeg command:
./ffmpeg_build/ffmpeg -i input.webm output_ffmpeg.gif
There's probably a way to override the defaults. Maybe ffmpeg's defaults can be matched and set to the gif config here.
I built a fresh
mpv
with mpv-player/mpv-build to try this. Weirdly enough, this time mpv's default output looks better than ffmpeg's default.
In my opinion, if you want quality GIFs, you have to generate and use a palette https://gist.github.com/alexlee-gk/38916bf524dc75ca1b988d113aa30710 However I don't know exactly what's possible through this MPV script.
If this script can get ffmpeg integration, we could also get free lossless trimming of videos without re-encoding and compressing them.
However I don't know exactly what's possible through this MPV script.
It invokes a new mpv process to use its encoding capabilities.
In my opinion, if you want quality GIFs, you have to generate and use a palette
Thanks for pointing this out. It looks like you can generate and use a palette similar to how you do it with ffmpeg. I believe it should be possible to integrate the two step process into mpv-webm. I can give it a try when I have the time.
Using @ShinkoNet's samples, these two are equivalent from what I can tell.
ffmpeg -i lkqsqk.webm -vf "palettegen" palette_ffmpeg.png
ffmpeg -i lkqsqk.webm -i palette_ffmpeg.png -filter_complex "paletteuse" out_ffmpeg.gif
mpv lkqsqk.webm --ovc=png --aid=no --vf=palettegen --o=palette_mpv.png
mpv lkqsqk.webm --aid=no --external-file=palette_mpv.png --lavfi-complex="[vid1][vid2]paletteuse[vo]" --o=out_mpv.gif
I managed to hack this in an ugly way and it worked. I will try to see if I can clean it up a bit. It will require adding a unique step just for gif which might look weird in the code. I'm not sure how acceptable that is.
In the same video I get a smaller gif that also looks better compared to the current gif option. Of course that may not be the case universally. I don't know if it's better to define a new "GIF with Palette" output format or replace the existing one.
I have a proof of concept on my fork if you'd like to give it a try
https://github.com/Vzaa/mpv-webm/releases/download/latest/webm.lua
Related change
https://github.com/Vzaa/mpv-webm/commit/a0a0138d97be2bcd784bf63e80c5db8ca16b18f1
I can turn this into a PR if it looks good
Update: It looks like the palettegen step uses the whole video and not the start/end sections so if the video is long it takes really long. I'll take a look at it later if that can be fixed
I've updated the change so that it uses --vf-add=trim
instead of --start
and --end
in the palettegen
step, and --lavfi-complex
for crop and scale instread of --vf-add=lavfi-scale/lavfi-crop
in the encoding step. It is pretty hacky but it works.
With these changes in place, the trimming doesn't break palettegen
and resizing doesn't break paletteuse
.
It might fail if there are multiple video streams open at once as [vid1]
for video and [vid2]
for the palette are hard coded.
Related change: https://github.com/Vzaa/mpv-webm/commit/a479d6606709af786faabae1e1b937ba48854983
Test build: https://github.com/Vzaa/mpv-webm/releases/download/latest/webm.lua
@Vzaa That's a great improvement in quality, awesome!
I tried converting the same webm to GIF using your test build and using ffmpeg to compare the results: Source file: Webm
Conversion using your test build: MPV GIF MPV Palette GIF: 42.5 MB Palette: 1.03 KB Great result, basically the same as ffmpeg with palettegen & paletteuse.
Conversion using ffmpeg (just palettegen & paletteuse): FFMPEG GIF FFMPEG Palette GIF: 43.2 MB Palette: 985 KB
Conversion using ffmpeg (palettegen & paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle"): FFMPEG GIF FFMPEG Palette GIF: 35.4 MB Palette: 985 KB Result is lower quality, a lot of color banding.
Thanks for the feedback. Since it's using ffmpeg filters it's also possible to add the same dither filter on top.
There are other problems with my current version though. Using other filters with lavfi-complex
causes problems with the order of filters applied and some options break paletteuse
. This is why I manually replaced resize
and crop
with their lavfi-complex
equivalents in my current version. I will update it to convert --vf
options to lavfi-complex
instead of manually converting them but it looks like options such as --video-rotate
will require manual lookup as they also seem to break paletteuse
and are not vf
options. I've found that rotate
and deinterlace
both cause problems and will require the manual coversion, it is doable of course but it starts to get a bit messy to do these one by one.
@Vzaa Now that the quality is splendid, is perhaps the addition of something like this an option? https://kornel.ski/lossygif * So the user can use between quality and file size efficiency?
it appears to be merged into: https://github.com/kohler/gifsicle I just used GIFsicle: `gifsicle -b -O3 --lossy=20 .gif` It reduced a 27MB GIF into a 17MB GIF
It looks like they add something like a threshold to LZW encoding to achieve some of the gains. I don't think ffmpeg has parameters for the LZW part of things so I don't see a way to do the same easily without such an option.
In a previous post you compared paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle
to paletteuse
defaults. Similar options to paletteuse
can be added here for some quality/size tradeoff I think.
I didn't have much time to play around with this more. I will try to make this ready for a proper PR at some point. It's just that adding complex filters doesn't seem to fit that well with things here. It requires a specific gif path to be added to the code.
https://github.com/Vzaa/mpv-webm/commit/0e9d445cde4cd78aa387617c26d3b82a8cd504a0
I merged the palettegen
and paletteuse
steps into a single command and modified the filter stuff a bit. I also changed structure and defined a postCommandModifier
method so that the code can be put in the gif class. I think this might be the least intrusive it can get without changing too much. Not sure what to do about the dither
mode for paletteuse
but maybe we can make it the default or create two GIF output formats.
Other than the decision for what to do about the dither
/diff_mode
options, I think it is PR ready, but I'll test it a bit more and see if I run into any problems.
Test build: https://github.com/Vzaa/mpv-webm/releases/download/latest/webm.lua
I'm still getting the grainy-looking gifs when converting to gif. I am using the latest version of the script with shinchiro's latest mpv build along with the latest ffmpeg.
Am I missing a step here or should it have worked fine on its own?
Does it need to be ported to Windows the same way this WebP generator (which is based on an mpv gif generator port for Windows)
https://github.com/ekisu/mpv-webm/issues/124
Here's the mpv gif generator for Windows if you need to take a look. It's not as robust and user as this script, though, but if it creates quality gifs instead of grainy ones using ffmpeg, it would be worth integrating into this script for Windows users.
along with the latest ffmpeg
This script doesn't actually call an external ffmpeg binary but calls mpv itself (which internally uses ffmpeg).
Am I missing a step here or should it have worked fine on its own?
It should have. Can you share an example short source clip and the gif output along with the settings you use to compare results? I don't have a Windows machine at hand to test, unfortunately. I don't expect Windows to behave differently as long as the same options are available 🤔 (unless mpv was built against ffmpeg with disabled features or something)
OK, I asked a friend to test on Windows and it does look bad there. I'll try to see if I can figure out what goes wrong. It is weird to me though, as @horusra was testing this on Windows according to the original post, and was happy with the results after the changes. I wonder what broke it.
EDIT: It is not Windows see next comment
but if it creates quality gifs instead of grainy ones using ffmpeg, it would be worth integrating into this script for Windows users.
BTW we can import the same options from that project here if they result in better quality gifs.
Alright, mystery solved.
The recent filter changes in https://github.com/ekisu/mpv-webm/commit/7041c07f973fee287fda22d7fdb01d33113ed456 seems to have broken it. It is not Windows, I had an outdated version of the script apparently!
@Pentaphon Can you try commenting the line with get_contrast_brightness_and_saturation_filters
by adding -- like below in the webm.lua script (around line 1690 on latest version) and try again to see if it fixes the problem for you?
append(filters, get_scale_filters())
append(filters, get_fps_filters())
--append(filters, get_contrast_brightness_and_saturation_filters())
append(filters, format:getPostFilters())
The gif code is a bit brittle unfortunately so I expect it to break. I'll try to send a fix when I find the time.
mpv version and platform
Windows 10 20H2
Description
It seems there is no option for GIF quality It always comes out looking like this: