Screencasting GIF; il modo UNIX


57

Per fare uno screenshot statico di una parte selezionata del mio schermo, lo uso spesso scrotcon -s shot.png. Questo è ottimo per aggiungere illustrazioni ai post di StackExchange. Ho anche trovato questo script per caricare automaticamente uno screenshot di questo tipo su Imgur.com e inserire un link negli appunti di X!

Portiamolo a dodici : come posso creare allo stesso modo uno screencast GIF?

Ci sono programmi come recordmydesktop, byzanz& co come discusso su Ask Ubuntu che mirano ad essere "user friendly", ma nella mia esperienza sono buggy, inefficienti, per lo più unscriptable e inadatto per poco una tantum cose come questa.

Voglio solo selezionare un'area e registrare una GIF, con un comando da console che posso capire, non una mostruosità arcana e non scriptabile della GUI.

Come posso fare questo?



2
Per tutto ciò che riguarda i terminali, questa potrebbe essere l'opzione migliore: asciinema.org
Flatron,

Risposte:


68

va bene allora

GIF vimcast!

Ho iniziato ffcast, fatto vim, chiuso ffcast, quindi converted .avi.gif.

Ho eseguito i comandi di registrazione in un altro terminale. Script lucido per te $PATHalla fine di questa risposta.

Quello che è successo?

cattura

FFcast aiuta l'utente a selezionare in modo interattivo un'area dello schermo e passa la geometria a un comando esterno, come FFmpeg, per la registrazione dello schermo.

ffcastè il glorioso prodotto di alcuni hacking nella comunità Arch Linux (principalmente lolilolicon ). Puoi trovarlo su github (o nell'AUR per Arch ers). Il suo elenco di dipendenze è giusto bashe ffmpeg, sebbene tu voglia xrectsel( collegamento AUR ) per la selezione interattiva del rettangolo.

È inoltre possibile aggiungere ffmpegflag subito dopo il comando. Ho impostato la -r 15cattura a 15 fotogrammi al secondo e -codec:v huffyuvper la registrazione senza perdita di dati. (Gioca con questi per modificare il compromesso dimensioni / qualità.)

GIFfing

ImageMagick in grado di leggere .avii video e ha alcuni trucchi di ottimizzazione GIF che riducono drasticamente le dimensioni dei file, preservando la qualità: L' -layers Optimizealla convertinvoca l'ottimizzatore general-purpose. Il manuale di ImageMagick ha anche una pagina sulle ottimizzazioni avanzate .

Sceneggiatura finale

Questo è quello che ho nel mio $PATH. Registra in un file temporaneo prima della conversione.

#!/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

Grazie a BenC per il lavoro investigativo nel capire le bandiere corrette dopo il recente ffcastaggiornamento.

Se desideri installare le dipendenze su una distribuzione basata su Debian, Louis ha scritto utili note di installazione .

WHEEEEEE!


1
Ho creato una versione che non richiede bash, ma che funziona su qualsiasi shell conforme a POSIX github.com/chilicuil/ffcast
Javier López

2
Sembra che la sintassi della riga di comando di ffcastsia cambiata: github.com/lolilolicon/FFcast/issues/8
Jack O'Connor

1
Il modo più semplice per farlo è ora ffcast -s rec [filename], anche se questo non fornisce le impostazioni esatte che stai usando nel tuo esempio. Sfortunatamente, per fornire impostazioni esatte, ora devi dare l'intero ffmpegcomando. La tua telefonata sul modo migliore per aggiornare questa risposta :)
Jack O'Connor,

4
Sulla base dei commenti su GH, 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_AVIsembra fare il trucco.
BenC,

1
Alcune note sull'installazione di alcune di queste cose per chiunque senza queste già sul loro sistema
Louis Maddox

11

Per me, la risposta è stata di utilizzare ffcastcon ffmpegquesto modo:

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

In seguito ho usato ffmpegla conversione da avi a gif: è molto veloce e mantiene intatto il framerate:

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

Infine ho usato convert nello stesso modo della risposta di @anko per ottimizzare la gif, ma ho impostato un limite sull'utilizzo delle risorse per interrompere l' uscita con un messaggio e ho rimosso il ritardo poiché ha già gestito che:convertkilledffmpeg

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


2

per la mia installazione (ubuntu 16.04), ffcast non funziona bene in quanto non viene aggiornato su github da un po 'di tempo.

così ho creato uno script usando slop ( https://github.com/naelstrof/slop ) e ffmpeg.

un esempio:

yay funziona

#!/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

Per questo motivo avevo scritto uno script wrapper interattivo per desktop unix e, dopo un anno di utilizzo, sono felice di condividerlo lì!

Realizzato con byzanz, gifsicle, xdotool, e lo script è scritto in php.

Esempio di output:

[1020px, larghezza gif non ridimensionata 1020px, 70 secondi, 50 colori, 65Kb ]

inserisci qui la descrizione dell'immagine

Fornisce buone gif compresse ed è una buona vetrina per questa domanda.

Questa è una base abbastanza semplice, pronta per essere hackerata da te.

Funzionalità : registrazione GIF a posizioni del mouse o a schermo intero, ridimensionamento, compressione, compressione colore, inversione / unione, caricamento arricciatura giphy.com.

Per avviare un record gif di 10 secondi: gif 10

Per registrare più volte con gli stessi parametri: gif !

Per avviare un disco gif di 5 secondi a schermo intero: gif 5 --fullscreen

Script runnning, registrandosi piacevolmente:

[ 45 secondi, larghezza 645px, colori pieni, 976kb ]
inserisci qui la descrizione dell'immagine

Script completo da 5kb:

#!/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";

Funzionalità di inversione / unione, per creare oggetti artistici.

Originale (435kb)

inserisci qui la descrizione dell'immagine

Invertito, unito: (826kb)

inserisci qui la descrizione dell'immagine

Per installare, usando phi :

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

A schermo intero:

[1920 * 1080px, gif 400px, 50 secondi , 100 colori, 2Mb ]

inserisci qui la descrizione dell'immagine

Fonte, con qualche spiegazione in più e potenziali aggiornamenti: https://github.com/webdev23/gif

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.