Damien Broqua
0d384b22bf
Added some ignored folders and files Updated waybar clock for Debian 11 Fixed bug on screen definition Fixed Iiyama North America PL2483H 1173700204528 Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway Some changes for work environment Some changes for work environment Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway Added .mp3 files Updated waybar config for laptop Added vim-jsx Added Teams to startup section (sad day in life!) Updated mpd config (local source) Added script for syncing my music Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway Updated ranger config Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway Replaced termite with alacritty Replaced termite by alacritty Updated rsync.sh results Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway Updated github user Updated irc alias Minor changes Added master if fail fait dev* Added zsh prompt Updated output definitions Added KDEConnect at startup Added second screen Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway Updated README Added C.A.V.A. Fixed bug for vte Added Tofu HHKB keyboard config Added script to update system Updated FuzzFm entry Added menu entry for Carnet Added qcad's ebuild Updated waybar for Thinkpad Updated temperature list for Thinkpad Fixed bug Updated input for thinkpad Added script to order files for Alpine car audio system Updated Fuzz url Added Grammalecte plugin Added displays for ThinkStation and ThinkPad Merge branch 'gentoo-sway' of framagit.org:dbroqua/home into gentoo-sway Updated waybar for laptop Fixed bug on adjust brightness Moved applications Co-authored-by: dbroqua <contact@darkou.fr> Co-authored-by: dbroqua <dbroqua@mousur.org> Reviewed-on: #1 Co-Authored-By: Damien Broqua <dbroqua@noreply.localhost> Co-Committed-By: Damien Broqua <dbroqua@noreply.localhost>
354 lines
11 KiB
Bash
Executable file
354 lines
11 KiB
Bash
Executable file
#! /bin/bash
|
|
|
|
set -eo pipefail
|
|
|
|
VERSION="2.0.4"
|
|
|
|
# Sane defaults in case of not being set in the config / config not existing.
|
|
CREDENTIALS_FILE="$HOME/.config/slip/credentials"
|
|
RECORD_PIDFILE="/tmp/slip_record.pid"
|
|
IMAGES="$HOME/Pictures"
|
|
VIDEOS="$HOME/Videos"
|
|
GIF_SCALE="640"
|
|
GIF_FPS=15
|
|
SOUND=0
|
|
NOUPLOAD=0
|
|
|
|
DMENU_CMD="rofi -dmenu -p slip"
|
|
|
|
# Load config.
|
|
CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/slip/config"
|
|
if [ -f $CONFIG ]; then
|
|
source $CONFIG
|
|
else
|
|
echo "No config was found - using default options. Please copy the example configuration to ~/.config/slip/config from https://github.com/Toqozz/slip"
|
|
fi
|
|
|
|
CLIENT_ID="abd3a90bbfb65e9"
|
|
|
|
# Dmenu prompts.
|
|
DMENU_OPTS="screenshot
|
|
video
|
|
gif
|
|
exit"
|
|
DMENU_RECORD_OPTS="stop
|
|
cancel"
|
|
DMENU_UPLOAD_OPTS_BIG="upload (gfycat)
|
|
delete
|
|
exit"
|
|
DMENU_UPLOAD_OPTS="upload (imgur)
|
|
upload (gfycat)
|
|
delete
|
|
exit"
|
|
|
|
# Maximum size for upload (kb).
|
|
# Gfycat does not have a file limit.
|
|
MAX_GIF_SIZE_IMGUR=10000
|
|
|
|
function usage() {
|
|
echo ""
|
|
echo " slip [ -h | -v | -s | -r | -a | -q ] -nu"
|
|
echo " Uploads images taken with ffmpeg via slop to imgur. Quick video recording."
|
|
echo " That's all."
|
|
echo ""
|
|
echo " -h | --help show this help"
|
|
echo " -v | --version show version"
|
|
echo " -s | --screenshot take a screenshot (skip dmenu)"
|
|
echo " -g | --gif take a gif (skip dmenu)"
|
|
echo " -r | --record take a video (skip dmenu)"
|
|
echo " -nu | --no-upload don't upload the result"
|
|
echo " -q | --stop stop recording a video / gif (skip dmenu) (only when recording)"
|
|
echo ""
|
|
}
|
|
|
|
function upload_imgur() {
|
|
file="$1"
|
|
|
|
if [ -f "$file" ]; then
|
|
if [ -f "$CREDENTIALS_FILE" ]; then
|
|
# We have an auth token to use.
|
|
check_auth_credentials
|
|
if [ $? -ne 1 ]; then
|
|
# Token valid.
|
|
curl -sH "Authorization: Bearer ${access_token}" -F "image=@$file" "https://api.imgur.com/3/upload"
|
|
fi
|
|
else
|
|
# Imgur needs to know what program is using its services.
|
|
curl -sH "Authorization: Client-ID ${CLIENT_ID}" -F "image=@$file" "https://api.imgur.com/3/upload"
|
|
fi
|
|
else
|
|
echo "File does not exist, what happened?"
|
|
fi
|
|
}
|
|
|
|
function upload_gfycat() {
|
|
local file="$1"
|
|
|
|
local result=$(curl -s -XPOST https://api.gfycat.com/v1/gfycats -H "Content-Type: application/json")
|
|
local gfyname=$(parse "gfycat" $result)
|
|
curl -s "https://filedrop.gfycat.com/$gfyname" --upload-file "$file"
|
|
|
|
# No new line so we can append it easily.
|
|
echo -n "$gfyname"
|
|
}
|
|
|
|
function check_auth_credentials() {
|
|
token_expire_time=0
|
|
if [ -f "${CREDENTIALS_FILE}" ]; then
|
|
source "${CREDENTIALS_FILE}"
|
|
fi
|
|
|
|
if [ ! -z ${access_token} ]; then
|
|
current_time="$(date +%s)"
|
|
preemptive_refresh_time="$((10*60))"
|
|
expired="$((current_time > (token_expire_time - preemptive_refresh_time)))"
|
|
|
|
if [ "${expired}" -eq "0" ]; then
|
|
#token has expired, get a new one.
|
|
echo 'The authorization token has expired, please get a new one.'
|
|
return 1;
|
|
fi
|
|
else
|
|
return 1;
|
|
fi
|
|
}
|
|
|
|
function clip_clear() {
|
|
# Clear x cliboard selection.
|
|
xsel -bc # Ctrl-v / Shift-Insert.
|
|
# xsel -pc # Middle click.
|
|
}
|
|
|
|
# Run slop and get the geometry line.
|
|
function slop_geom() {
|
|
if [ "$1" = "image" ]; then
|
|
slop -f '%wx%h+%x+%y'
|
|
else
|
|
slop -f '%wx%h|%x,%y' # | sed -e s/+/\|/ -e s/+/,/
|
|
fi
|
|
#elif [ "$1" = "video" ]; then
|
|
#slop -f '%wx%h+%x+%y' | sed -e s/+/\|/ -e s/+/,/
|
|
#slop | sed -n 5p | sed -e s/G=// -e s/+/\|/ -e s/+/,/
|
|
#elif [ "$1" = "gif" ]; then
|
|
#slop -f '%wx%h+%x+%y' | sed -e s/+/\|/ -e s/+/,/
|
|
}
|
|
|
|
# Take the shot (or start the video.)
|
|
function shot() {
|
|
if [ "$1" = "image" ]; then
|
|
extension=".png" # img-2016-04-16-153906.png
|
|
filename="$IMAGES/img-`date +%Y-%m-%d-%H%M%S`$extension" # .png, .jpg
|
|
maim -g "$2" $filename
|
|
# TODO, do we want more dependencies? (optional dependencies?)
|
|
#ffmpeg -f x11grab -video_size "$2" -i "$DISPLAY+$3" -vframes 1 $filename &> /dev/null
|
|
elif [ "$1" = "video" ]; then
|
|
extension=".mkv" # vid-2016-04-16-153906.mkv
|
|
filename="$VIDEOS/vid-`date +%Y-%m-%d-%H%M%S`$extension" # .mkv, .mp4
|
|
if [ $SOUND == 0 ]; then
|
|
ffmpeg -f x11grab -video_size "$2" -framerate 60 -i "$DISPLAY+$3" -loglevel quiet -c:v libx264 -preset ultrafast $filename &
|
|
else
|
|
ffmpeg -f pulse -i 1 -f x11grab -video_size "$2" -framerate 60 -i "$DISPLAY+$3" -loglevel quiet -c:v libx264 -preset ultrafast $filename &
|
|
fi
|
|
echo "$! vid $filename" > "$RECORD_PIDFILE"
|
|
elif [ "$1" = "gif" ]; then
|
|
extension=".gif" # gif-2016-04-16-153906.gif
|
|
tmpfilename="/tmp/gif-`date +%Y-%m-%d-%H%M%S-tmp`.mkv"
|
|
filename="$VIDEOS/gif-`date +%Y-%m-%d-%H%M%S`$extension" # .gif
|
|
# Record a video to be converted to gif.
|
|
ffmpeg -f x11grab -video_size "$2" -framerate $GIF_FPS -i "$DISPLAY+$3" -loglevel quiet -c:v libx264 -preset ultrafast $tmpfilename &
|
|
#ffmpeg -f x11grab -video_size "$2" -framerate 15 -i "$DISPLAY+$3" -vf scale="$GIF_SCALE:-1" $filename &> /dev/null &
|
|
|
|
# We need to access this information later.
|
|
ratio=$(awk -F"x" '{ print int($1/$2) }' <<< "$2") # We only really need a binary answer.
|
|
if [ "$ratio" -ge 1 ]; then echo "$! gif $tmpfilename $filename 0" > "$RECORD_PIDFILE"
|
|
else echo "$! gif $tmpfilename $filename 1" > "$RECORD_PIDFILE"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function kill_ffmpeg() {
|
|
# Kill ffmpeg (stopping the recording.)
|
|
kill $1 || echo "Failed to kill ffmpeg, did it crash? Removing $RECORD_PIDFILE anyway."
|
|
# Remove the pid file so that slip can be used as normal again.
|
|
rm "$RECORD_PIDFILE"
|
|
}
|
|
|
|
function convert_to_gif() {
|
|
local tfn=$1
|
|
local pfn=$2
|
|
local fn=$3
|
|
local wh=$4 # 0 = width larger than height, 1 = height larger than width
|
|
|
|
local ratio
|
|
# If the width is larger than the height, we want to scale with the width, otherwise scale with the height.
|
|
if [ $wh -eq 0 ]; then
|
|
ratio="$GIF_SCALE:-1"
|
|
else
|
|
ratio="-1:$GIF_SCALE"
|
|
fi
|
|
|
|
notify "Converting to gif…"
|
|
# Give enough time to save the file.
|
|
sleep 1 && ffmpeg -i "$tfn" -loglevel quiet -vf fps=$GIF_FPS,scale="$ratio":flags=lanczos,palettegen "$pfn" &&
|
|
ffmpeg -i "$tfn" -i "$pfn" -loglevel quiet -filter_complex "fps=$GIF_FPS,scale=$ratio:flags=lanczos[x];[x][1:v]paletteuse" "$fn" &&
|
|
|
|
echo "$fn"
|
|
}
|
|
|
|
function stop_rec() {
|
|
local choice
|
|
|
|
local pid=$1 # Process id (for killing ffmpeg).
|
|
local tfn=$3 # Temp file name (for gifs).
|
|
local fn=$4 # File name for the gif/vid we're saving.
|
|
local pfn="${tfn}-palette.png" # Palette file name (for gif rendering).
|
|
|
|
# Stop recording.
|
|
kill_ffmpeg "$pid"
|
|
|
|
# When processing a gif, we canvert it straight away and then upload.
|
|
# NOTE: gfycat does not require the video to be converted, but we convert it anyway to store
|
|
# the .gif file.
|
|
# Is this actually a good idea? We could just store the .mkv instead, but then we lose the ability to store .gif.
|
|
if [ "$2" = "gif" ]; then
|
|
fn=$(convert_to_gif "$tfn" "$pfn" "$fn" "$5")
|
|
size=$(du -k $fn | cut -f1)
|
|
|
|
if [ $NOUPLOAD == 0 ]; then
|
|
if [ "$size" -lt "${MAX_GIF_SIZE_IMGUR}" ]; then
|
|
choice=$($DMENU_CMD <<< $DMENU_UPLOAD_OPTS)
|
|
else
|
|
choice=$($DMENU_CMD <<< $DMENU_UPLOAD_OPTS_BIG)
|
|
fi
|
|
|
|
if [ "$choice" = "upload (gfycat)" ]; then
|
|
clip_clear
|
|
name=$(upload_gfycat "$tfn")
|
|
url="https://gfycat.com/$name"
|
|
notify "Uploading to $url ..."
|
|
echo "$url"
|
|
echo -n "$url" | xsel -bi # Read to clipboard.
|
|
elif [ "$choice" = "upload (imgur)" ]; then
|
|
clip_clear
|
|
output=$(upload_imgur "$fn")
|
|
url=$(parse "imgur" "$output")
|
|
notify "$url"
|
|
echo "$url"
|
|
echo -n "$url" | xsel -bi # Read to clipboard.
|
|
elif [ "$choice" = "delete" ]; then
|
|
rm $fn
|
|
fi
|
|
fi
|
|
else
|
|
notify "$fn"
|
|
fi
|
|
}
|
|
|
|
# Parse x,y -- but also imgur.
|
|
function parse() {
|
|
if [ "$1" = "geometryx" ]; then
|
|
awk -F"|" '{ print $1 }' <<< "$2"
|
|
elif [ "$1" = "geometry+" ]; then
|
|
awk -F"|" '{ print $2 }' <<< "$2"
|
|
elif [ "$1" = "imgur" ]; then
|
|
jq -r ".data.link" <<< "$2"
|
|
#sed -e 's/.*\"link\":"\([^"]*\).*/\1/' -e 's/\\//g' <<< "$2"
|
|
#sed -e 's/\"link\":"\([^"]*\)/\1/' -e 's/\\//g' <<< "$2"
|
|
elif [ "$1" = "gfycat" ]; then
|
|
jq -r ".gfyname" <<< "$2"
|
|
fi
|
|
}
|
|
|
|
function notify() {
|
|
notify-send -t 7000 "slip" "$1"
|
|
}
|
|
|
|
function main() {
|
|
if [ "$1" = "screenshot" ]; then
|
|
# Run slop and get geometry from it.
|
|
# maim naturally supports slop's output coordinates.
|
|
geometry=$(slop_geom "image")
|
|
# Take the shot.
|
|
shot "image" "$geometry"
|
|
# Parse imgur json into link.
|
|
|
|
# If noupload is not set.
|
|
if [ $NOUPLOAD == 0 ]; then
|
|
#echo "uploading..."
|
|
# Clear cliboard before doing anything, so we can copy link to it later.
|
|
clip_clear
|
|
output=$(upload_imgur "$filename")
|
|
url=$(parse "imgur" "$output")
|
|
# Notify user that upload has finished.
|
|
notify "$url"
|
|
echo "$url"
|
|
# Read to clipboard, removing trailing newline.
|
|
echo -n "$url" | xsel -bi
|
|
else
|
|
notify "$filename"
|
|
fi
|
|
|
|
# echo "$url" | xsel -pi # Read to primary.
|
|
elif [ "$1" = "video" ]; then
|
|
geometry=$(slop_geom "video")
|
|
wxh=$(parse "geometryx" $geometry)
|
|
off=$(parse "geometry+" $geometry)
|
|
shot "video" "$wxh" "$off"
|
|
elif [ "$1" = "gif" ]; then
|
|
geometry=$(slop_geom "gif")
|
|
wxh=$(parse "geometryx" $geometry)
|
|
off=$(parse "geometry+" $geometry)
|
|
shot "gif" "$wxh" "$off"
|
|
elif [ "$1" = "stop" ]; then
|
|
# Get info of recording process.
|
|
local info
|
|
# Get infor from the pidfile.
|
|
info=$(cat "$RECORD_PIDFILE")
|
|
# Stop with parameters ("<pid> <type> <filename> <ratio>")
|
|
stop_rec $info
|
|
exit 0
|
|
else
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# Dependencies.
|
|
depends="curl
|
|
jq
|
|
maim
|
|
slop
|
|
ffmpeg"
|
|
while read line
|
|
do
|
|
if ! type $line &> /dev/null ; then
|
|
echo "$line not found, expect unexpected or breakage."
|
|
fi
|
|
done <<< "$depends"
|
|
|
|
# Main.
|
|
# Yes, we could call this stuff with integers, but this is much clearer.
|
|
if [ "$1" = "-nu" -o "$1" = "--no-upload" -o "$2" = "-nu" -o "$2" = "--no-upload" ]; then
|
|
NOUPLOAD=1
|
|
fi
|
|
|
|
if [ "$1" = "-h" -o "$1" = "--help" ]; then
|
|
usage
|
|
exit 0
|
|
elif [ "$1" = "-v" -o "$1" = "--version" ]; then
|
|
echo "Version: $VERSION"
|
|
exit 0
|
|
elif [ "$1" = "-s" -o "$1" = "--screenshot" ]; then
|
|
main "screenshot"
|
|
elif [ "$1" = "-g" -o "$1" = "--gif" ]; then
|
|
main "gif"
|
|
elif [ "$1" = "-r" -o "$1" = "--record" ]; then
|
|
main "video"
|
|
elif [ "$1" = "-q" -o "$1" = "--stop" ]; then
|
|
main "stop"
|
|
elif [ $# == 0 ]; then
|
|
if [ -a "$RECORD_PIDFILE" ]; then
|
|
main $($DMENU_CMD <<< "$DMENU_RECORD_OPTS")
|
|
else
|
|
main $($DMENU_CMD <<< "$DMENU_OPTS")
|
|
fi
|
|
fi
|