GIF ekranlama; UNIX yolu


57

Bir çekmek için statik ekran görüntüsü benim ekranın seçilen kısmının, sık sık kullanmak scrotile -s shot.png. Bu, StackExchange yayınlarına resimler eklemek için mükemmeldir. Böyle bir ekran görüntüsünü otomatik olarak Imgur.com'a yüklemek ve X panosuna bir bağlantı koymak için bile bu komut dosyasını buldum !

Bunu oniki haline getirelim : Benzer şekilde bir GIF screencast'ı nasıl oluşturabilirim?

Orada olan gibi programlar recordmydesktop, byzanz& co Ask Ubuntu üzerinde tartışıldığı gibi "kullanıcı dostu" olmayı hedefliyoruz, ama benim deneyim bu gibi küçük bir defaya mahsus şeyler için çoğunlukla unscriptable ve elverişsiz, arabası, verimsizdir.

Sadece bir alan seçmek ve bir GIF kaydetmek istiyorum, anlayabildiğim bir konsol komutuyla, bazı gizli şifreli GUI canavarlığını değil.

Bunu nasıl yapabilirim?



2
Terminal ile ilgili herhangi bir şey için, bu daha iyi seçenek olabilir: asciinema.org
Flatron

Yanıtlar:


68

tamam ozaman

GIF vimcast!

Ben başladım ffcast, yaptım vim, bıraktım ffcast, sonra converted .avi.gif.

Kayıt komutlarını başka bir terminalde çalıştırdım. $PATHBu cevabın sonunda sizin için cilalanmış senaryo .

Ne oldu?

yakalama

FFcast, kullanıcının etkileşimli bir ekran bölgesi seçmesine ve ekran kaydı için geometriyi FFmpeg gibi harici bir komuta teslim etmesine yardımcı olur.

ffcastArch Linux topluluğundaki (çoğunlukla lolilolicon ) bazı hacklerin şanlı ürünüdür . Bunu github'da bulabilirsiniz (veya Arch aers for AUR ). Onun bağımlılık listesi adildir ve sen isteyeceksiniz rağmen ( AUR bağlantısını interaktif dikdörtgen seçimi için).bashffmpegxrectsel

Ayrıca ffmpegkomuttan hemen sonra bayrak ekleyebilirsiniz . -r 15Saniyede 15 kare -codec:v huffyuvçekmeye ve kayıpsız kayıt yapmaya başladım . (Boyut / kalite değişimini düzeltmek için bunlarla oynayın.)

GIFfing

ImageMagick okuyabilir .avivideo ve kaliteyi korurken büyük ölçüde dosya boyutunu azaltmak bazı GIF optimizasyon hileler vardır: -layers Optimizeiçin convertgenel amaçlı optimize edici çağırır. ImageMagick el kitabında gelişmiş optimizasyonlar için bir sayfa da var.

Son senaryo

İçimdeki şey bu $PATH. Dönüştürmeden önce geçici bir dosyaya kaydeder.

#!/bin/bash
TMP_AVI=$(mktemp /tmp/outXXXXXXXXXX.avi)
ffcast -s % ffmpeg -y -f x11grab -show_region 1 -framerate 15 \
    -video_size %s -i %D+%c -codec:v huffyuv                  \
    -vf crop="iw-mod(iw\\,2):ih-mod(ih\\,2)" $TMP_AVI         \
&& convert -set delay 10 -layers Optimize $TMP_AVI out.gif

Dedektif çalışmaları için BenC'ye teşekkürler, en son ffcastgüncellemeden sonra doğru bayrakları bulmak .

Bağımlılıkları Debian merkezli bir dağıtıma kurmak istiyorsanız, Louis yararlı kurulum notları yazdı .

Wheeeeee!


1
Bash gerektirmeyen, ancak herhangi bir POSIX uyumlu kabuk üzerinde çalışan bir sürüm oluşturdum github.com/chilicuil/ffcast
Javier López

2
Komut satırı sözdizimi ffcastdeğişmiş gibi görünüyor : github.com/lolilolicon/FFcast/issues/8
Jack O'Connor

1
Bunu yapmanın en basit yolu şimdi ffcast -s rec [filename], ancak bu örnekte kullandığınız ayarları tam olarak vermese de. Maalesef, tam ayarları yapmak için şimdi tüm ffmpegkomutu vermeniz gerekiyor . Bu cevabı güncellemenin en iyi yolu hakkında aramanız :)
Jack O'Connor

4
GH hakkındaki yorumlara dayanarak ffcast -s % ffmpeg -f x11grab -show_region 1 -framerate 20 -video_size %s -i %D+%c -codec:v huffyuv -vf crop="iw-mod(iw\\,2):ih-mod(ih\\,2)" $TMP_AVI, hile yapmak gibi görünüyor.
BenC

1
Zaten kendi sistemlerinde bu olmadan başkalarına bu şeylerin bazılarının kurulumuyla ilgili bazı notlar
Louis Maddox

11

Benim için, cevap kullanmaktı ffcastile ffmpegşöyle:

ffcast -w % ffmpeg -f x11grab -show_region 1 -framerate 20 -video_size %s -i %D+%c -codec:v huffyuv -vf crop="iw-mod(iw\\,2):ih-mod(ih\\,2)" out.avi

Daha sonra ffmpegavi'den gif'e dönüşüm yaptım - çok hızlı ve kare hızını sağlam tutuyor:

ffmpeg -i out.avi -pix_fmt rgb24 out.gif

Son olarak ben aynı şekilde dönüştürmek kullanılan @anko 'ın cevabı gif optimize etmek, ama durdurmak için kaynak kullanımı için bir limit tespit convertbir ile çıkarken killedmesaj olarak ve ben gecikme kaldırıldı ffmpegzaten ele alarak:

convert -limit memory 1 -limit map 1 -layers Optimize out.gif out_optimised.gif


2

kurulumum için (ubuntu 16.04), ffcast uzun bir süredir github'da güncellenmediği için iyi çalışmıyor.

bu yüzden slop ( https://github.com/naelstrof/slop ) ve ffmpeg kullanarak bir script hazırladım .

Bir örnek:

yay çalışıyor

#!/bin/bash

read -r X Y W H G ID < <(slop -f "%x %y %w %h %g %i")
TMP_AVI=$(mktemp /tmp/outXXXXXXXXXX.avi)

ffmpeg -s "$W"x"$H" -y -f x11grab -i :0.0+$X,$Y -vcodec 
huffyuv -r 25 $TMP_AVI \
&& convert -set delay 5 -layers Optimize $TMP_AVI out.gif 

1

Bu nedenle, unix masaüstleri için etkileşimli bir sarmalayıcı komut dosyası yazmıştım ve bir yıllık kullanımdan sonra, onu orada paylaşmaktan mutluyum!

Made with byzanz, gifsicle, xdotoolve komut dosyası yazılır php.

Örnek çıktı:

[1020px, boyutlandırılmamış gif genişliği 1020px, 70 saniye, 50 renk, 65Kb ]

görüntü tanımını buraya girin

İyi sıkıştırılmış gif sağlar ve bu soru için iyi bir vitrindir.

Bu, sizin tarafınızdan saldırıya hazır, oldukça basit bir üs.

İşlevsellikler : Fare konumlarında veya tam ekran olarak GIF kaydı, yeniden boyutlandırma, sıkıştırma, renk sıkıştırma, ters / birleştirme, giphy.com curl upload.

10 saniyelik bir gif kaydı başlatmak için: gif 10

Aynı parametrelerle birden çok kez kaydetmek için: gif !

Tam ekran 5 saniyelik bir gif kaydı başlatmak için: gif 5 --fullscreen

Komut dosyası çalıştırma, hoş bir şekilde kendini kaydetme:

[ 45 saniye, genişlik 645px, tam renkler, 976kb ]
görüntü tanımını buraya girin

Tam 5kb komut dosyası:

#!/usr/bin/php

<?php
#> php xdotool byzanz gifsicle curl
#@ https://webdev23.github.io/gif/gif

echo "Usage: ./gif [time in seconds|!] [--fullscreen|-f]\n";
echo "--------------------------------------------------\n";
echo "Gif recorder tool\n";
echo "gif ! to call back last settings\n";
echo "Please move your mouse at the top left corner point\n";
echo "of the wanted gif area. Then press enter.\n";
echo "\n";

#~ Nico KraZhtest | 05/2017 | https://github.com/webdev23/gif
#~ Create fluid GIF's fastly
#~ You can set the gif record time as argument: ./gif 10
#~ Default record time is 1 seconde, or set it now:
   $recordTime = 1;
#~ ----------------

$t = @$argv[1];

$x1;$y1;$x2;$y2;$gw;$gh;$defc;$rw;

if (!isset($argv[1]) || @$argv[1] === "!") {
  $t = $recordTime;
}

if (@$argv[1] === "!") {
  $pos = file_get_contents("./.config/gif/pos");
  $pos = explode("\n", $pos);
  $x1 = $pos[0];
  $y1 = $pos[1];
  $x2 = $pos[2];
  $y2 = $pos[3];
  $gw = $pos[4];
  $gh = $pos[5];
  $t = $pos[6];
  @$GLOBALS['defc'] = $pos[7];
  @$GLOBALS['$rw'] = $pos[8];
   #~ echo $x1." ".$y1." ".$x2." ".$y2." ".$gw." ".$gh." ".$t." ".$defc." ".@$rw;
  }

else if (@$argv[2] === "fullscreen" || @$argv[2] === "--fullscreen" || @$argv[2] === "-f" || @$argv[2] === "f") {
  echo "############\nStarting fullscreen record\n";
  $fs = system("xdpyinfo  | grep 'dimensions:'");
  echo "\n";
  $fs = explode("    ",$fs);
  echo $fs[1];
  $fs = explode(" ",$fs[1]);
  echo $fs[0];
  $fs = explode("x",$fs[0]);
  echo $fs[0]."\n";
  echo $fs[1];
  $x1 = "0";
  $y1 = "0";
  $x2 = "fs";
  $y2 = "fs";
  $gw = $fs[0];
  $gh = $fs[1];
  $t = $argv[1];
  system("mkdir -p ./.config/gif/");
  system("cd ./.config/gif/ && \
          echo '$x1\n$y1\n$x2\n$y2\n$gw\n$gh\n$t\n\n\n\n' > pos");
  }

else {
  $stdin = fopen('php://stdin', 'r');
  $response = rtrim(fgets(STDIN));

  $p1 = system("xdotool getmouselocation");

  $pos1 = explode(" ",$p1);

  $x1 = $pos1[0];
  $x1 = explode(":",$x1);
  $x1 = $x1[1];
  echo "X1: ".$x1;

  $y1 = $pos1[1];
  $y1 = explode(":",$y1);
  $y1 = $y1[1];
  echo " Y1: ".$y1;

  echo "\nNow move your mousse at the bottom right corner.\nThen enter\n";

  $stdin = fopen('php://stdin', 'r');
  $response = rtrim(fgets(STDIN));

  $p2 = system("xdotool getmouselocation");

  $pos2 = explode(" ",$p2);

  $x2 = $pos2[0];
  $x2 = explode(":",$x2);
  $x2 = $x2[1];
  echo "X2: ".$x2;

  $y2 = $pos2[1];
  $y2 = explode(":",$y2);
  $y2 = $y2[1];
  echo " Y2: ".$y2;

  $gw = ($x2 - $x1);
  echo "\nGif width: ".$gw;

  $gh = ($y2 - $y1);
  echo "\nGif height: ".$gh;
  echo "\n".$x1." ".$y1." ".$x2." ".$y2." ".$gw." ".$gh." ".$t."\n";

  system("mkdir -p ./.config/gif/");
  system("cd ./.config/gif/ && \
          echo '$x1\n$y1\n$x2\n$y2\n$gw\n$gh\n$t\n\n\n\n' > pos");
  }

$unix = date_timestamp_get(date_create());

echo "\n".$unix." | Starting ".$t."s gif record\n";

@system("byzanz-record \
        -v             \
        --duration=$t  \
        --x=$x1        \
        --y=$y1        \
        --width=$gw    \
        --height=$gh   \
        ~/Pictures/gif$unix.gif");

$named = "gif".$unix;

echo "Saved as ~/Pictures/".$named.".gif\n";

echo "\nOptimize | How many colors to keep? (default 100, max 256) \n";

if (@$argv[1] === "!"){
  $pos = file_get_contents("./.config/gif/pos");
  $pos = explode("\n", $pos);
  $defc = $pos[7];
  }

if (!isset($defc)){
  $defc = readline("Colors: ");
  }

if (empty($defc)){
  $defc = "100";
  }

echo "\nKeeping ".$defc." colors\n";

system("gifsicle --verbose -i ~/Pictures/$named.gif -O5 --colors=$defc -o ~/Pictures/$named\_reduced.gif");

echo "\nOptimize | Resize width in pixels (default 360px) \n";

if (@$argv[1] === "!"){
  $pos = file_get_contents("./.config/gif/pos");
  $pos = explode("\n", $pos);
  $rw = $pos[8];
  }

if (!isset($rw)){
  $rw = readline("Width : ");
  }

if (empty($rw)){
  $rw = "360";
  }

echo "\nResized by ".$rw." pixels width\n";

@system("gifsicle --verbose -i ~/Pictures/$named\_reduced.gif --resize-width $rw -o ~/Pictures/".$named."_optimized.gif");

$opt = "~/Pictures/".$named."_optimized.gif";

usleep(5000000);

echo "\nSpecial | Reverse and merge?\n";

system("xdg-open ~/Pictures/".$named."_optimized.gif > /dev/null");

if (@$argv[1] === "!"){
  $pos = file_get_contents("./.config/gif/pos");
  $pos = explode("\n", $pos);
  $rev = $pos[9];
  }

if (!isset($rev)){
  $stdin = fopen('php://stdin', 'r');
  $rev = rtrim(fgets(STDIN));
  $rev = "1";
  }

if (!isset($rev)){
  $rev = "0";
  }

@system("cd ./.config/gif/ && sed -i '8s/.*/$defc/' pos");
@system("cd ./.config/gif/ && sed -i '9s/.*/$rw/' pos");
@system("cd ./.config/gif/ && sed -i '10s/.*/$rev/' pos");

if ($rev === "1"){
  @system("gifsicle                           \
            -i ~/Pictures/$named\_reduced.gif \
            '#-2-1'                           \
            -o ~/Pictures/".$named."_reversed.gif");

  $inv = "~/Pictures/".$named."_reversed.gif";

  usleep(400000);

  @system("gifsicle                           \
            -i ~/Pictures/$named\_reduced.gif \
          --append $inv                       \
          --resize-width $rw                  \
          -o ~/Pictures/".$named."_merged.gif");

  usleep(3000000);

  system("xdg-open ~/Pictures/".$named."_merged.gif > /dev/null");

  }

echo "\n####################";
echo "\nUpload to giphy.com?\n";

$stdin = fopen('php://stdin', 'r');
$response = rtrim(fgets(STDIN));

$m = "~/Pictures/".$named."_merged.gif";
$f = system("du -h $m");
$f = explode("  ",$f);
$f = $f[1];

$www = system('curl                         \
                --progress-bar              \
                -v                          \
                -F "file=@'.$f.'"           \
                -F "api_key=dc6zaTOxFJmzC"  \
                "http://upload.giphy.com/v1/gifs"');

$www = json_decode($www);

echo "\n\nhttps://i.giphy.com/".$www->data->id.".gif\n";

echo "\nThanks YOU!\n";

Sanatsal şeyler yaratmak için ters / birleştirme yeteneği.

Orijinal (435kb)

görüntü tanımını buraya girin

Birleştirilmiş, ters çevrildi: (826kb)

görüntü tanımını buraya girin

Phi kullanarak kurmak için :

php <(curl https://webdev23.github.io/phi/phi) install https://webdev23.github.io/gif/gif

Tam ekran:

[1920 * 1080px, gif 400px, 50 saniye , 100 renk, 2 Mb ]

görüntü tanımını buraya girin

Kaynak, daha fazla açıklama ve potansiyel güncellemeler ile: https://github.com/webdev23/gif

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.