Screencasting GIF; cara UNIX

57

Untuk mengambil screenshot statis dari bagian yang dipilih dari layar saya, saya sering menggunakan scrotdengan -s shot.png. Ini bagus untuk menambahkan ilustrasi ke posting StackExchange. Saya bahkan menemukan skrip ini untuk secara otomatis mengunggah tangkapan layar ke Imgur.com dan menaruh tautan di papan klip X saya!

Mari kita ubah ini menjadi dua belas : Bagaimana cara saya membuat screencast GIF?

Ada beberapa program seperti recordmydesktop, byzanz& co seperti yang dibahas pada Tanya Ubuntu yang bertujuan untuk menjadi "ramah pengguna", tetapi dalam pengalaman saya adalah buggy, tidak efisien, sebagian besar tidak dapat ditulis dan tidak cocok untuk hal-hal kecil seperti ini.

Saya hanya ingin memilih area dan merekam GIF, dengan perintah konsol yang dapat saya mengerti, bukan sesuatu yang misterius yang tidak dapat dituliskan dengan GUI.

Bagaimana saya bisa melakukan ini?

Anko
sumber
2
Terkait: Bagaimana cara membuat gambar GIF animasi screencast? dari Ask Ubuntu.
Cristian Ciupitu
2
Untuk terminal apa pun yang terkait, ini mungkin pilihan yang lebih baik: asciinema.org
Flatron

Jawaban:

68

Baiklah kalau begitu

GIF vimcast!

Saya mulai ffcast, lakukan vim, berhenti ffcast, lalu convertedit .avi.gif.

Saya menjalankan perintah perekaman di terminal lain. Skrip yang dipoles untuk Anda $PATHdi akhir jawaban ini.

Apa yang terjadi?

Menangkap

FFcast membantu pengguna secara interaktif memilih wilayah layar dan menyerahkan geometri ke perintah eksternal, seperti FFmpeg, untuk perekaman layar.

ffcastadalah produk luar biasa dari beberapa peretasan di komunitas Arch Linux (terutama lolilolicon ). Anda dapat menemukannya di github (atau di AUR for Arch ers). Daftar ketergantungannya adil bashdan ffmpeg, meskipun Anda ingin xrectsel( tautan AUR ) untuk pemilihan persegi panjang interaktif.

Anda juga dapat menambahkan ffmpegflag tepat setelah perintah. Saya mengatur -r 15untuk menangkap pada 15 frame per detik dan -codec:v huffyuvuntuk perekaman lossless. (Mainkan dengan ini untuk men-tweak pengorbanan ukuran / kualitas.)

GIFfing

ImageMagick dapat membaca .avivideo dan memiliki beberapa trik optimasi GIF yang secara drastis mengurangi ukuran file sambil menjaga kualitas: The -layers Optimizeuntuk convertmemanggil pengoptimal tujuan umum. Manual ImageMagick juga memiliki halaman tentang optimisasi tingkat lanjut .

Naskah akhir

Inilah yang saya miliki di blog saya $PATH. Ini merekam ke dalam file sementara sebelum mengkonversi.

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

Terima kasih kepada BenC untuk pekerjaan detektif dalam mencari tanda yang benar setelah ffcastpembaruan terbaru .

Jika Anda ingin menginstal dependensi pada distro berbasis Debian, Louis telah menulis catatan instalasi yang bermanfaat .

Aduh!

Anko
sumber
1
Saya telah membuat versi yang tidak memerlukan bash, tetapi yang bekerja pada semua shell yang sesuai dengan POSIX github.com/chilicuil/ffcast
Javier López
2
Sepertinya sintaks baris perintah ffcasttelah berubah: github.com/lolilolicon/FFcast/issues/8
Jack O'Connor
1
Cara paling sederhana untuk melakukannya adalah sekarang ffcast -s rec [filename], meskipun itu tidak memberikan pengaturan tepat yang Anda gunakan dalam contoh Anda. Sayangnya, untuk memberikan pengaturan yang tepat, Anda sekarang harus memberikan seluruh ffmpegperintah. Panggilan Anda tentang cara terbaik untuk memperbarui jawaban ini :)
Jack O'Connor
4
Berdasarkan komentar di 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_AVIsepertinya melakukan trik.
BenC
1
Beberapa catatan tentang pemasangan beberapa hal ini untuk orang lain tanpa ini sudah ada di sistem mereka
Louis Maddox
11

Bagi saya, jawabannya adalah untuk menggunakan ffcastdengan ffmpegseperti:

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

Saya kemudian biasa ffmpegmelakukan konversi dari avi ke gif - sangat cepat dan menjaga framerate tetap utuh:

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

Terakhir saya menggunakan convert dalam cara yang sama seperti @anko 's jawaban untuk mengoptimalkan gif, tapi saya menetapkan batas pada penggunaan sumber daya untuk berhenti convertkeluar dengan killedpesan, dan saya dihapus penundaan sebagai ffmpegtelah ditangani bahwa:

convert -limit memory 1 -limit map 1 -layers Optimize out.gif out_optimised.gif
John Hamelink
sumber
2

untuk pengaturan saya (ubuntu 16.04), ffcast tidak berfungsi dengan baik karena tidak diperbarui di github untuk sementara waktu.

jadi saya memasang script menggunakan slop ( https://github.com/naelstrof/slop ) dan ffmpeg.

sebuah contoh:

ya itu berhasil

#!/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 
TC Zhang
sumber
1

Saya telah menulis skrip pembungkus interaktif untuk desktop unix untuk alasan ini, dan setelah satu tahun penggunaan, saya senang membagikannya di sana!

Dibuat dengan byzanz, gifsicle, xdotool, dan script ditulis dalam php.

Contoh output:

[1020px, lebar gif tidak diubah ukuran 1020px, 70 detik, 50 warna, 65Kb ]

masukkan deskripsi gambar di sini

Ini memberikan gif terkompresi yang baik, dan merupakan karya yang bagus untuk pertanyaan ini.

Ini adalah basis yang cukup sederhana, siap untuk diretas oleh Anda.

Fungsi : Gif record pada posisi mouse atau layar penuh, mengubah ukuran, kompresi, kompresi warna, membalikkan / menggabungkan, unggahan ikal giphy.com.

Untuk memulai catatan gif 10 detik: gif 10

Untuk merekam beberapa kali dengan parameter yang sama: gif !

Untuk memulai catatan gif layar penuh 5 detik: gif 5 --fullscreen

Script runnning, dengan senang hati merekam dirinya sendiri:

[ 45 detik, lebar 645px, penuh warna, 976kb ]
masukkan deskripsi gambar di sini

Skrip 5kb penuh:

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

Kemampuan membalikkan / menggabungkan, untuk membuat barang artistik.

Asli (435kb)

masukkan deskripsi gambar di sini

Terbalik, digabung: (826kb)

masukkan deskripsi gambar di sini

Untuk menginstal, menggunakan phi :

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

Layar penuh:

[1920 * 1080px, gif 400px, 50 detik , 100 warna, 2Mb ]

masukkan deskripsi gambar di sini

Sumber, dengan beberapa penjelasan lebih lanjut dan potensi pembaruan: https://github.com/webdev23/gif

NVRM
sumber