画面の選択した部分の静的スクリーンショットを撮るには、 scrot
と-s shot.png
。これは、StackExchange投稿にイラストを追加するのに最適です。私も this script を見つけて、そのようなスクリーンショットをImgur.comに自動的にアップロードし、Xクリップボードにリンクを配置しました!
これをtwelve に変えましょう:どうすればよいですか同様にGIFスクリーンキャストを作成しますか?
recordmydesktop
、byzanz
&coなどのareプログラムがあります Ask Ubuntuで説明されているように 「ユーザーフレンドリー」を目指しています「しかし、私の経験では、バグが多く、非効率的で、ほとんどがスクリプト不可能で、このような小さな1回限りのものには適していません。
領域を選択してGIFを記録したいのですが、理解できないコンソールコマンドを使用しています。不可解なスクリプト不可能なGUIの怪物ではありません。
これどうやってするの?
私はffcast
を開始し、vim
を実行し、ffcast
を終了し、次にconvert
ed .avi
→.gif
を終了しました。
別の端末で記録コマンドを実行しました。この回答の最後にある$PATH
の洗練されたスクリプト。
FFcastは、ユーザーがインタラクティブに画面領域を選択し、ジオメトリをFFmpegなどの外部コマンドに渡して画面を記録するのに役立ちます。
ffcast
は、Arch Linuxコミュニティでの some hacking (主に lolilolicon )の素晴らしい製品です。あなたはそれを見つけることができます githubで (または AURでArch ersの場合)。依存関係リストはbash
とffmpeg
だけですが、インタラクティブな四角形の選択には xrectsel
( AUR link )が必要です。
コマンドの直後にffmpeg
フラグを追加することもできます。 -r 15
を15フレーム/秒でキャプチャするように設定し、-codec:v huffyuv
をロスレス録音用に設定します。 (サイズと品質のトレードオフを微調整するには、これらを試してください。)
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
最近のffcast
の更新後に正しいフラグを特定する際の探偵の仕事に感謝 BenC .
Debianベースのディストリビューションに依存関係をインストールする場合は、 Louis が 役立つインストールノート を作成しています。
私にとって、答えは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 answer と同じように変換を使用してgifを最適化しましたが、リソースの使用に制限を設定してconvert
の終了を停止しましたkilled
メッセージを表示し、ffmpeg
がすでに処理しているため、遅延を削除しました。
convert -limit memory 1 -limit map 1 -layers Optimize out.gif out_optimised.gif
私のセットアップ(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
更新:コードが更新され、Ruffが述べたようにffmpegがconvert
の実行を妨げる終了コード2を返します。記録後、ctrl + Cを押すとffmpegが終了し、convert
を実行してout.gifが生成されます。
このリポジトリは、選択領域からgifを作成し、それを最適化するのに役立ちます
このため、私はUNIXデスクトップ用のインタラクティブなラッパースクリプトを作成しており、1年間使用した後、そこで共有できてうれしいです。
byzanz
、gifsicle
、xdotool
で作成され、スクリプトはphp
で記述されています。
出力例:
[1020px、サイズ変更されていないgif幅1020px、70秒、50色、65Kb]
優れた圧縮GIFを提供し、この質問の良いショーケースです。
これはかなり単純なベースであり、ハッキングされる準備ができています。
機能:マウス位置またはフルスクリーンでのGifレコード、サイズ変更、圧縮、色圧縮、逆/マージ、giphy.comカールのアップロード。
10秒のgifレコードを開始するには:gif 10
同じパラメータで複数回記録するには:gif !
フルスクリーンの5秒間のgifレコードを開始するには:gif 5 --fullscreen
スクリプトを実行し、自分自身を心地よく録音:
完全な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
TC Zhang の答えの上に構築し(私は単純さが好きでしたが、それを止める方法がわかりませんでした)、gifを [〜#〜] nvrm [〜 #〜] の答え(私が言わなければならない非常に素晴らしい品質)、私は自分のバージョンを作成しました。
まず、録音する領域を(無音で)要求し、次にボタンの付いた小さなボックスを選択の右下隅のすぐ下に配置します(録音に干渉しません。上部に残りますが、フォーカスを取得しません。
いつでも一時停止/続行、または単に停止することができます。事前に期間を指定するのは面倒だと思いますので、お気軽に!
結果は〜/ Downloads /に配置され、2020-02-29--0237.gifのようなタイムスタンプが付けられます(保存場所/保存方法の指定に時間をかけたくない)。
必要に応じて自由にカスタマイズしてください。私はそれをとても自明にしようとしました。
私はそれをすべて一緒にまとめることを学びました(yad、ffmpeg、シグナル、bashなど)
誰かが録音/変換品質のより良いパラメータを見つけたら、私に知らせてください。更新させていただきます。
よろしくお願いします。
例:
#!/bin/bash
# Inspired on script from https://unix.stackexchange.com/questions/113695/gif-screencasting-the-unix-way
# Failsafe, just in case interactive stop fails, recording can be large
# If you are goint to pause consider increasing it as clock is still ticking while paused
DURATION=40;
# Destination for output gif file
GIF_OUT_FOLDER="/home/$USER/Downloads"
GIF_OUT_FILE=$GIF_OUT_FOLDER/$(date +'%Y-%m-%d--%H%M').gif
# Request section to record interactively
read -r X Y W H G ID < <(slop -f "%x %y %w %h %g %i")
# Create the name for the temp file with video
TMP_AVI=$(mktemp /tmp/outXXXXXXXXXX.avi)
# Export variables
export TMP_AVI DURATION GIF_OUT_FOLDER GIF_OUT_FILE X Y W H G ID
# Define functions and export them
#--------------------------------------------
stop_recording_and_create_gif() {
killall --user $USER --ignore-case --signal INT ffmpeg ; convert -layers removeDups -layers Optimize -delay 13 -loop 0 $TMP_AVI $GIF_OUT_FILE && rm -I "$TMP_AVI";
# Optimize gif file
gifsicle --verbose --batch --interlace $GIF_OUT_FILE --optimize=05 --colors=128; # --output out.gif
}
export -f stop_recording_and_create_gif
#--------------------------------------------
start_recording_screen_section () {
# Record and convert to gif file
#3 not-original / added -t n for n seconds recording
ffmpeg -t $DURATION -s "$W"x"$H" -y -f x11grab -i :0.0+$X,$Y -vcodec huffyuv -r 25 $TMP_AVI;
}
export -f start_recording_screen_section
#--------------------------------------------
FContinue () { killall --user $USER --ignore-case --signal SIGCONT ffmpeg ;}
FPause () { killall --user $USER --ignore-case --signal SIGSTOP ffmpeg ; }
export -f FContinue FPause
####################################
# Collect the YAD options
cmd=(yad
--width 5
--height 5
--on-top
--skip-taskbar
--borders=0
#--undecorated (so you have something to grab it if you want to move it)
--columns 1
--no-focus
#--mouse (it gets a bit inside the recording window)
--geometry=5x5+$(($X+$W+10))+$(($Y+$H+10))
#--no-buttons (avoids having buttons we don't need)
# This is a trick to have the buttons vertical
--form
--title="Screencast to GIF"
--field='Start recording!stop!Start recording (maximum defined duration)':fbtn 'bash -c "start_recording_screen_section"'
--field='Stop recording!gtk-quit!Stop recording and create gif file in output folder':fbtn 'bash -c "stop_recording_and_create_gif & kill -SIGUSR1 $YAD_PID"'
--field='Pause!gtk-pause!':fbtn 'bash -c "FPause"'
--field='Continue!gtk-continue!':fbtn 'bash -c "FContinue"'
--button='Quit!gtk-ok':'bash -c "kill -SIGUSR1 $YAD_PID"'
)
# Run yad
"${cmd[@]}"
# Cleanup before leaving
unset TMP_AVI DURATION GIF_OUT_FOLDER GIF_OUT_FILE X Y W H G ID
unset stop_recording_and_create_gif
unset start_recording_screen_section
unset FContinue FPause