GIF screencasting; วิธี UNIX


57

ที่จะใช้หน้าจอแบบคงที่ของส่วนที่เลือกของหน้าจอของฉันฉันมักจะใช้กับscrot -s shot.pngนี่เป็นสิ่งที่ยอดเยี่ยมสำหรับการเพิ่มภาพประกอบในโพสต์ StackExchange ฉันยังพบสคริปต์นี้เพื่ออัปโหลดภาพหน้าจอดังกล่าวไปยังImgur.comโดยอัตโนมัติและใส่ลิงค์ไว้ในคลิปบอร์ด X ของฉัน!

ลองเปลี่ยนเป็นสิบสอง : ฉันจะสร้างหน้าจอ GIF แบบเดียวกันได้อย่างไร

มีมีโปรแกรมเช่นrecordmydesktop, byzanzและร่วมตามที่กล่าวไว้ในการขอให้อูบุนตูที่มีจุดมุ่งหมายที่จะ "ใช้งานง่าย" แต่ในประสบการณ์ของผมเป็นรถไม่มีประสิทธิภาพส่วนใหญ่ unscriptable และพอเพียงเล็กน้อยสิ่งหนึ่งออกเช่นนี้

ฉันแค่ต้องการเลือกพื้นที่และบันทึก GIF ด้วยคำสั่งคอนโซลที่ฉันสามารถเข้าใจได้ไม่ใช่ความผิดพลาด GUI ที่ไม่สามารถอธิบายได้

ฉันจะทำสิ่งนี้ได้อย่างไร



2
สำหรับเทอร์มินัลอะไรก็ตามนี่อาจเป็นตัวเลือกที่ดีกว่า: asciinema.org
Flatron

คำตอบ:


68

โอเคถ้าอย่างนั้น

GIF vimcast!

ผมเริ่มffcastไม่vimเลิกffcastแล้วconvertเอ็ด→.avi.gif

ฉันรันคำสั่งการบันทึกในเทอร์มินัลอื่น สคริปต์ขัดสำหรับคุณ$PATHในตอนท้ายของคำตอบนี้

เกิดอะไรขึ้น?

จับ

FFcast ช่วยให้ผู้ใช้เลือกพื้นที่หน้าจอแบบโต้ตอบและส่งมอบเรขาคณิตให้กับคำสั่งภายนอกเช่น FFmpeg สำหรับการบันทึกหน้าจอ

ffcastเป็นผลิตภัณฑ์ที่มีชื่อเสียงของการแฮ็กข้อมูลที่ชุมชน Arch Linux (ส่วนใหญ่เป็นโลลิโลลิคอน ) คุณสามารถค้นหาได้ใน GitHub (หรือใน AURสำหรับArch ers) รายการการพึ่งพานั้นเป็นเพียงbashและffmpegแม้ว่าคุณจะต้องการxrectsel( ลิงก์ AUR ) สำหรับการเลือกสี่เหลี่ยมผืนผ้าแบบโต้ตอบ

นอกจากนี้คุณยังสามารถผนวกffmpegค่าสถานะหลังจากคำสั่ง ฉันตั้งไว้-r 15ที่ 15 เฟรมต่อวินาทีและ-codec:v huffyuvบันทึก lossless (เล่นกับสิ่งเหล่านี้เพื่อปรับแต่งการแลกเปลี่ยนขนาด / คุณภาพ)

GIFfing

ImageMagick สามารถอ่าน.aviวิดีโอและมีบางเทคนิคการเพิ่มประสิทธิภาพ GIF ที่ลดขนาดไฟล์ในขณะที่รักษาคุณภาพการ-layers Optimizeที่จะconvertเรียกเพิ่มประสิทธิภาพวัตถุประสงค์ทั่วไป คู่มือ ImageMagick มีหน้าเกี่ยวกับการเพิ่มประสิทธิภาพขั้นสูงด้วย

สคริปต์สุดท้าย

$PATHนี่คือสิ่งที่ฉันมีในของฉัน มันบันทึกลงในไฟล์ชั่วคราวก่อนที่จะแปลง

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

ขอบคุณBenCสำหรับงานนักสืบในการหาค่าสถานะที่ถูกต้องหลังจากffcastอัพเดตล่าสุด

หากคุณต้องการที่จะติดตั้งการอ้างอิงใน distro Debian ตาม, หลุยส์ได้เขียนหมายเหตุการติดตั้งที่เป็นประโยชน์

Wheeeeee!


1
ฉันสร้างรุ่นที่ไม่ต้องใช้ทุบตี แต่ทำงานบนเชลล์ที่ได้มาตรฐาน POSIX github.com/chilicuil/ffcast
Javier López

2
ดูเหมือนว่าไวยากรณ์บรรทัดคำสั่งของffcastมีการเปลี่ยนแปลง: github.com/lolilolicon/FFcast/issues/8
Jack O'Connor

1
วิธีที่ง่ายที่สุดที่จะทำคือตอนนี้ffcast -s rec [filename]แม้ว่าจะไม่ได้ให้การตั้งค่าที่แน่นอนที่คุณใช้ในตัวอย่างของคุณ แต่น่าเสียดายที่จะให้การตั้งค่าที่แน่นอนตอนนี้คุณจะต้องให้ทั้งffmpegคำสั่ง การโทรศัพท์ของคุณเกี่ยวกับวิธีที่ดีที่สุดในการอัปเดตคำตอบนี้ :)
Jack O'Connor

4
จากความคิดเห็นเกี่ยวกับ 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_AVIดูเหมือนว่าจะทำเคล็ดลับ
BenC

1
หมายเหตุบางประการเกี่ยวกับการติดตั้งสิ่งเหล่านี้ให้กับผู้อื่นที่ไม่มีสิ่งเหล่านี้ในระบบของพวกเขาแล้ว
Louis Maddox

11

สำหรับฉันคำตอบคือใช้ffcastกับffmpegเช่น:

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

จากนั้นฉันเคยffmpegทำการแปลงจาก avi เป็น gif - มันเร็วมากและทำให้เฟรมเหมือนเดิม:

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

สุดท้ายฉันใช้การแปลงในลักษณะเดียวกับ@anko 's คำตอบเพื่อเพิ่มประสิทธิภาพ gif แต่ฉันได้กำหนดขีด จำกัด ในการใช้ทรัพยากรเพื่อหยุดconvertออกจากkilledข้อความและฉันลบความล่าช้าตามที่ffmpegได้รับการจัดการแล้ว:

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


2

สำหรับการตั้งค่าของฉัน (Ubuntu 16.04), ffcast ใช้งานไม่ได้เพราะมันไม่ได้รับการอัปเดตบน github มาระยะหนึ่งแล้ว

ดังนั้นฉันจึงวางสคริปต์โดยใช้ slop ( https://github.com/naelstrof/slop ) และ ffmpeg

ตัวอย่าง:

ใช่มันทำงานอยู่

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

ฉันเขียนสคริปต์ตัวตัดคำโต้ตอบสำหรับเดสก์ท็อปยูนิกซ์ด้วยเหตุนี้และหลังจากการใช้งานเป็นเวลาหนึ่งปีฉันมีความสุขที่ได้แบ่งปันมัน!

ทำด้วยbyzanz, gifsicle, xdotool, phpและสคริปต์ที่เขียนไว้ใน

ตัวอย่างผลลัพธ์:

[1020px, ไม่ปรับขนาดความกว้างของ GIF 1020px, 70 วินาที, 50 สี, 65Kb ]

ป้อนคำอธิบายรูปภาพที่นี่

มันให้ gif ที่บีบอัดได้ดีและเป็นตู้โชว์ที่ดีสำหรับคำถามนี้

นี่เป็นฐานที่ค่อนข้างง่ายพร้อมที่จะถูกแฮ็กโดยคุณ

ฟังก์ชันการทำงาน : บันทึก Gif ที่ตำแหน่งเมาส์หรือเต็มหน้าจอ, ปรับขนาด, บีบอัด, บีบอัดสี, ย้อนกลับ / รวม, อัปโหลด giphy.com

วิธีเริ่มบันทึก gif 10 วินาที: gif 10

ในการบันทึกหลาย ๆ ครั้งด้วยพารามิเตอร์เดียวกัน: gif !

ในการเริ่มบันทึก gif แบบเต็มหน้าจอ 5 วินาที: gif 5 --fullscreen

สคริปต์ทำงานต่อเนื่องบันทึกตัวเองอย่างน่ารื่นรมย์:

[ 45 วินาที, ความกว้าง 645px, สีเต็ม 976kb ]
ป้อนคำอธิบายรูปภาพที่นี่

สคริปต์เต็ม 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";

ย้อนกลับ / ผสานความสามารถในการสร้างเนื้อหาศิลปะ

เดิม (435kb)

ป้อนคำอธิบายรูปภาพที่นี่

ย้อนกลับผสานแล้ว: (826kb)

ป้อนคำอธิบายรูปภาพที่นี่

ในการติดตั้งโดยใช้phi :

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

เต็มจอ:

[1920 * 1080px, gif 400px, 50 วินาที , 100 สี, 2mb ]

ป้อนคำอธิบายรูปภาพที่นี่

แหล่งที่มาพร้อมคำอธิบายเพิ่มเติมและข้อมูลอัปเดตที่เป็นไปได้: https://github.com/webdev23/gif

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.