phw / peek

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

some gifs are empty #1

Closed cedlemo closed 7 years ago

cedlemo commented 8 years ago

My system is ArchLinux x86_64 and I have installed peek via the its AUR package.

I have made 5/6 attempt to create a gif and sometimes the file created is empty.

FYI info I use the basic configuration (no change on the framerate).

phw commented 8 years ago

I have not yet experienced this. Can you start Peek from a terminal and post the output of such a case?

cedlemo commented 8 years ago

I have tried recording with different times:

The ouput:

ffmpeg version 3.0 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.3.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libdcadec --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-shared --enable-version3 --enable-x11grab
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Input #0, x11grab, from ':0+168,132':
  Duration: N/A, start: 1457357508.631989, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 722x503, 15 fps, 15 tbr, 1000k tbn, 15 tbc
[huffyuv @ 0x55f4e3cec4a0] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55f4e3cec960] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55f4e3cf4f60] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55f4e3cf7ac0] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55f4e3cc98e0] using huffyuv 2.2.0 or newer interlacing flag
Output #0, avi, to '/tmp/peekXZOUDY.avi':
  Metadata:
    ISFT            : Lavf57.25.100
    Stream #0:0: Video: huffyuv (HFYU / 0x55594648), rgb24, 722x502, q=2-31, 200 kb/s, 15 fps, 15 tbn, 15 tbc
    Metadata:
      encoder         : Lavc57.24.102 huffyuv
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> huffyuv (native))
Press [q] to stop, [?] for help
Recording stopped15 q=-0.0 size=  346943kB time=00:01:07.26 bitrate=42252.1kbits/s speed=   1x    
frame= 1015 fps= 15 q=-0.0 Lsize=  349020kB time=00:01:07.66 bitrate=42253.8kbits/s speed=   1x    
video:348991kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.008437%

Seeing the ouput I am a little surprised that you use an external tool for recording. (I know nothing about this matter so I don't judge, I am just surprised). So I guess the process is:

The part of conversion and save seem to be very heavy in term of resources usage.

Just a question:

Why don't you use pixbufs of your window in order to get image of the underlying windows at a "f" frenquencie and use them to build the gif.

phw commented 8 years ago

Sorry for the long delay in answering. I am not able to reproduce this. Even longer videos work fine, and I have recorded a couple of demo sessions for my applications. But it might be related to #2.

Seeing the ouput I am a little surprised that you use an external tool for recording. (I know nothing about this matter so I don't judge, I am just surprised).

ffmpeg in general does a very nice job, I just did not want to reinvent the wheel. But the code is structured in a way that I can plugin another recording backend and I think I will try you pixbuf suggestion. Also to see whether this helps with #2 . The AVI generated by ffmpeg is really larger than I think it should be.

cedlemo commented 8 years ago

But the code is structured in a way that I can plugin another recording backend and I think I will try you pixbuf suggestion.

I have done a little program with ruby in order to see if how it could work (it was after I asked it) The idea was to get the pixbuf with a timeout and then build a gif with rmagick.

The script is around 150 lines I planed to propose it as a sample example for the Ruby-GNOME2 project. If you want I could send you a link (ruby is not that hard to understand and the script is simple)

The issue is to find the good timing to register the pixbuf then use the good timing with rmagick so that the gif is smooth

phw commented 8 years ago

The script is around 150 lines I planed to propose it as a sample example for the Ruby-GNOME2 project. If you want I could send you a link (ruby is not that hard to understand and the script is simple)

That would be great. I am actually quite familiar with Ruby, even though my Ruby programming is a bit rusty :D I figured the timing would be the greatest issue.

cedlemo commented 8 years ago

I haven't proposed yet but here is the code (quite ugly):

#!/usr/bin/env ruby
require "gtk3"
require "cairo"
require "rmagick"

class AlphaWindow < Gtk::Window
  def initialize
    super()

    header = Gtk::HeaderBar.new
    header.set_title("Giffffff")
    header.show_close_button = true
    set_titlebar(header)
    record_button = Gtk::Button.new(:label => "Record")

    stop_button = Gtk::Button.new(:label => "Stop")
    stop_button.sensitive = false

    record_button.signal_connect "clicked" do |widget|
      set_keep_above(true)
      record
      stop_button.sensitive = true
      widget.sensitive = false
    end

    stop_button.signal_connect "clicked" do |widget|
      set_keep_above(false)
      stop_record
      make_gif
      record_button.sensitive = true
      widget.sensitive = false
    end

    header.pack_start(record_button)
    header.pack_end(stop_button)

    set_app_paintable(true)
    set_default_size(1200, 600)

    signal_connect("delete_event") do
      Gtk.main_quit
    end

    signal_connect("screen-changed") do |widget, _old_screen|
      screen_changed(widget)
    end

    @recording_view = Gtk::Box.new(:vertical,0)
    @recording_view.visible = true
    @recording_view.can_focus = false
    @recording_view.set_width_request(100)
    @recording_view.set_height_request(100)
    @recording_view.pack_start(Gtk::Label.new("Pof"))
    add(@recording_view)

    @recording_view.signal_connect "draw" do |widget, event|
      cr = widget.window.create_cairo_context
      cr.set_operator(Cairo::OPERATOR_CLEAR) 
      if @supports_alpha
        cr.set_source_rgba(0.0, 0.0, 0.0, 0.5)
      else
        cr.set_source_rgb(0.0, 0.0, 0.0)
      end
      cr.fill

      win_region = create_region_from(widget.toplevel)
      rec_region = create_region_from(widget)
      win_region.subtract!(rec_region)
      self.input_shape_combine_region(win_region)

      false
    end

    screen_changed(self)
    @nb = 0
    @files = []

  end

  def create_region_from(widget)
    x, y, w, h = widget.allocation.to_a
    x, y = widget.translate_coordinates(widget.toplevel, 0, 0)
    region = Cairo::Region.new([x , y , w, h])
  end

  def screen_changed(widget)
    visual = widget.screen.rgba_visual
    if visual && widget.screen.composited?
      set_visual(visual)
      @supports_alpha = true
    else
      set_visual(widget.screen.system_visual)
      @supports_alpha = false
    end
  end

  def stop_record
    GLib::Source.remove(@timer) if @timer
  end

  def record
    @timer = GLib::Timeout.add(200) do
      queue_draw
      x, y, w, h = @recording_view.allocation.to_a
      _x, _y = @recording_view.translate_coordinates(self, 0, 0)
      x, y = window.position 
      @nb += 1
      filename = "/tmp/pof#{@nb}.png"
      @files << filename
      pix = Gdk.default_root_window.to_pixbuf(x + _x , y +_y , w, h)
      pix.save(filename, "png")
      true
    end
  end

  def make_gif
    gif = Magick::ImageList.new(*@files)
    gif.delay = 1
    gif.ticks_per_second = 5 
    gif.write("pof_animated.gif")
  end
end

alpha = AlphaWindow.new
alpha.show_all
Gtk.main
SalahAdDin commented 8 years ago

I have the same problem.

In the first, all is well, two beautiful and lovely gift, them, i make the same gif one by one time, at least five times.

I take two screen shots :+1: captura de pantalla de 2016-09-12 20-28-56 captura de pantalla de 2016-09-12 20-31-05

One empty gif ever.

Other problem that i have is the performance, normally i haven't leaks in memory, but in the final, after take the empty gif, doesn't matter if reboot the laptop, i have memory leaks because peek.

This is my SO:

               `.-/::/-``
            .-/osssssssso/.               salahaddin@TulipanROG
           :osyysssssssyyys+-             OS: Antergos 
        `.+yyyysssssssssyyyyy+.           Kernel: x86_64 Linux 4.7.2-1-ARCH
       `/syyyyyssssssssssyyyyys-`         Uptime: 53m
      `/yhyyyyysss++ssosyyyyhhy/`         Packages: 1316
     .ohhhyyyyso++/+oso+syy+shhhho.       Shell: zsh 5.2
    .shhhhysoo++//+sss+++yyy+shhhhs.      Resolution: 1920x1080
   -yhhhhs+++++++ossso+++yyys+ohhddy:     DE: Gnome 
  -yddhhyo+++++osyyss++++yyyyooyhdddy-    WM: GNOME Shell
 .yddddhso++osyyyyys+++++yyhhsoshddddy`   WM Theme: Numix-Frost-Light
`odddddhyosyhyyyyyy++++++yhhhyosddddddo   GTK Theme: Arc [GTK2/3]
.dmdddddhhhhhhhyyyo+++++shhhhhohddddmmh.  Icon Theme: Xenlism-Wildfire-ThursDay
ddmmdddddhhhhhhhso++++++yhhhhhhdddddmmdy  Font: Cantarell 11
dmmmdddddddhhhyso++++++shhhhhddddddmmmmh  CPU: Intel Core i7-4720HQ CPU @ 3.6GHz
-dmmmdddddddhhyso++++oshhhhdddddddmmmmd-  RAM: 2812MiB / 15941MiB
 .smmmmddddddddhhhhhhhhhdddddddddmmmms. 
   `+ydmmmdddddddddddddddddddmmmmdy/.     
      `.:+ooyyddddddddddddyyso+:.`
SalahAdDin commented 8 years ago

Here are the trace back:

peek                                                                                                                                     1 ↵  2846  21:45:46 
ffmpeg version 3.1.3 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 6.1.1 (GCC) 20160802
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-netcdf --enable-shared --enable-version3 --enable-x11grab
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 48.101 / 57. 48.101
  libavformat    57. 41.100 / 57. 41.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 47.100 /  6. 47.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
[x11grab @ 0x55c406843b00] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, x11grab, from ':0+182,304':
  Duration: N/A, start: 1473734755.661748, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1294x585, 15 fps, 1000k tbr, 1000k tbn, 1000k tbc
[huffyuv @ 0x55c40686e760] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55c40687d740] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55c406882060] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55c406886e00] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55c40688bac0] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55c406890780] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55c406895440] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55c40689a100] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x55c40684cdc0] using huffyuv 2.2.0 or newer interlacing flag
[avi @ 0x55c40684b7c0] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Output #0, avi, to '/tmp/peekVZ40NY.avi':
  Metadata:
    ISFT            : Lavf57.41.100
    Stream #0:0: Video: huffyuv (HFYU / 0x55594648), rgb24, 1294x584, q=2-31, 200 kb/s, 15 fps, 15 tbn, 15 tbc
    Metadata:
      encoder         : Lavc57.48.101 huffyuv
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> huffyuv (native))
Press [q] to stop, [?] for help
Recording stopped15 q=-0.0 size=  538407kB time=00:01:02.46 bitrate=70607.8kbits/s speed=   1x    
frame=  944 fps= 15 q=-0.0 Lsize=  542517kB time=00:01:02.93 bitrate=70619.1kbits/s speed=   1x    
video:542489kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.005121%
military1 commented 8 years ago

The same problem on Antargos. be the solution?

phw commented 8 years ago

My suspicion to all of these issues are memory restrictions. On Arch Linux by default /tmp will be mounted as a memory filesystem using your RAM. So temporary files will consume RAM, and Peek generates temporary files to hold the recording. If you are low on memory one solution would be to mount /tmp not in RAM but use your HDD or SSD for it.

Other problem that i have is the performance, normally i haven't leaks in memory, but in the final, after take the empty gif, doesn't matter if reboot the laptop, i have memory leaks because peek.

Memory leaks do not survive reboots :) But during run time the temporary files could be the issue. Peek should actually clean up all temporary files once it doesn't need them anymore, but maybe in case of the above error some files are left behind.

lode commented 8 years ago

I know from SilentCast (https://github.com/colinkeenan/silentcast) that it saves the temporary files on disk, somewhere in /home. A bit ugly, but maybe better suited for larger animations.

strixaluco commented 8 years ago

I'm having empty gifs with a similar output as above, except for notable ImageMagick's-related errors:

convert: delegate failed `"avconv" -v -1 -i "%i" -vframes %S -vcodec pam -an -f rawvideo -y "%u.pam" 2> "%Z"' @ error/delegate.c/InvokeDelegate/1310.
convert: unable to open image `/tmp/magick-12086Su1hLuf0PyXb.pam': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no images defined `/tmp/peekL6O3OY.gif' @ error/convert.c/ConvertImageCommand/3210.

Environment: Debian 8 Stable + backports Peek 0.7.2

Full log:

peek
ffmpeg version 3.1.3-1~bpo8+1 Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 4.9.2 (Debian 4.9.2-10)
  configuration: --prefix=/usr --extra-version='1~bpo8+1' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --disable-libebur128 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librubberband --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-chromaprint --enable-libopencv --enable-libx264
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 48.101 / 57. 48.101
  libavformat    57. 41.100 / 57. 41.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 47.100 /  6. 47.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
Input #0, x11grab, from ':0+36,225':
  Duration: N/A, start: 1475819738.493736, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 856x435, 15 fps, 15 tbr, 1000k tbn, 1000k tbc
[huffyuv @ 0x1d52480] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x1d55600] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x1d58d00] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x1d5c480] using huffyuv 2.2.0 or newer interlacing flag
[huffyuv @ 0x1d2b4c0] using huffyuv 2.2.0 or newer interlacing flag
[avi @ 0x1d2a320] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Output #0, avi, to '/tmp/peekFNMROY.avi':
  Metadata:
    ISFT            : Lavf57.41.100
    Stream #0:0: Video: huffyuv (HFYU / 0x55594648), rgb24, 856x434, q=2-31, 200 kb/s, 15 fps, 15 tbn, 15 tbc
    Metadata:
      encoder         : Lavc57.48.101 huffyuv
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> huffyuv (native))
Press [q] to stop, [?] for help
frame=   13 fps=0.0 q=-0.0 size=    4369kB time=00:00:00.66 bitrate=53689.0kbitsframe=   21 fps= 20 q=-0.0 size=    7821kB time=00:00:01.20 bitrate=53390.9kbitsframe=   29 fps= 18 q=-0.0 size=   11291kB time=00:00:01.73 bitrate=53364.1kbitsframe=   37 fps= 17 q=-0.0 size=   14771kB time=00:00:02.26 bitrate=53383.2kbitsframe=   45 fps= 17 q=-0.0 size=   18258kB time=00:00:02.80 bitrate=53417.9kbitsframe=   53 fps= 17 q=-0.0 size=   21755kB time=00:00:03.33 bitrate=53465.1kbitsframe=   61 fps= 16 q=-0.0 size=   25259kB time=00:00:03.86 bitrate=53513.6kbitsframe=   69 fps= 16 q=-0.0 size=   28797kB time=00:00:04.40 bitrate=53614.8kbitsframe=   77 fps= 16 q=-0.0 size=   32386kB time=00:00:04.93 bitrate=53778.2kbitsframe=   85 fps= 16 q=-0.0 size=   36050kB time=00:00:05.46 bitrate=54022.1kbitsframe=   93 fps= 16 q=-0.0 size=   39776kB time=00:00:06.00 bitrate=54307.5kbitsRecording stopped 

frame=   96 fps= 16 q=-0.0 Lsize=   42609kB time=00:00:06.40 bitrate=54539.0kbits/s speed=1.04x    
video:42601kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.018559%
convert: delegate failed `"avconv" -v -1 -i "%i" -vframes %S -vcodec pam -an -f rawvideo -y "%u.pam" 2> "%Z"' @ error/delegate.c/InvokeDelegate/1310.
convert: unable to open image `/tmp/magick-12086Su1hLuf0PyXb.pam': No such file or directory @ error/blob.c/OpenBlob/2712.
convert: no images defined `/tmp/peekL6O3OY.gif' @ error/convert.c/ConvertImageCommand/3210.
Kabouik commented 7 years ago

I get the 0 bytes gifs too, especially when I try to record a large area or more than 15 sec. It also comes with horrible performance (extreme lag, freezes), while everything works correctly and smoothly when Peek succeeds in generating a working gif. I have an i5 CPU with 8 GB RAM and 3 GB of Swap on a ssd, running Solus 1.2.1.

phw commented 7 years ago

Closing this since I bieve this has improved in the current git master. I will make a new release soon. Please feel free to open new issues if you experience this with the latest code.

phw commented 7 years ago

While refactoring the recorders to support multiple formats I found a race condition where Peek did not wait for ffmpeg to finish its job before passing this on to ImageMagick. This is very likely to be the root cause of this issue. Fix will be in the next release.

strixaluco commented 7 years ago

In fact, I'm not having empty gif issues with Peek 0.8.0 anymore. Unfortunately, can't tell for sure what was the reason, but v. 0.8.0 definitely has been problematic for some period of time. Maybe recent update of ffmpeg or ImageMagick eliminated the bug.

SalahAdDin commented 7 years ago

@phw. when going you to release new version? I'm waiting for it.

phw commented 7 years ago

@SalahAdDin Not quite sure, but soon. Actually I want to get the things on https://github.com/phw/peek/milestone/1 finished and then I will release this as Peek 1.0, since it will include all the features I initially aimed for. Expect a release in the next 1 or 2 weeks, depending on how I find the time.

SalahAdDin commented 7 years ago

@phw Did you finish it man?

phw commented 7 years ago

@SalahAdDin Release has been out for a few weeks: https://github.com/phw/peek/releases

SalahAdDin commented 7 years ago

Thanks!