Repository: phisch/giph
Branch: master
Commit: 6cee9780fa6a
Files: 5
Total size: 21.7 KB
Directory structure:
gitextract_icb2cw67/
├── LICENSE
├── Makefile
├── README.md
├── man/
│ └── giph.1
└── src/
└── giph
================================================
FILE CONTENTS
================================================
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019 Philipp Schaffrath
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Makefile
================================================
PREFIX ?= /usr/local
DESTDIR ?=
BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/share/man
all:
@echo "Nothing to do, try \"make install\" instead."
install-common:
@install -v -d "$(DESTDIR)$(MANDIR)/man1" && install -m 0644 -v man/giph.1 "$(DESTDIR)$(MANDIR)/man1/giph.1"
install: install-common
@install -v -d "$(DESTDIR)$(BINDIR)/" && install -m 0755 -v src/giph "$(DESTDIR)$(BINDIR)/giph"
uninstall:
@rm -vrf \
"$(DESTDIR)$(BINDIR)/giph" \
"$(DESTDIR)$(MANDIR)/man1/giph.1"
.PHONY: install uninstall install-common
================================================
FILE: README.md
================================================
# giph
giph is a screen recorder that records the desktop, a window or selection and encodes it into a gif file. It prints the encoded gif directly to standard output when omitting the output filename.

*I used **giph** to record a gif of **giph** recording a gif*.
## Examples
```bash
$ giph -s -l -c 1,1,1,0.3 -b 5 -p -5 out.gif
```
Select a window or area with slop. The selection rectangle is highlighted in a transparent blue color abd has a 5px border on the inside.
After stopping the recording with either `ctrl+c`, by running `giph --stop` or by sending a `SIGINT` to the processgroup, the resulting gif is written to `out.gif`.
```bash
$ giph -g 100x200+0+0 -d 5 -t 10
```
Records a 100x200 pixel rectangle in the top left corner of the screen. The recording starts after a 5 seconds countdown and will record for exactly 10 seconds. The resulting gif will be printed to standard output, which makes this able to be piped into other scripts like a file-upload to an image hosting service.
```bash
$ giph -f 30 -t 5 -s -a -m out.webm
```
Records a 5 second video of the users selection at 30 fps. The recording also contains the users desktop audio and microphone. If the recording fails because the default audio source `0` is not the correct one, run `pacmd list-sources` to get the correct source `index` or `name` and pass it to the `-as` parameter instead of using `-a`. Example: `giph -f 30 -t 5 -s -as 1 -m out.webm` (using id) or `giph -f 30 -t 5 -s -as alsa_output.pci-0000_04_00.1.hdmi-stereo.monitor -m out.webm` (using name)
```bash
$ giph -s -t 10 --format webm | curl -F "file=@-" 0x0.st | xclip -selection clipboard
```
Records a 10 second webm of the users selection, uploads the video to 0x0.st using curl and copies the returned url to the clipboard.
## Installation
### Arch
```bash
$ yay -S giph
```
Or install [giph-git](https://aur.archlinux.org/packages/giph-git/) to get the latest development version.
### From source
Make sure to install the following dependencies:
- ffmpeg
- xdotool
Optionally, install the following dependencies:
- slop (`--select`)
- libnotify (`--notify`)
- pgrep (`--stop`)
Clone the giph repository:
```bash
$ git clone https://github.com/phisch/giph.git
```
And finally install giph:
```bash
$ cd giph
$ sudo make install
```
## Desktop Makers
<a href="https://discord.gg/RqKTeA4uxW" title="Desktop Makers Discord"><img align="left" width="72" alt="type=discord" src="https://user-images.githubusercontent.com/1282767/161089772-d7ad28bf-76eb-4951-b0f0-985afd5ea57a.png"></a>
I am actively working on giph and other cool projects on the [Desktop Makers Discord](https://discord.gg/RqKTeA4uxW). It aims to be a community for communities of Linux desktop related projects. If you are looking to collaborate with or want to contribute to great projects, this might be the right place for you.
================================================
FILE: man/giph.1
================================================
.TH GIPH 1 "April 2019" "MIT License" "User Commands"
.SH NAME
giph \- record gif from desktop, window or selection
.SH SYNOPSIS
.B giph
.RI [ OPTIONS "] [" FILENAME ]
.br
.B giph
[\fB-g\fR \fIGEOMETRY\fR |
\fB-w\fR \fIINT\fR |
\fB-s\fR [\fB-l\fR] [\fB-c\fR \fIFLOAT,FLOAT,FLOAT,FLOAT\fR] [\fB-p\fR \fIFLOAT\fR] [\fB-b\fR \fIFLOAT\fR]]
[\fB-d\fR \fIINT\fR]
[\fB-t\fR \fIINT\fR]
[\fB-f\fR \fIINT\fR]
[\fB--format\fR \fISTRING\fR]
[\fB-a\fR | \fB -as \fISTRING\fR]
[\fB-m\fR | \fB -ms \fISTRING\fR]
[\fIFILENAME\fR]
.SH DESCRIPTION
.B giph
is a screen recorder that records the desktop, a window or selection and encodes it into a video file.
.br
The recorded video file is encoded in one of the supported formats, gif, webm, mp4 or mkv based on the file extension given in [\fIFILENAME\fR].
.br
When omitting [\fIFILENAME\fR], the default format "gif" is used (use --format to overwrite), and the resulting video directly printed to standard output.
.SH EXAMPLES
.TP
.BI "giph -g " "300x200+600+200 ~/Videos/$(date +%s).png"
Records a 300x200 pixel (width x height) rectangle, that is shifted 600 pixel to the right and 200 pixel down from the top-left corner. The recording stops when either
.B ctrl+c
is pressed, or after calling
.B giph --stop.
.br
The encoded gif will be saved in your users videos directory and has the current timestamp as a name.
.SH OPTIONS
.TP
.BR \-h ", " \-\-help
Print help and exit.
.TP
.BR \-\-stop
Finish any running giph recordings
.TP
.BR \-\-version
Print version and exit.
.TP
.BR \-v* ", " \-\-verbose ", " \-\-quiet
Defines how verbose giph will be. Omitting [\fIFILENAME\fR] will overwrite the verbosity to \fI-1\fR (quiet). Use the following list to determine which option to use for each verbosity level:
.in +2
\(bu
.IB "-1 \fR(quiet)" " --quiet \fR - logs errors"
.br
\(bu
.IB " 0 \fR(normal) - like quiet, also displays interactive components"
.br
\(bu
.IB " 1 \fR(verbose)" " -v\fR, \fB--verbose" "\fR - like normal, also logs basic information about steps"
.br
\(bu
.IB " 2 \fR(very_verbose) " -vv "\fR - like verbose, also logs detailed information about steps"
.br
\(bu
.IB " 3 \fR(debug) " -vvv "\fR - like very_verbose, also shows background process output"
.TP
.BR \-s ", " \-\-select
Uses slop to interactively select the desired region or window to record. This uses the
.B SLOP OPTIONS
described below.
.TP
.BR \-g ", " \-\-geometry " " \fIGEOMETRY
Sets the region to record.
.TP
.BR \-w ", " \-\-window " " \fIINT
Sets the window id of the desired window to record.
.TP
.BR \-d ", " \-\-delay " " \fIINT
Sets the time in seconds to wait before the recording starts.
.TP
.BR \-t ", " \-\-timer " " \fITIMEDURATION
Sets a fixed time to record. The format is a timeduration as described in the ffmpeg documentation (https://ffmpeg.org/ffmpeg-utils.html#Time-duration). As an example, '10' would mean 10 seconds, '3:30' means 3 minutes and 30 seconds, '1:02:03' means 1 hour, 2 minutes and 3 seconds, and '5.5' means 5.5 seconds.
.TP
.BR \-f ", " \-\-framerate " \fIINT\fR (default: \fI20\fR)"
Sets the desired framerate of the recorded gif. A higher framerate will result in a larger filesize.
.TP
.BR \-\-format
Overwrites the format that should be used for the recording. The available formats are
.IR gif ", " webm ", " mp4 " and " mkv "."
While
.IR gif
is the only format that does not support audio recording.
.TP
.BR \-a ", " \-\-audio
Enables audio recording for formats that support audio.
.TP
.BR \-as ", " \-\-audio-source " \fISTRING\fR (default: '\fI0\fR')"
Define which pulseaudio source should be used for the recording. Run `pacmd list-sources` to get a list of all available sources. You can use either the index or the name of the source for this parameter. When setting this parameter, setting
.BR \-a " or " \-\-audio
can be omitted.
.TP
.BR \-m ", " \-\-microphone
Enables microphone recording for formats that support audio.
.TP
.BR \-ms ", " \-\-microphone-source " \fISTRING\fR (default: '\fIdefault\fR')"
Define which pulseaudio source should be used for the recording. Run `pacmd list-sources` to get a list of all available sources. You can use either the index or the name of the source for this parameter. When setting this parameter, setting
.BR \-m " or " \-\-microphone
can be omitted.
.TP
.BR \-y ", " \-\-notify
Uses notify-send to send an urgent notification if an error happens, or a normal notification when the final gif was saved successfully.
.SH SLOP OPTIONS
When
.BR -s " or " --select
is used, slop will be used to get geometry information. Read
.B slop(1)
for more detailed information about slop options. The following options will be passed to slop if they are set:
.TP
.BR \-b ", " \-\-bordersize " \fIFLOAT\fR (default: \fI1\fR)"
Set the selection border thickness.
.TP
.BR \-p ", " \-\-padding " \fIFLOAT\fR (default: \fI0\fR)"
Set the selection padding. This can be negative.
.TP
.BR \-to ", " \-\-tolerance " \fIFLOAT\fR (default: \fI2\fR)"
Defines how far the mouse can move after clicking while still being considered a click.
.TP
.BR \-c ", " \-\-color " \fIFLOAT,FLOAT,FLOAT,FLOAT\fR (default: \fI0.5,0.5,0.5,1\fR)"
Set the selection color as RGB or ARGB.
.TP
.BR \-r ", " \-\-shader " \fISTRING"
Set the shader to be used.
.TP
.BR \-n ", " \-\-nodecorations " \fIINT\fR (default: \fI0\fR)"
.RI "Tries to select child windows. " 0 " is off, " 1 " tries to remove decorations, " 2 " aggressively tries to remove decorations."
.TP
.BR \-l ", " \-\-highlight
.RB "Highlight the selection rectangle. This uses the color provided in " -c " or " --color "."
.TP
.BR \-k ", " \-\-nokeyboard
Disable being able to cancel the selection using the keyboard.
.TP
.BR \-o ", " \-\-noopengl
Disable graphics acceleration.
.SH SEE ALSO
.B slop(1)
================================================
FILE: src/giph
================================================
#!/usr/bin/env bash
stty -echoctl # don't print ^C when pressing ctrl+c
readonly VERSION=1.1.1
# verbosity
VERBOSITY=0
# options
SLOP=0
DELAY=0
FRAMERATE=20
AUDIO=0
AUDIO_SOURCE=0
MICROPHONE=0
MICROPHONE_SOURCE=default
FORMAT_OVERWRITE=""
function print_version() {
echo "$VERSION"
exit 0
}
function print_help() {
cat << EOF
SYNOPSIS
giph [OPTIONS] [FILENAME]
DESCRIPTION
giph is a screen recorder that records the desktop, a window or selection and encodes it into a video file.
The recorded video file is encoded in one of the supported formats, gif, webm, mp4 or mkv based on the file extension given in [FILENAME].
When omitting [FILENAME], the default format "gif" is used (use --format to overwrite), and the resulting video directly printed to standard output.
OPTIONS
-h, --help Print help and exit.
--version Print version and exit.
-v*, --verbose, --quiet Set the verbosity.
-s, --select Enable slop selection.
-g, --geometry=STRING Record rectangle by geometry. (like 100x300+0+0)
-w, --window=INT Record window by id.
-d, --delay=INT Time in seconds before the recording starts.
-t, --timer=TIMEDURATION Time of the recording. (e.g. 10 for 10 seconds or 1:30 for 1 minute 30 seconds)
-f, --framerate=INT Set the framerate.
--format Set the wanted output format. This overwrites the autodetection.
-a, --audio Enable audio recording.
-as, --audio-source=STRING Overwrite the default audio source.
-m, --microphone Enable microphone recording.
-ms, --microphone-source=STRING Overwrite the default microphone source.
-y, --notify Send notification on error or success.
--stop Finish any running giph recordings.
SLOP OPTIONS
-b, --bordersize=FLOAT Set the selection border thickness.
-p, --padding=FLOAT Set the selection padding.
-to, --tolerance=FLOAT Set how far the mouse can move after clicking before recrangle draws.
-c, --color=FLOAT,FLOAT,FLOAT,FLOAT Set the selection color.
-r, --shader=STRING Set the shader to be used.
-n, --nodecorations=INT Set how aggresively decorations should be avoided.
-l, --highlight Highlight the selection rectangle.
-k, --nokeyboard Disable cancel through keypress.
-o, --noopengl Disable graphics acceleration.
EOF
exit 0
}
# log a message - (message:string, verbosity:int, timestamp:bool, stop_execution:bool, no_trailing_newline:bool)
function log() {
[ "${2:-1}" -gt "$VERBOSITY" ] && return 0
log=(echo -e)
[ "$5" = true ] && log+=(-n)
[ "$3" = true ] && log+=("\033[0;37m$(date '+%Y-%m-%d %H:%M:%S'):\033[0m")
log+=("$1")
"${log[@]}"
[ "$4" = true ] && exit 1
}
function log_error() {
notify "$1" "critical"
log "\033[0;31mERROR:\033[0m $1" -1 "${2:-true}" true
}
function log_warning() {
log "\033[0;33mWARNING:\033[0m $1" 0 "${2:-true}"
}
function log_success() {
notify "$1" "normal"
log "\033[0;32mSUCCESS:\033[0m $1" 0 "${2:-true}"
}
function log_info() {
log "\033[0;36mINFO:\033[0m $1" 0 "${2:-true}"
}
function notify() {
[ "$NOTIFY" = 1 ] && {
notify=(notify-send -t 3000)
notify+=(-u "$2")
notify+=("giph" "$1")
"${notify[@]}"
}
}
if [ -z "$1" ]; then
print_help
fi
# flag handling
while [[ "$1" == -* ]]; do
case "$1" in
-h|--help)
print_help
;;
--version)
print_version
;;
-v*)
(( VERBOSITY += ${#1} - 1 ))
;;
--verbose)
(( VERBOSITY++ ))
;;
--quiet)
VERBOSITY=-1
;;
--stop)
SHOULD_STOP=true
;;
-s|--select)
SLOP=1
;;
-g|--geometry)
shift
GEOMETRY="$1"
;;
-w|--window)
shift
WINDOW="$1"
;;
-d|--delay)
shift
DELAY="$1"
;;
-t|--timer)
shift
TIMER="$1"
;;
-f|--framerate)
shift
FRAMERATE="$1"
;;
--format)
shift
FORMAT_OVERWRITE="$1"
;;
-a|--audio)
AUDIO=1
;;
-as|--audio-source)
shift
AUDIO=1
AUDIO_SOURCE="$1"
;;
-m|--microphone)
MICROPHONE=1
;;
-ms|--microphone-source)
shift
MICROPHONE=1
MICROPHONE_SOURCE="$1"
;;
-y|--notify)
NOTIFY=1
;;
-b|--bordersize)
shift
SLOP_BORDERSIZE="$1"
;;
-p|--padding)
shift
SLOP_PADDING="$1"
;;
-to|--tolerance)
shift
SLOP_TOLERANCE="$1"
;;
-c|--color)
shift
SLOP_COLOR="$1"
;;
-r|--shader)
shift
SLOP_SHADER="$1"
;;
-n|--nodecorations)
shift
SLOP_NODECORATIONS="$1"
;;
-l|--highlight)
SLOP_HIGHLIGHT=true
;;
-k|--nokeyboard)
SLOP_NOKEYBOARD=true
;;
-o|--noopengl)
SLOP_NOOPENGL=true
;;
-*)
log_error "option '$1' does not exist" false
;;
esac
shift
done
# set verbosity to -1 if the file should be printed to stdout
[ -n "$1" ] && OUTPUT_FILE="$1" || VERBOSITY=-1
case "$OUTPUT_FILE" in
*.webm) FORMAT="webm" ;;
*.mp4) FORMAT="mp4" ;;
*.mkv) FORMAT="mkv" ;;
*) FORMAT="gif" ;;
esac
if [ -n "$FORMAT_OVERWRITE" ]; then
case "$FORMAT_OVERWRITE" in
webm|mp4|mkv|gif) FORMAT="$FORMAT_OVERWRITE";;
*) log_error "'$FORMAT_OVERWRITE' is not a supported format."
esac
fi
function get_geometry() {
if [ "$SLOP" = 1 ]; then
log "using slop to determine recording geometry" 1 true
get_geometry_from_slop
elif [ -n "$GEOMETRY" ]; then
log "using provided geometry string" 1 true
get_geometry_from_string
elif [ -n "$WINDOW" ]; then
log "determining geometry from provided window id" 1 true
get_geometry_from_window_id "$WINDOW"
else
log_warning "no method to provide geometry given, using full desktop geometry instead"
log "determining desktop geometry" 1 true
get_geometry_for_desktop
fi
log "geometry string: '$GEOMETRY_STRING'" 2 true
parse_geometry_string
}
function get_geometry_from_slop() {
slop=(slop -f "%g")
[ -n "$SLOP_BORDERSIZE" ] && slop+=(-b "$SLOP_BORDERSIZE")
[ -n "$SLOP_PADDING" ] && slop+=(-p "$SLOP_PADDING")
[ -n "$SLOP_TOLERANCE" ] && slop+=(-t "$SLOP_TOLERANCE")
[ -n "$SLOP_COLOR" ] && slop+=(-c "$SLOP_COLOR")
[ -n "$SLOP_SHADER" ] && slop+=(-r "$SLOP_SHADER")
[ -n "$SLOP_NODECORATIONS" ] && slop+=(-n "$SLOP_NODECORATIONS")
[ -n "$SLOP_HIGHLIGHT" ] && slop+=(-l)
[ -n "$SLOP_NOKEYBOARD" ] && slop+=(-k)
[ -n "$SLOP_NOOPENGL" ] && slop+=(-o)
[ "$VERBOSITY" -lt "3" ] && slop+=(-q)
slop_command="${slop[*]}"
log "slop command: '$slop_command'" 2 true
slop_value="$($slop_command)"
[ "$?" -eq 1 ] && log_error "slop selection got canceled"
GEOMETRY_STRING="$slop_value"
}
function get_geometry_from_string() {
GEOMETRY_STRING="$GEOMETRY"
}
function get_geometry_from_window_id() {
xdotool_output="$(xdotool getwindowgeometry --shell "$1" 2> /dev/null)"
[ "$?" = 1 ] && log_error "window with id $1 does not exist"
WIDTH=0
HEIGHT=0
eval "$xdotool_output"
[[ "$X" != "-"* ]] && X="+$X"
[[ "$Y" != "-"* ]] && Y="+$Y"
GEOMETRY_STRING="${WIDTH}x${HEIGHT}${X}${Y}"
}
function get_geometry_for_desktop() {
root_window_id="$(xdotool search --maxdepth 0 --class '')"
get_geometry_from_window_id "$root_window_id"
}
function parse_geometry_string() {
[[ "$GEOMETRY_STRING" =~ ([0-9]+)x([0-9]+)[+]?([-]?[0-9]+)[+]?([-]?[0-9]+) ]]
width="${BASH_REMATCH[1]}"
height="${BASH_REMATCH[2]}"
x="${BASH_REMATCH[3]}"
y="${BASH_REMATCH[4]}"
[ -z "$width" ] || [ -z "$height" ] || [ -z "$x" ] || [ -z "$y" ] && {
log_error "could not parse geometry string '$GEOMETRY_STRING'"
}
get_geometry_for_desktop
[ "$x" -gt "$WIDTH" ] || [ "$((x + width))" -lt 0 ] || [ "$y" -gt "$HEIGHT" ] || [ "$((y + height))" -lt 0 ] && {
log_error "the area to record is fully outside of the root window"
}
[ "$x" -lt 0 ] && {
width="$((width + x))"
x="0"
}
[ "$y" -lt 0 ] && {
height="$((height + y))"
y="0"
}
[ "$((x+width))" -gt "$WIDTH" ] && {
((width-="$((x + width - WIDTH))"))
}
[ "$((y+height))" -gt "$HEIGHT" ] && {
((height-="$((y + height - HEIGHT))"))
}
log "parsed geometry: width=$width, height=$height, x=$x, y=$y" 2 true
}
function create_temporary_directory() {
TEMP_DIRECTORY="$(mktemp -d)"
[ "$?" = 1 ] && log_error "could not create temporary directory"
log "created temporary directory $TEMP_DIRECTORY" 2 true
}
function record() {
ffmpeg=(ffmpeg -f x11grab -s "$width"x"$height" -i "$DISPLAY+$x,$y")
if [ "$FORMAT" != "gif" ]; then
[ "$AUDIO" = 1 ] && ffmpeg+=(-f pulse -i "$AUDIO_SOURCE")
[ "$MICROPHONE" = 1 ] && ffmpeg+=(-f pulse -i "$MICROPHONE_SOURCE")
[ "$AUDIO" = 1 ] && [ "$MICROPHONE" = 1 ] && ffmpeg+=(-filter_complex amerge -ac 2)
fi
ffmpeg+=(-vf "crop=trunc(iw/2)*2:trunc(ih/2)*2")
[ "$VERBOSITY" -lt "3" ] && ffmpeg+=(-loglevel "quiet")
[ -n "$TIMER" ] && [ "$TIMER" -gt 0 ] && ffmpeg+=(-t "$TIMER")
ffmpeg+=(-r "$FRAMERATE")
case "$FORMAT" in
mp4|mkv)
ffmpeg+=(-pix_fmt yuv420p)
ffmpeg+=(-crf 15)
ffmpeg+=("$TEMP_DIRECTORY/final.$FORMAT")
;;
gif|webm|*)
ffmpeg+=(-preset veryslow)
ffmpeg+=(-crf 0)
ffmpeg+=("$TEMP_DIRECTORY/lossless.mp4")
;;
esac
[ -n "$DELAY" ] && [ "$DELAY" -gt 0 ] && countdown_cli "$DELAY" "recording starts in"
ffmpeg_command="${ffmpeg[*]}"
log "ffmpeg command: '$ffmpeg_command'" 2 true
"${ffmpeg[@]}" &
FFMPEG_PID="$!"
log "started recording video with ffmpeg" 1 true
if [ -n "$TIMER" ] && [ "$TIMER" -gt 0 ]; then
countdown_cli "$TIMER" "recording stops in"
else
stop_recording_handler_cli
fi
wait "$FFMPEG_PID"
[ "$?" = 1 ] && log_error "recording video with ffmpeg failed"
log "completed ffmpeg video recording" 1 true
}
function countdown_cli() {
seconds="$1"
while [ "$seconds" -ge 0 ]; do
log "\r\033[K\033[0;36m$2:\033[0m $seconds" 0 false false true
if [ "$seconds" -gt 0 ]; then
sleep 1
else
log "\r\033[K" 0 false false true
fi
: "$((seconds--))"
done
}
function stop_recording_handler_cli() {
log_info "stop recording with \033[1;36mctrl+c\033[0m or call \033[1;36mgiph --stop\033[0m"
trap '' INT
}
function encode() {
log "encoding $FORMAT using ffmpeg" 1 true
ffmpeg_encode=(ffmpeg -i "$TEMP_DIRECTORY/lossless.mp4")
case "$FORMAT" in
"gif")
ffmpeg_encode+=(-vf "split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse")
;;
"webm")
ffmpeg_encode+=(-c:v libvpx-vp9)
;;
esac
[ "$VERBOSITY" -lt "3" ] && ffmpeg_encode+=(-loglevel "quiet")
ffmpeg_encode+=("$TEMP_DIRECTORY/final.$FORMAT")
ffmpeg_encode_command="${ffmpeg_encode[*]}"
log "ffmpeg encode command: '$ffmpeg_encode_command'" 2 true
"${ffmpeg_encode[@]}"
[ "$?" = 1 ] && log_error "could not encode $FORMAT from lossless recording"
}
function deliver() {
if [ -n "$OUTPUT_FILE" ]; then
mv "$1" "$OUTPUT_FILE" && {
log_success "final $FORMAT saved as \"$OUTPUT_FILE\""
}
else
cat "$1"
fi
}
function delete_temporary_directory() {
rm -r "$TEMP_DIRECTORY"
[ "$?" = 1 ] && log_error "could not delete temporary directory"
log "deleted temporary directory $TEMP_DIRECTORY" 2 true
}
function giph() {
get_geometry
create_temporary_directory
record
if [[ "$FORMAT" == "gif" || "$FORMAT" == "webm" ]]; then
encode
fi
deliver "$TEMP_DIRECTORY/final.$FORMAT"
delete_temporary_directory
exit 0
}
function stop_all_recordings() {
for pid in "$(pgrep -f "bash.+giph")"; do
kill -INT -$pid
done
}
if [ -n "$SHOULD_STOP" ]; then
stop_all_recordings
else
giph
fi
wait
gitextract_icb2cw67/
├── LICENSE
├── Makefile
├── README.md
├── man/
│ └── giph.1
└── src/
└── giph
Condensed preview — 5 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (24K chars).
[
{
"path": "LICENSE",
"chars": 1075,
"preview": "MIT License\n\nCopyright (c) 2019 Philipp Schaffrath\n\nPermission is hereby granted, free of charge, to any person obtainin"
},
{
"path": "Makefile",
"chars": 528,
"preview": "PREFIX ?= /usr/local\nDESTDIR ?=\nBINDIR ?= $(PREFIX)/bin\nMANDIR ?= $(PREFIX)/share/man\n\nall:\n\t@echo \"Nothing to do, try \\"
},
{
"path": "README.md",
"chars": 2921,
"preview": "# giph\ngiph is a screen recorder that records the desktop, a window or selection and encodes it into a gif file. It prin"
},
{
"path": "man/giph.1",
"chars": 5739,
"preview": ".TH GIPH 1 \"April 2019\" \"MIT License\" \"User Commands\"\n.SH NAME\ngiph \\- record gif from desktop, window or selection\n.SH "
},
{
"path": "src/giph",
"chars": 11908,
"preview": "#!/usr/bin/env bash\n\nstty -echoctl # don't print ^C when pressing ctrl+c\n\nreadonly VERSION=1.1.1\n\n# verbosity\nVERBOSITY="
}
]
About this extraction
This page contains the full source code of the phisch/giph GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 5 files (21.7 KB), approximately 7.1k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.