GIF 스크린 캐스팅; 유닉스 방식


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와 같은 외부 명령에 넘겨줍니다.

ffcastArch Linux 커뮤니티 (주로 lolilolicon ) 에서 해킹 한 것의 영광스러운 제품입니다 . 당신은 그것을 찾을 수 있습니다 GitHub의에 (또는 AUR를에 대한 아치 ERS)를. 그것의 의존성 목록은 그냥 하고 당신이 원하는거야하지만, ( AUR 링크 대화 형 사각형 선택을).bashffmpegxrectsel

ffmpeg명령 바로 뒤에 플래그 를 추가 할 수도 있습니다 . 내가 설정 -r 15초당 15 프레임의 속도로 캡처 -codec:v huffyuv무손실 녹음. (크기 / 품질 균형을 조정하려면이 기능을 사용하십시오.)

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.

데비안 기반 배포판에 의존성을 설치하려면 Louis유용한 설치 정보를 작성했습니다 .

응!


1
나는 bash가 필요하지 않지만 POSIX 호환 쉘 github.com/chilicuil/ffcast
Javier López

2
의 명령 줄 구문 같은데 ffcast: 변경 github.com/lolilolicon/FFcast/issues/8
잭 오코너

1
가장 간단한 방법은 now 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


11

나에게 답은 다음 ffcastffmpeg같이 사용 하는 것이 었습니다 .

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

그런 다음 ffmpegavi에서 gif로 변환 하는 데 사용 했습니다. 매우 빠르고 프레임 속도를 그대로 유지합니다.

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

마지막으로 @anko답변 과 같은 방식으로 변환을 사용 하여 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

나는 이런 이유로 유닉스 데스크탑을위한 대화식 래퍼 스크립트를 작성했으며, 1 년 동안 사용한 후에는 그것을 공유하게되어 기쁘다!

로 만든 byzanz, gifsicle, xdotool, 그리고 스크립트로 작성된 것입니다 php.

출력 예 :

[1020px, 크기 조정되지 않은 gif 너비 1020px, 70 초, 50 색, 65Kb ]

여기에 이미지 설명을 입력하십시오

좋은 압축 GIF를 제공 하며이 질문에 대한 좋은 쇼케이스입니다.

이것은 당신이 해킹 할 준비가 된 매우 간단한 기지입니다.

기능 : 마우스 위치 또는 전체 화면, 크기 조정, 압축, 색 압축, 역 / 병합, giphy.com curl 업로드에서 Gif 기록.

10 초 gif 레코드를 시작하려면 gif 10

동일한 매개 변수로 여러 번 기록하려면 다음을 수행하십시오. gif !

전체 화면 5 초 gif 레코드를 시작하려면 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.