summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Smith <luke@lukesmith.xyz>2020-11-11 17:03:55 -0500
committerLuke Smith <luke@lukesmith.xyz>2020-11-11 17:03:55 -0500
commitaea27f3f2bcebaffdd6db6b74e9ad0aecd91a54b (patch)
tree10cdf4e0426aec6c37ff346fe84e01cc6eaa1297
parentbe8ff717b176d281e954329c3dfdb1f508531e25 (diff)
downloadeibhear-aea27f3f2bcebaffdd6db6b74e9ad0aecd91a54b.tar.gz
eibhear-aea27f3f2bcebaffdd6db6b74e9ad0aecd91a54b.tar.zst
eibhear-aea27f3f2bcebaffdd6db6b74e9ad0aecd91a54b.zip
slider now takes text and has many nice options
-rwxr-xr-x.local/bin/slider103
1 files changed, 79 insertions, 24 deletions
diff --git a/.local/bin/slider b/.local/bin/slider
index 0fa6f88..950b496 100755
--- a/.local/bin/slider
+++ b/.local/bin/slider
@@ -6,26 +6,76 @@
#
# Imagemagick and ffmpeg required.
-# TODO:
-# - add the ability to include text, using imagemagick text to image feature.
+# Application cache if not stated elsewhere.
+cache="${XDG_CACHE_HOME:-$HOME/.cache}/slider"
+while getopts "hvrpi:c:a:o:d:f:t:e:x:" o; do case "${o}" in
+ c) bgc="$OPTARG" ;;
+ t) fgc="$OPTARG" ;;
+ i) file="$OPTARG" ;;
+ a) audio="$OPTARG" ;;
+ o) outfile="$OPTARG" ;;
+ d) prepdir="$OPTARG" ;;
+ r) redo="$OPTARG" ;;
+ s) ppt="$OPTARG" ;;
+ e) endtime="$OPTARG" ;;
+ x) res="$OPTARG"
+ echo "$res" | grep -qv "^[0-9]\+x[0-9]\+$" &&
+ echo "Resolution must be dimensions separated by a 'x': 1280x720, etc." &&
+ exit 1 ;;
+ p) echo "Purge old build files in $cache? [y/N]"
+ read -r confirm
+ echo "$confirm" | grep -iq "^y$" && rm -rf "$cache" && echo "Done."
+ exit ;;
+ v) verbose=True ;;
+ *) echo "$(basename "$0") usage:
+ -i input timecode list (required)
+ -a audio file
+ -c color of background (use html names, black is default)
+ -t text color for text slides (white is default)
+ -s text font size for text slides (150 is default)
+ -o output video file
+ -e if no audio given, the time in seconds that the last slide will be shown (5 is default)
+ -x resolution (1920x1080 is default)
+ -d tmp directory
+ -r rerun imagemagick commands even if done previously (in case files or background has changed)
+ -p purge old build files instead of running
+ -v be verbose" && exit 1
-[ -z "$1" ] && echo "Usage:
- first arg: file with timecodes
- second arg: audio file (optional)" && exit 1
+esac done
-prepdir="$1-src"
-prepfile="$prepdir/$1.prep"
-outfile="$1.mp4"
+# Check that the input file looks like it should.
+{ head -n 1 "$file" 2>/dev/null | grep -q "^00:00:00 " ;} || {
+ echo "Give an input file with -i." &&
+ echo "The file should look as this example:
-totaldur="$(ffmpeg -i "$2" 2>&1 | awk '/Duration/ {print $2}' | sed s/,//)"
-totseconds="$(date '+%s' -d "$totaldur")"
+00:00:00 first_image.jpg
+00:00:03 otherdirectory/next_image.jpg
+00:00:09 this_image_starts_at_9_seconds.jpg
+etc...
+Timecodes and filenames must be separated by Tabs." &&
+ exit 1
+ }
+
+if [ -n "${audio+x}" ]; then
+ # Check that the audio file looks like an actual audio file.
+ case "$(file --dereference --brief --mime-type -- "$audio")" in
+ audio/*) ;;
+ *) echo "That doesn't look like an audio file."; exit 1 ;;
+ esac
+ totseconds="$(date '+%s' -d $(ffmpeg -i "$audio" 2>&1 | awk '/Duration/ {print $2}' | sed s/,//))"
+ endtime="$((totseconds-seconds))"
+fi
+
+prepdir="${prepdir:-$cache/$file}"
+outfile="${outfile:-$file.mp4}"
+prepfile="$prepdir/$file.prep"
+
+[ -n "${verbose+x}" ] && echo "Preparing images... May take a while depending on the number of files."
mkdir -p "$prepdir"
-echo "Preparing images... May take a while depending on the number of files."
{
-
while read -r x;
do
# Get the time from the first column.
@@ -34,14 +84,20 @@ do
# Duration is not used on the first looped item.
duration="$((seconds - prevseconds))"
- # Get the filename from the rest.
- filename="${x#* }"
- base="$(basename "$filename")"
+ # Get the filename/text content from the rest.
+ content="${x#* }"
+ base="$(basename "$content")"
base="${base%.*}.jpg"
- # Resize and read the image file, but not if already done.
- [ ! -f "$prepdir/$base" ] &&
- convert -size 1920x1080 canvas:black -gravity center "$filename" -resize 1920x1080 -composite "$prepdir/$base"
+ if [ -f "$content" ]; then
+ # If images have already been made in a previous run, do not recreate
+ # them unless -r was given.
+ { [ ! -f "$prepdir/$base" ] || [ -n "${redo+x}" ] ;} &&
+ convert -size "${res:-1920x1080}" canvas:"${bgc:-black}" -gravity center "$content" -resize 1920x1080 -composite "$prepdir/$base"
+ else
+ { [ ! -f "$prepdir/$base" ] || [ -n "${redo+x}" ] ;} &&
+ convert -size "${res:-1920x1080}" -background "${bgc-black}" -fill "${fgc:-white}" -pointsize "${ppt:-150}" -gravity center label:"$content" "$prepdir/$base"
+ fi
# If the first line, do not write yet.
[ "$time" = "00:00:00" ] || echo "file '$prevbase'
@@ -51,17 +107,16 @@ duration $duration"
prevbase="$base"
prevtime="$time"
prevseconds="$(date '+%s' -d "$prevtime")"
-done < "$1"
+done < "$file"
# Do last file which must be given twice as follows
echo "file '$base'
-duration $((totseconds-seconds))
+duration ${endtime:-5}
file '$base'"
} > "$prepfile"
-
-if [ -f "$2" ]; then
- ffmpeg -y -f concat -safe 0 -i "$prepfile" -i "$2" -c:a aac -vsync vfr -c:v libx264 -pix_fmt yuv420p "$outfile"
+if [ -n "${audio+x}" ]; then
+ ffmpeg -hide_banner -y -f concat -safe 0 -i "$prepfile" -i "$audio" -c:a aac -vsync vfr -c:v libx264 -pix_fmt yuv420p "$outfile"
else
- ffmpeg -y -f concat -safe 0 -i "$prepfile" -vsync vfr -c:v libx264 -pix_fmt yuv420p "$outfile"
+ ffmpeg -hide_banner -y -f concat -safe 0 -i "$prepfile" -vsync vfr -c:v libx264 -pix_fmt yuv420p "$outfile"
fi
# Might also try: