diff --git a/modules/video_previews.sh b/modules/video_previews.sh new file mode 100755 index 0000000..a250361 --- /dev/null +++ b/modules/video_previews.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +preview_dir="$(dirname "$0")/../previews" + +search_dir="${1}" + +check_dependencies() { + if ! mkdir -p "$preview_dir"; then + echo "ERROR: Unable to create preview directory" + exit 1 + elif ! command -v ffmpeg 2>&1 >/dev/null; then + echo "ERROR: FFmpeg must be installed" + exit 1 + fi +} + +check_input() { + if [[ ! -e "${search_dir}" ]]; then + echo "ERROR: Input file '${search_dir}' does not exist" + exit 2 + fi +} + +# Search for videos recursively using the MIME type +find_videos() { + video_list=$(find "${search_dir}" -type f -exec file -i {} \; | grep -oP '.*(?=: video/)') + + echo "${video_list}" >&2 +} + +create_previews() { + while IFS= read -r video; do + echo "Making preview for ${video}" + make_preview + done <<< "${video_list}" +} + +get_size() { + IFS=',' + read -r width height <<< $(ffprobe -v error -select_streams v -show_entries stream=width,height -of csv=p=0 "${video}") + + if [[ $width -gt $height ]]; then + rows=4 cols=5 + scale_format="200:-1" + else + rows=5 cols=4 + scale_format="-1:200" + fi +} + +get_num_frames() { + local num_snapshots=$(( rows * cols )) + + num_frames=$(ffprobe -v error -select_streams v:0 -count_frames -show_entries stream=nb_read_frames -of csv=p=0 "${video}") + echo "Num frames: $num_frames" >&2 + + frames_per_snapshot=$(( num_frames / num_snapshots )) +} + +make_preview() { + get_size + get_num_frames + + filename="$(basename "${video}")" + + ffmpeg -nostdin -loglevel panic -i "${video}" -frames 1 -q:v 90 -vf "select=not(mod(n\,$frames_per_snapshot)),scale=$scale_format,tile=${rows}x${cols}" "$preview_dir/${filename}.webp" +} + +check_dependencies +check_input +find_videos +create_previews