#!/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:0 -show_entries stream=width,height -of csv=p=0 "${video}") if (( $width >= $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="$preview_dir/$(basename "${video}").webp" filters="select=not(mod(n\,$frames_per_snapshot)),scale=$scale_format,tile=${rows}x${cols}" ffmpeg -nostdin -loglevel panic -i "${video}" -frames 1 -q:v 90 -vf "$filters" "${filename}" } check_dependencies check_input find_videos create_previews