GIF ghi lại; cách UNIX


57

Để chụp ảnh màn hình tĩnh của một phần được chọn trên màn hình của tôi, tôi thường sử dụng scrotvới -s shot.png. Điều này là tuyệt vời để thêm hình minh họa vào bài viết StackExchange. Tôi thậm chí đã tìm thấy tập lệnh này để tự động tải lên một ảnh chụp màn hình như vậy lên Imgur.com và đặt một liên kết trong bảng tạm X của tôi!

Chúng ta hãy biến điều này thành mười hai : Làm thế nào để tôi tạo một screencast tương tự ?

những chương trình như recordmydesktop, byzanznhư đã thảo luận trên Ask Ubuntu nhằm mục đích "thân thiện với người dùng", nhưng theo kinh nghiệm của tôi là lỗi, không hiệu quả, chủ yếu là không thể mô tả và không được sử dụng cho những thứ nhỏ nhặt như thế này.

Tôi chỉ muốn chọn một khu vực và ghi lại một GIF, với lệnh console tôi có thể hiểu, không phải là một sự quái dị GUI không thể mô tả phức tạp.

Tôi có thể làm cái này như thế nào?



2
Đối với bất kỳ thiết bị đầu cuối nào có liên quan, đây có thể là lựa chọn tốt hơn: asciinema.org
Flatron

Câu trả lời:


68

Được rồi

GIF vimcast!

Tôi bắt đầu ffcast, đã làm vim, bỏ ffcast, sau đó converted .avi.gif.

Tôi chạy các lệnh ghi âm trong một thiết bị đầu cuối khác. Kịch bản đánh bóng cho bạn $PATHở cuối câu trả lời này.

Chuyện gì đã xảy ra?

Chụp

FFcast giúp người dùng tương tác chọn một vùng màn hình và bàn giao hình học cho một lệnh bên ngoài, chẳng hạn như FFmpeg, để ghi lại màn hình.

ffcastlà sản phẩm vinh quang của một số hack tại cộng đồng Arch Linux (chủ yếu là lolilolicon ). Bạn có thể tìm thấy nó trên github (hoặc trong AUR for Arch ers). Danh sách phụ thuộc của nó chỉ là bashffmpegmặc dù bạn sẽ muốn xrectsel( liên kết AUR ) cho lựa chọn hình chữ nhật tương tác.

Bạn cũng có thể chắp thêm ffmpegcờ ngay sau lệnh. Tôi cài đặt -r 15để chụp ở 15 khung hình mỗi giây và -codec:v huffyuvđể ghi lại lossless. (Chơi với những thứ này để điều chỉnh kích thước / chất lượng đánh đổi.)

QUÀ TẶNG

ImageMagick có thể đọc .avivideo và có một số thủ thuật tối ưu hóa GIF đó làm giảm đáng kể kích thước tập tin trong khi vẫn giữ chất lượng: Các -layers Optimizeđể convertgọi optimizer có mục đích chung. Hướng dẫn ImageMagick cũng có một trang về tối ưu hóa nâng cao .

Kịch bản cuối cùng

Đây là những gì tôi có trong tôi $PATH. Nó ghi vào một tập tin tạm thời trước khi chuyển đổi.

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

Cảm ơn BenC vì công việc thám tử trong việc tìm ra những lá cờ chính xác sau ffcastbản cập nhật gần đây .

Nếu bạn muốn cài đặt các phụ thuộc vào bản phân phối dựa trên Debian, Louis đã viết các ghi chú cài đặt hữu ích .

Wheeeeee!


1
Tôi đã tạo một phiên bản không yêu cầu bash, nhưng ai làm việc trên bất kỳ shell nào tuân thủ POSIX github.com/chilicuil/ffcast
Javier López

2
Có vẻ như cú pháp dòng lệnh ffcastđã thay đổi: github.com/lolilolicon/FFcast/issues/8
Jack O'Connor

1
Cách đơn giản nhất để làm điều đó là bây giờ ffcast -s rec [filename], mặc dù điều đó không đưa ra các cài đặt chính xác mà bạn đang sử dụng trong ví dụ của mình. Thật không may, để đưa ra các cài đặt chính xác, bây giờ bạn phải đưa ra toàn bộ ffmpeglệnh. Cuộc gọi của bạn về cách tốt nhất để cập nhật câu trả lời này :)
Jack O'Connor

4
Dựa trên các ý kiến ​​về 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_AVIdường như để thực hiện các mẹo.
BenC

1
Một số lưu ý khi cài đặt một số trong những thứ này cho bất kỳ ai khác mà chưa có trong hệ thống của họ
Louis Maddox

11

Đối với tôi, câu trả lời là sử dụng ffcastvới ffmpegnhư vậy:

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

Sau đó, tôi đã từng ffmpegthực hiện chuyển đổi từ avi sang gif - nó rất nhanh và nó giữ nguyên tốc độ khung hình:

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

Cuối cùng, tôi đã sử dụng chuyển đổi theo cách tương tự như câu trả lời của @anko để tối ưu hóa gif, nhưng tôi đặt giới hạn cho việc sử dụng tài nguyên để ngừng thoát bằng một tin nhắn và tôi đã xóa sự chậm trễ như đã xử lý:convertkilledffmpeg

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


2

đối với thiết lập của tôi (ubfox 16.04), ffcast không hoạt động tốt vì nó không được cập nhật trên github trong một thời gian dài.

vì vậy tôi đưa ra một tập lệnh bằng cách sử dụng slop ( https://github.com/naelstrof/slop ) và ffmpeg.

một ví dụ:

yay nó hoạt động

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

Tôi đã viết một kịch bản trình bao bọc tương tác cho máy tính để bàn unix vì lý do này, và sau một năm sử dụng, tôi rất vui được chia sẻ nó ở đó!

Thực hiện với byzanz, gifsicle, xdotool, và kịch bản được viết bằng php.

Ví dụ đầu ra:

[1020px, không thay đổi kích thước gif chiều rộng 1020px, 70 giây, 50 màu, 65Kb ]

nhập mô tả hình ảnh ở đây

Nó cung cấp gifs nén tốt, và là một điển hình tốt cho câu hỏi này.

Đây là một cơ sở khá đơn giản, sẵn sàng để bị hack bởi bạn.

Chức năng : Bản ghi Gif tại các vị trí chuột hoặc toàn màn hình, thay đổi kích thước, nén, nén màu, đảo ngược / hợp nhất, tải lên cuộn tròn giphy.com.

Để bắt đầu bản ghi gif 10 giây: gif 10

Để ghi lại nhiều lần với cùng một tham số: gif !

Để bắt đầu bản ghi gif toàn màn hình 5 giây: gif 5 --fullscreen

Kịch bản chạy, ghi lại chính mình:

[ 45 giây, chiều rộng 645px, màu sắc đầy đủ, 976kb ]
nhập mô tả hình ảnh ở đây

Kịch bản 5kb đầy đủ:

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

Khả năng đảo ngược / hợp nhất, để tạo ra các tác phẩm nghệ thuật.

Bản gốc (435kb)

nhập mô tả hình ảnh ở đây

Hoàn nguyên, sáp nhập: (826kb)

nhập mô tả hình ảnh ở đây

Để cài đặt, sử dụng phi :

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

Toàn màn hình:

[1920 * 1080px, gif 400px, 50 giây , 100 màu, 2Mb ]

nhập mô tả hình ảnh ở đây

Nguồn, với một số giải thích và cập nhật tiềm năng: https://github.com/webdev23/gif

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.