phw / peek

Simple animated GIF screen recorder with an easy to use interface
GNU General Public License v3.0
10.3k stars 320 forks source link

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

Closed ronjouch closed 7 years ago

ronjouch commented 7 years ago

@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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

@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.

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 commented 7 years ago

This sounds an awful lot like the issues reported at https://github.com/phw/peek/issues/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 commented 7 years ago

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 commented 7 years ago

@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 commented 7 years ago

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

ronjouch commented 7 years ago

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

phw commented 7 years ago

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 commented 7 years ago

@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 commented 7 years ago

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 commented 7 years ago

Works for me. @phw awesome work 👍.

ronjouch commented 7 years ago

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):

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 commented 7 years ago

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:

New plan: I add a checkbox to enable gifski.

ronjouch commented 7 years ago

@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 commented 7 years ago

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 https://github.com/phw/peek/commit/daba57c7b70694a36263fa4780b8af49afe9c16f

andersaamodt commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

Ah. Is there a workaround?

phw commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

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

phw commented 7 years ago

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

andersaamodt commented 6 years ago

No, they don't show up