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

Consider / propose as option / default to new high-quality GIF encoder gifski #212

Closed
ronjouch opened this issue Nov 2, 2017 · 25 comments
Closed
Milestone

Comments

@ronjouch
Copy link

ronjouch commented Nov 2, 2017

@pornel of ImageOptim/PNGQuant fame just released a first version of gifski (website, github). Quoting the website,

Highest-quality GIF encoder based on pngquant.

gifski converts video frames to GIF animations using pngquant's fancy features for efficient cross-frame palettes and temporal dithering. It produces animated GIFs that use thousands of colors per frame.
demo
It's a CLI tool, but it can also be compiled as library for seamelss use in other apps (note that for closed-source apps you need a commercial pngquant license).

Would be awesome for Peek to be able to directly use it. Probably as an option (?) as I guess it means good-looking but heavy GIFs, which depending on the use case may not be the user-desired tradeoff.

@phw
Copy link
Owner

phw commented Nov 2, 2017

This looks like an awesome tool. I will give this a test run as soon as possible and implement this in peek. Another option for replacing ImageMagick finally :)

@phw phw added the enhancement label Nov 2, 2017
@phw phw added this to the 1.2.0 milestone Nov 2, 2017
@phw
Copy link
Owner

phw commented Nov 3, 2017

Here we go with a first quick implementation. For now hidden behind an environment variable. To test install the gifski executable somewhere in your $PATH and run latest peek from git with:

PEEK_POSTPROCESSOR=gifski peek

Looking good so far. I haven't done many tests, but the quality seems to be great. But the images are significantly larger, in my tests the size was roughly doubled.

I like gifski and want to keep it as an option, but use ffmpeg by default. Not yet sure how to best expose this option to the user.

@phw
Copy link
Owner

phw commented Nov 3, 2017

Some more observations: Rendering the GIF takes way more time than with ffmpeg, but memory usage stays low all the time :) Quality is much better. I will try to upload an example later.

@ronjouch
Copy link
Author

ronjouch commented Nov 3, 2017

@phw installed gifski from cargo (running gifski --help works), built peek from source and ran it with PEEK_POSTPROCESSOR=gifski.

But before we talk gifski I need help with the build, my self-built peek is borked: with or without the PEEK_POSTPROCESSOR variable, the output GIF is always a single frame (around 20kB or 100kB, depending on what I captured).

This is the first time I build peek, so I may have done something wrong. HALP.

  • Ubuntu 16.04.3 / Unity / Compiz
  • Followed build peek from source steps, except the final make install, which felt undesired (since I have a ppa install) & unnecessary (since docs mention I can "Run directly from source" after build).
  • Build went fine after installing the 👍 documented deps.
  • Settings: Format=GIF, Delay=2, Framerate=5, Downsampling=1, Cursor=true.
  • From the log below I see Peek is using my PATH ffmpeg 3.4, which is an official static build. Bad?

Log:

 /opt/peek/build  ± master  ./peek

** (peek:28992): WARNING **: Binding '<Ctrl><Alt>R' failed!
Using screen recorder backend ffmpeg
ffmpeg version 3.4-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.4.0 (Debian 6.4.0-7) 20170920
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
[x11grab @ 0x5c94f40] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, x11grab, from ':0+1288,120':
  Duration: N/A, start: 1509718090.487766, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1233x547, 5 fps, 1000k tbr, 1000k tbn, 1000k tbc
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> pam (native))
Press [q] to stop, [?] for help
Output #0, rawvideo, to '/home/ronj/.cache/peek/peek3LVY8Y.pam':
  Metadata:
    encoder         : Lavf57.83.100
    Stream #0:0: Video: pam, rgb24, 1233x547, q=2-31, 200 kb/s, 5 fps, 5 tbn, 5 tbc
    Metadata:
      encoder         : Lavc57.107.100 pam
frame=   20 fps=5.5 q=-0.0 Lsize=   39520kB time=00:00:04.00 bitrate=80936.7kbits/s speed=1.11x
video:39520kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
ffmpeg version 3.4-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.4.0 (Debian 6.4.0-7) 20170920
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Input #0, image2, from '/home/ronj/.cache/peek/peek3LVY8Y.pam':
  Duration: 00:00:00.04, start: 0.000000, bitrate: 8093668 kb/s
    Stream #0:0: Video: pam, rgb24, 1233x547, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (pam (native) -> png (native))
Press [q] to stop, [?] for help
Output #0, image2, to '/home/ronj/.cache/peek/peekY13Z8Y.png':
  Metadata:
    encoder         : Lavf57.83.100
    Stream #0:0: Video: png, rgba, 16x16 [SAR 1:1 DAR 1:1], q=2-31, 200 kb/s, 5 fps, 5 tbn, 5 tbc
    Metadata:
      encoder         : Lavc57.107.100 png
frame=    0 fps=0.0 q=0.0 Lsize=N/A time=00:00:00.00 bitrate=N/A speed=   0x
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
ffmpeg version 3.4-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.4.0 (Debian 6.4.0-7) 20170920
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Input #0, image2, from '/home/ronj/.cache/peek/peek3LVY8Y.pam':
  Duration: 00:00:00.04, start: 0.000000, bitrate: 8093668 kb/s
    Stream #0:0: Video: pam, rgb24, 1233x547, 25 tbr, 25 tbn, 25 tbc
/home/ronj/.cache/peek/peekY13Z8Y.png: Invalid data found when processing input
Error: Child process exited with code 1
File save error: Error when getting information for file '/home/ronj/.cache/peek/peekSI0T8Y.gif': No such file or directory
Temp file delete error: Error removing file: No such file or directory

@phw
Copy link
Owner

phw commented Nov 3, 2017

This sounds an awful lot like the issues reported at #198

I have no idea really, especially since I did not change anything in the recording itself. If you run

PEEK_POSTPROCESSOR=imagemagick ./peek

you should get exactly the same behavior as with Peek 1.1.0, does this make a difference?

@phw
Copy link
Owner

phw commented Nov 3, 2017

It's interesting, the initial ffmpeg command for recording the video (pam file) shows time=00:00:04.00 at the end. The later ffmpeg commands loading the file show Duration: 00:00:00.04. Something is wrong here. I have to refactor the recording part anyway (writing the data to that pam file only made sense in combination with imagemagick).

@ronjouch
Copy link
Author

ronjouch commented Nov 3, 2017

@phw

This sounds an awful lot like the issues reported at #198

Indeed, thanks for the pointer 👍.

I have no idea really, especially since I did not change anything in the recording itself. If you run

PEEK_POSTPROCESSOR=imagemagick ./peek

you should get exactly the same behavior as with Peek 1.1.0, does this make a difference?

It does: with this flag recording works as before.

It's interesting, the initial ffmpeg command for recording the video (pam file) shows time=00:00:04.00 at the end. The later ffmpeg commands loading the file show Duration: 00:00:00.04. Something is wrong here. I have to refactor the recording part anyway (writing the data to that pam file only made sense in combination with imagemagick).

👍, feel free to ping me when I can try the refactor. Or to avoid derailing the gifski discussion, ping #198, I subscribed to it. Thanks for the prompt feedback!

@phw
Copy link
Owner

phw commented Nov 3, 2017

Can you try again latest master? I could finally reproduce, changed the intermediary output format. This is probably an intermediate fix.

@ronjouch
Copy link
Author

ronjouch commented Nov 3, 2017

@phw #198 fixed with your latest changes, and gifski postprocessor working! As expected, output is beautiful and filesize is huge.

@phw
Copy link
Owner

phw commented Nov 5, 2017

gifski now supports a quality setting (0-100). This is interesting, because in a quick test a quality of around 50-60 gave me pretty similar results than ffmpeg, but with smaller file size. Ffmpeg still encodes faster, but it's kinda ok with gifski in lower quality settings.

There is a big case of making gifski the default and add a slider for quality. My current idea is to just do that with gifski, settting the default quality to 60. The user can then configure the quality with a slider. And if gifski is not available fall back to ffmpeg without quality setting.

Some comparisson, first with ffmpeg:

ffmpeg

gifski quality 100:

quality100

gifski quality 60:

quality60

@ronjouch
Copy link
Author

ronjouch commented Nov 5, 2017

@phw

gifski now supports a quality setting (0-100). This is interesting, because in a quick test a quality of around 50-60 gave me pretty similar results than ffmpeg, but with smaller file size. Ffmpeg still encodes faster, but it's kinda ok with gifski in lower quality settings.

There is a big case of making gifski the default and add a slider for quality. My current idea is to just do that with gifski, settting the default quality to 60. The user can then configure the quality with a slider. And if gifski is not available fall back to ffmpeg without quality setting.

Pure awesome 👍; we can have our PNGQuant awesomeness cake and eat it in GIF-land 🙂. I guess/hope that will still let users customize capture framerate (but there's no reason not to, right?), it remains an important way to keep GIF filesize reasonable. Ping me here if/when a first implementation is available, I'll be glad to test it.

@phw
Copy link
Owner

phw commented Nov 6, 2017

I have made gifski the default. If gifski is available it will be used, if not Peek will fallback to ffmpeg.

By default Peek will use a quality setting of 60. But you can change it in the preferences, see below. This setting is only available if gifski is installed.

bildschirmfoto vom 2017-11-06 18-11-11

@ronjouch
Copy link
Author

ronjouch commented Nov 6, 2017

Works for me. @phw awesome work 👍.

@ronjouch
Copy link
Author

ronjouch commented Nov 7, 2017

I have made gifski the default. If gifski is available it will be used, if not Peek will fallback to ffmpeg.

By default Peek will use a quality setting of 60. But you can change it in the preferences, see below. This setting is only available if gifski is installed.

@phw I've been playing with it (latest master gifski+peek), but for now I feel it's a bad idea to replace ffmpeg, because although gifski now advertises a quality setting, gifski remains in a whole diffrent ballpark regarding filesize, even when setting minimum gifski quality. See for yourself on similar screencasts (manual timing and clicking, so that's not a 100% exact comparison, but still gives an idea):

  • Baseline ffmpeg: 300kB
    peek-ffmpeg

  • Gifski q=20: 1.2MB
    peek-giphy_20

  • Gifski q=100: 1MB (yes, smaller than q=20, I guess it's actually just a bit shorter)
    peek-giphy_100

It feels like high quality makes for a bit less dithering, but overall filesize remains huge (300kB → ~1MB).

Am I doing something wrong? (Do you get the same behavior when fiddling with gifski quality?) If you confirm the huge filesizes regardless of gifski quality, please keep ffmpeg as an option.

@phw
Copy link
Owner

phw commented Nov 7, 2017

Thanks a lot for this testing. Yes, these results speak against gifski as default, especially as gifski cannot play out its huge advantage on the typical screen recording content (application interfaces without too many colors).

My results have been indeed different, gifski with q=60 was around the file size of ffmpeg, even a bit smaller sometimes. But the final file size depends so heavily on the recorded content and colors shown. For tests I encoded the WebM video in test.zip with ffmpeg, imagemagick and gifski in different quality. My results where:

  • imagemagick: 4.1 MB
  • ffmpeg: 3.9 MB
  • gifski q 100: 5.9 MB
  • gifski q 80: 4.5 MB
  • gifski q 60: 3.8 MB
  • gifski q 40: 3.3 MB
  • gifski q 20: 2.8 MB

New plan: I add a checkbox to enable gifski.

@phw phw reopened this Nov 7, 2017
@ronjouch
Copy link
Author

ronjouch commented Nov 7, 2017

@phw thinking about the non-effect of the new gifski slider, could it simply be that my build is screwed? Especially, I didn't make install, so the xml conf schemas were not deployed. I noticed that running from the build folder with ./peek succeeds in making peek run (whereas if I just run /opt/peek-git/build/peek from ~ it crashes with a gschemas error), so it looks like new schemas (including the gifsky quality integer) are used, but could something more be wrong, causing a constant/default be passed to gifski regardless of the slider position?

@phw
Copy link
Owner

phw commented Nov 8, 2017

Which version of gifski do you use? gifski 0.5 compiled from AUR, or gifski-git, or the official binary from gifski release page?

UPDATE: Additional discussion at daba57c

@andersaamodt
Copy link

I have installed gifski 0.6.0 on Ubuntu 14.04 but when I open Peek the preferencs box does not show the quality slider. Is it not detecting gifski correctly?

@phw
Copy link
Owner

phw commented Nov 14, 2017

How did you install Peek? As it is not possible to install Peek in 14.04 from source I assume you are using the snap version, right?

If so, the snap.package is not yet update to include gifski. Due to the Sandboxer nature of snap apps it cannot use your system wide installation.

@andersaamodt
Copy link

Ah. Is there a workaround?

@phw
Copy link
Owner

phw commented Nov 16, 2017

@andersaamodt No, not currently. The flatpak builds already include gifski, but I don't know whether you can run this on 14.04. I will update the snaps to include gifski before the next release.

@phw phw closed this as completed in 3c5fa06 Nov 16, 2017
phw added a commit that referenced this issue Nov 16, 2017
@phw
Copy link
Owner

phw commented Nov 16, 2017

@andersaamodt I have updated the snaps to include gifski, could you try the latest snap from the edge channel if it works for you?

sudo snap install --edge peek 

@andersaamodt
Copy link

Hmm, I installed the update but there is still no progress bar.

@phw
Copy link
Owner

phw commented Nov 17, 2017

What do you mean with progress bar? Do you see the gifski settings in Peek's preferences

@andersaamodt
Copy link

No, they don't show up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants