slider now takes text and has many nice options
This commit is contained in:
parent
be8ff717b1
commit
aea27f3f2b
1 changed files with 79 additions and 24 deletions
|
@ -6,26 +6,76 @@
|
||||||
#
|
#
|
||||||
# Imagemagick and ffmpeg required.
|
# Imagemagick and ffmpeg required.
|
||||||
|
|
||||||
# TODO:
|
# Application cache if not stated elsewhere.
|
||||||
# - add the ability to include text, using imagemagick text to image feature.
|
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:
|
esac done
|
||||||
first arg: file with timecodes
|
|
||||||
second arg: audio file (optional)" && exit 1
|
|
||||||
|
|
||||||
prepdir="$1-src"
|
# Check that the input file looks like it should.
|
||||||
prepfile="$prepdir/$1.prep"
|
{ head -n 1 "$file" 2>/dev/null | grep -q "^00:00:00 " ;} || {
|
||||||
outfile="$1.mp4"
|
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/,//)"
|
00:00:00 first_image.jpg
|
||||||
totseconds="$(date '+%s' -d "$totaldur")"
|
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"
|
mkdir -p "$prepdir"
|
||||||
|
|
||||||
echo "Preparing images... May take a while depending on the number of files."
|
|
||||||
{
|
{
|
||||||
|
|
||||||
while read -r x;
|
while read -r x;
|
||||||
do
|
do
|
||||||
# Get the time from the first column.
|
# Get the time from the first column.
|
||||||
|
@ -34,14 +84,20 @@ do
|
||||||
# Duration is not used on the first looped item.
|
# Duration is not used on the first looped item.
|
||||||
duration="$((seconds - prevseconds))"
|
duration="$((seconds - prevseconds))"
|
||||||
|
|
||||||
# Get the filename from the rest.
|
# Get the filename/text content from the rest.
|
||||||
filename="${x#* }"
|
content="${x#* }"
|
||||||
base="$(basename "$filename")"
|
base="$(basename "$content")"
|
||||||
base="${base%.*}.jpg"
|
base="${base%.*}.jpg"
|
||||||
|
|
||||||
# Resize and read the image file, but not if already done.
|
if [ -f "$content" ]; then
|
||||||
[ ! -f "$prepdir/$base" ] &&
|
# If images have already been made in a previous run, do not recreate
|
||||||
convert -size 1920x1080 canvas:black -gravity center "$filename" -resize 1920x1080 -composite "$prepdir/$base"
|
# 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.
|
# If the first line, do not write yet.
|
||||||
[ "$time" = "00:00:00" ] || echo "file '$prevbase'
|
[ "$time" = "00:00:00" ] || echo "file '$prevbase'
|
||||||
|
@ -51,17 +107,16 @@ duration $duration"
|
||||||
prevbase="$base"
|
prevbase="$base"
|
||||||
prevtime="$time"
|
prevtime="$time"
|
||||||
prevseconds="$(date '+%s' -d "$prevtime")"
|
prevseconds="$(date '+%s' -d "$prevtime")"
|
||||||
done < "$1"
|
done < "$file"
|
||||||
# Do last file which must be given twice as follows
|
# Do last file which must be given twice as follows
|
||||||
echo "file '$base'
|
echo "file '$base'
|
||||||
duration $((totseconds-seconds))
|
duration ${endtime:-5}
|
||||||
file '$base'"
|
file '$base'"
|
||||||
} > "$prepfile"
|
} > "$prepfile"
|
||||||
|
if [ -n "${audio+x}" ]; then
|
||||||
if [ -f "$2" ]; 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"
|
||||||
ffmpeg -y -f concat -safe 0 -i "$prepfile" -i "$2" -c:a aac -vsync vfr -c:v libx264 -pix_fmt yuv420p "$outfile"
|
|
||||||
else
|
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
|
fi
|
||||||
|
|
||||||
# Might also try:
|
# Might also try:
|
||||||
|
|
Loading…
Reference in a new issue