У меня есть другой надлежащий способ сделать это, вставить этот код Ваш ~/.bashrc
или создайте новый файл и source file
:
PROMPT_COMMAND=$(
cat<<-'EOF'
retval=$?
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
STOP=$(tput sgr0)
# arithmetic using bash parameter expansion on a array
if (($retval + ${PIPESTATUS[@]/%/+} + 0)); then
PS1="\[$RED\]\u@\h:\w$ \[$STOP\]"
else
PS1="\[$GREEN\]\u@\h:\w$ \[$STOP\]"
fi
EOF
)
Это добьется цели =)
Bash выполнит код внутри PROMPT_COMMAND
поскольку каждый управляет.
Если у Вас есть скопировать/вставить проблема, можно загрузить сценарий
ОБЪЯСНЕНИЯ
(( ))
арифметика в bash
, см. http://wiki.bash-hackers.org/syntax/arith_exprPROMPT_COMMAND
: если установлено, значение выполняется как команда до издания каждой основной подсказки. Посмотрите man bash | less +/PROMPT_COMMAND
tput
лучше, чем трудное кодирование управляющие коды ANSI. См. http://wiki.bash-hackers.org/scripting/terminalcodesPIPESTATUS
: Переменная типа массив, содержащая список статуса выхода, оценивает от процессов в последний раз выполняемом приоритетном конвейере (который может содержать только единственную команду). Посмотрите man bash | less +/PIPESTATUS
cat<<-'EOF'
специальное предложение здесь документ: -
символ означает, что я могу форматировать код и одинарные кавычки на 'EOF'
средства не интерполировать переменныеЯ запустил ffcast
, сделал vim
, выход ffcast
, затем convert
редактор .avi
→.gif
.
Я выполнил команды записи в другом терминале. Полируемый сценарий для Вашего $PATH
в конце этого ответа.
FFcast помогает пользователю в интерактивном режиме выбрать экранный регион и передает геометрию внешней команде, такой как FFmpeg, для экранной записи.
ffcast
великолепный продукт некоторого взламывания в Дуге сообщество Linux (главным образом lolilolicon). Можно найти его на GitHub (или в АУРЕ для Стрельцов). Его список зависимости справедлив bash
и ffmpeg
, хотя Вы захотите xrectsel
(Ссылка АУРА) для интерактивного прямоугольного выбора.
Можно также добавить 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
Благодаря BenC для расследования в выяснении корректных флагов после недавнего ffcast
обновление.
Если требуется установить зависимости от находящегося в 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 - это очень быстро, и это сохраняет framerate в целости:
ffmpeg -i out.avi -pix_fmt rgb24 out.gif
Наконец я использовал, преобразовывают таким же образом как ответ @anko для оптимизации gif, но я установил предел для использования ресурсов для остановки , преобразовывают
, выход с уничтожил
сообщение, и я удалил задержку как , ffmpeg
уже обработал это:
convert -limit memory 1 -limit map 1 -layers Optimize out.gif out_optimised.gif
Этот репозиторий поможет вам создать GIF из области выделения, а также оптимизировать его для вас
По этой причине я написал интерактивный скрипт-оболочку для рабочих столов Unix, и после года использования я рад поделиться им!
Сделано с помощью byzanz
, gifsicle
, xdotool
, а скрипт написан на php
.
Пример вывода:
[1020px, без изменения размера gif ширина 1020px, 70 секунд, 50 цветов, 65Kb ]
Он предоставляет хорошие сжатые GIF-файлы и является хорошей демонстрацией для этого вопроса.
Это довольно простая база, которую вы можете взломать.
Функциональные возможности:Запись Gif в положениях мыши или в полноэкранном режиме, изменение размера, сжатие, сжатие цвета, реверс/объединение, загрузка giphy.com curl.
Чтобы начать 10-секундную запись GIF:gif 10
Для многократной записи с одними и теми же параметрами:gif !
Для запуска полноэкранной 5-секундной GIF-записи:gif 5 --fullscreen
Сценарий запущен, приятно записывает себя:
[ 45 секунд, ширина 645 пикселей, полноцветный режим, 976 КБ ]
Полный скрипт 5 КБ:
#!/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";
Возможность реверса/слияния для создания художественных материалов.
Оригинал (435 КБ)
Перевернутое, объединенное:(826 КБ)
Для установки с помощью 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 ответ (Мне понравилась простота, но я не мог понять, как это остановить ), и взял gifsicle из NVRM ответ (очень хорошее качество, должен сказать ), я создал свою собственную версию.
Он начинается с запроса области для записи (без звука ), а затем прямо под нижним правым углом вашего выбора помещается небольшой квадрат с кнопками (, не мешающий записи. Он остается сверху, но не захватывает фокус.
Вы можете приостановить/продолжить или просто остановить в любое время. Я считаю болью необходимость указывать продолжительность заранее, будьте свободны!
Результат помещается в ~/Загрузки/ с отметкой времени типа 2020 -02 -29 --0237.gif (Я предпочитаю не тратить время на указание куда/как сохранить ).
Не стесняйтесь настраивать под свои нужды. Я попытался сделать это очень понятным.
Я многому научился, соединяя все вместе (yad, ffmpeg и signal, 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
Я просмотрел ImageMagick import
, и оказалось, что выходные данные содержат размеры захваченной области. Итак, если вы похожи на меня, и у вас установлен ImageMagick, и вы не хотите устанавливать другую утилиту только для получения разрешения и смещения x/y выбранной области, вы можете использовать что-то вроде этого:
#!/bin/sh
eval "$(
import - | awk '
/^DisplayImage$/{
getline
print "X=" $1
print "Y=" $2
getline
print "W=" $1
print "H=" $2
exit
}
'
)"
# Record a region of your desktop as gif
ffmpeg -f x11grab -s "$W"x"$H" -r 30 -i :0.0+"$X","$Y" -pix_fmt rgb24 -loop 0 output.gif
# Take a partial screenshot using ffmpeg
# ffmpeg -f x11grab -s "$W"x"$H" -i :0.0+"$X","$Y" -vframes 1 output.png
# You might as well just use `import` (`import` doesn't support gifs though)
# import output.png
ffcast
изменился: Интересный github.com/lolilolicon/FFcast/issues/8 – Jack O'Connor 30.09.2014, 23:25ffcast -s rec [filename]
, хотя это не дает точные настройки, Вы используете в своем примере. К сожалению, для предоставления точных настроек теперь необходимо дать всеffmpeg
команда. Ваш вызов о лучшем способе обновить этот :) – Jack O'Connor 01.10.2014, 04:47ffcast -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 01.10.2014, 13:35