Last active
April 23, 2023 17:29
-
-
Save AlexTMjugador/0b7619b4526de25d4047501fd446212a to your computer and use it in GitHub Desktop.
Shell script to create nice-looking animated Discord stickers. Supports processing several files in parallel.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh -e | |
# Shell script to convert videos to APNG images suitable for use as Discord | |
# stickers. Tools used: | |
# - ffmpeg | |
# - pngquant | |
# - apngasm | |
while getopts r:f:p:m:h option; do | |
case $option in | |
r) # Resolution | |
RESOLUTION="$OPTARG";; | |
f) # FPS | |
FPS="$OPTARG";; | |
p) # Palette size | |
PALETTE_SIZE="$OPTARG";; | |
m) # Duration multiplier (useful for squeezing a bit more content in the 5 second limit) | |
DURATION_MULTIPLIER="$OPTARG";; | |
h|*) # Help | |
echo "Usage: $0 [-r WxH] [-f FPS] [-p PALETTE_SIZE] [-m DURATION_MULTIPLIER]" | |
exit 1;; | |
esac | |
done | |
readonly RESOLUTION="${RESOLUTION:-132x132}" | |
readonly FPS="${FPS:-16}" | |
readonly PALETTE_SIZE="${PALETTE_SIZE:-32}" | |
readonly DURATION_MULTIPLIER="${DURATION_MULTIPLIER:-1}" | |
WORK_DIRECTORY=$(mktemp -d -t discticker.XXX) | |
readonly WORK_DIRECTORY | |
trap 'rm -rf "$WORK_DIRECTORY"' EXIT INT TERM | |
shift $((OPTIND - 1)) | |
for video in "$@"; do | |
{ | |
video_basename="${video##*/}" | |
result_file="${video_basename%.*}.png" | |
mkdir "$WORK_DIRECTORY/$video_basename" | |
ffmpeg -hide_banner -i "$video" \ | |
-filter:v "setpts=$DURATION_MULTIPLIER*PTS,fps=$FPS,trim=duration=4.95" \ | |
-s "$RESOLUTION" \ | |
"$WORK_DIRECTORY/$video_basename/frame%03d.png" | |
pngquant --speed 1 --ext .png --force "$PALETTE_SIZE" -- "$WORK_DIRECTORY/$video_basename"/frame*.png | |
apngasm "$result_file" "$WORK_DIRECTORY/$video_basename"/frame*.png 1 "$FPS" -z2 | |
result_size=$(stat -c%s "$result_file") | |
if [ "$result_size" -ge $((512 * 1024)) ]; then | |
echo "! $result_file exceeds the 512 KiB Discord size limit. Aborting conversion" | |
rm "$result_file" | |
else | |
echo "> Sticker stored at $result_file ($((result_size / 1024)) KiB)" | |
fi | |
} & | |
done | |
wait |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment