Last active
January 19, 2021 23:43
-
-
Save ismith/d1b080c18e2de6d19075e6d02cd84291 to your computer and use it in GitHub Desktop.
Dark's caption embedding script
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
#!/usr/bin/env bash | |
set -euo pipefail | |
if [ $# -eq 0 ]; then | |
echo "This script takes two mandatory options - \$1 is the input video, \$2 is the | |
input subtitles." | |
echo | |
echo "By default, we burn in hard subs; you may use --soft-subs to embed soft | |
subs. See: https://en.wikipedia.org/wiki/Subtitle_(captioning)#Types" | |
# Note: mkv would allow default subs on (`-disposition:s:s:0 forced`), but mkv | |
# doesn't work out of box in Quicktime | |
exit 0 | |
fi | |
############################### | |
# verify correct getopt version | |
# | |
# this assumes you're using gnu's getopt, which is not the same as osx' default | |
# getopt | |
############################### | |
# If we've got brew installed, use its gnu-getopt | |
if [ -x "$(command -v brew)" ]; then | |
if ( ! brew list gnu-getopt ); then | |
echo "You need to install gnu-getopt:" | |
echo " brew install gnu-getopt" | |
exit 1 | |
fi | |
brew_prefix=$(brew --prefix gnu-getopt) | |
export PATH=${brew_prefix}/bin:$PATH | |
fi | |
set +e | |
opt=$(getopt -T) | |
set -e | |
# 4 is the return code from gnu's `getopt -T`, and the -n $opt checks that its | |
# stdout is empty, not '--' (it will be '--' if using the non-gnu osx getopt | |
if (( $? != 4 )) && [[ -n $opt ]]; then | |
echo "Either no getopt is installed, or you're using a non-gnu getopt." | |
echo "If you're on OS X, you can install gnu-getopt using homebrew to fix | |
this." | |
exit 1 | |
fi | |
############################## | |
# end verifying correct getopt | |
############################## | |
OPTS=$(getopt --options s --longoptions soft-subs "$@") | |
eval set -- "$OPTS" | |
SOFTSUBS=0 | |
while true ; do | |
case "$1" in | |
--soft-subs|-s) | |
SOFTSUBS=1 | |
shift | |
;; | |
--) | |
shift | |
break | |
;; | |
*) | |
echo "Unknown option: $1" | |
exit 1 | |
;; | |
esac | |
done | |
INVIDEO=$1 | |
INSUBS=$2 | |
CCOVERLAY=$(dirname "$0")/cc.png | |
if ( ! command -v ffmpeg ); then | |
echo "This script depends on ffmpeg." | |
exit 1 | |
fi | |
if [[ "$INVIDEO" == "" ]]; then | |
echo "No in video (foo.mp4?) provided." | |
echo | |
exit 1 | |
fi | |
if ! [[ "$INSUBS" =~ .srt$ ]]; then | |
echo "No subtitles provided." | |
echo | |
echo "Debug: options given: INVIDEO: ${INVIDEO}, INSUBS: ${INSUBS}" | |
exit 1 | |
fi | |
if (( "$SOFTSUBS" )); then | |
# if this file needs scaling at some point, use imagemagick: | |
# convert cc.png -resize 120x120 cc.png | |
if [[ ! -f $CCOVERLAY ]]; then | |
echo "No ccoverlay image found." | |
exit 1 | |
fi | |
fi | |
tmpfile=$(mktemp /tmp/postprocess-video.XXXXXX.mp4) | |
rm "$tmpfile" # so ffmpeg doesn't ask if you want to overwrite it | |
set -x | |
if (( "$SOFTSUBS" )); then | |
# Add CCOVERLAY watermark in bottom right corner | |
ffmpeg -i "$INVIDEO" \ | |
-vf "movie=${CCOVERLAY} [watermark]; [in][watermark] overlay=(main_w-overlay_w-10):(main_h-overlay_h-10) [out]" \ | |
"$tmpfile" | |
else | |
ffmpeg -i "$INVIDEO" -vf subtitles="$INSUBS" "$tmpfile" | |
fi | |
ffmpeg -i "$tmpfile" -f srt -i "$INSUBS" \ | |
-c:v copy -c:a copy -c:s mov_text \ | |
-metadata:s:s:0 language=English \ | |
out.mp4 | |
# could put this in a signal handler if you wanted to be really sure it gets | |
# cleaned up | |
rm "$tmpfile" | |
if (( "$SOFTSUBS" )); then | |
echo "Done, with soft subs! See out.mp4" | |
else | |
echo "Done, with hard and soft subs! See out.mp4" | |
fi |
If you are receiving the wrong outputs for $1 and $2 (check using echo) chances are it is an issue with getopt.
- Install gnu-getopt via homebrew (brew install gnu-getopt).
- Run with this prefix: PATH=/usr/local/opt/gnu-getopt/bin:$PATH ./embed-captions.sh video.mp4 subs.srt
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you are not a regular bash user, this is the format for the CLI:
./captioning.sh video.mp4 subs.srt