brtv-imgs-to-video.sh (1601B)
1 #!/bin/sh 2 # read hashtags.txt as stdin, download all images, and convert them to videos 3 # requirements: hurl(1), ffmpeg(1), convert(1) 4 5 6 ### CONFIGURATION START 7 8 # dir to contain images as videos 9 out_dir="/br/gopher/tv/img2vid" 10 11 # ffmpeg flags for generated videos 12 video_ext="webm" 13 ffmpeg_codec="-loglevel error -acodec libopus -b:a 96K -f webm -vf scale=1280:-1 -r 30 -ac 2" 14 15 # target video resolution 16 video_resolution=1280x720 17 18 # slide style 19 bgcolor=magenta 20 21 # show image memes for this duration [s] 22 image_display_time=10 23 24 ### CONFIGURATION END 25 26 27 die() { 28 printf '%s: error: %s\n' "${0##*/}" "$1" >&2 29 exit 1 30 } 31 32 regeximatch() { 33 printf '%s' "$1" | grep -iEq "$2" 34 } 35 36 fit_img_16_9() { 37 convert -resize "$video_resolution"\> -size "$video_resolution" "$1" \ 38 xc:"$bgcolor" +swap -gravity center -composite "$2" 39 } 40 41 video_from_img() { 42 ffmpeg -y \ 43 -f lavfi \ 44 -i anullsrc=r=48000 \ 45 -i "$1" \ 46 -t "${image_display_time}" \ 47 $ffmpeg_codec \ 48 "$2" < /dev/null 49 } 50 51 mkdir -p "$out_dir" 52 53 # generate video from each image 54 while read -r tag url; do 55 if ! regeximatch "$url" '\.(jpg|jpeg|png|gif)$'; then 56 continue 57 fi 58 59 imgfile="${out_dir}/${url##*/}" 60 out="${imgfile%.*}.${video_ext}" 61 62 if [ ! -f "$out" ]; then 63 64 if [ ! -f "$imgfile" ]; then 65 if ! hurl "$url" > "$imgfile"; then 66 die "hurl could not download $url" 67 fi 68 fi 69 70 if ! regeximatch "$(file -ib "$imgfile")" "^image\/"; then 71 die "input image $imgfile is invalid ($(file -b "$imgfile"))" 72 fi 73 fit_img_16_9 "$imgfile" "${out%.*}_16-9.jpg" 74 video_from_img "${out%.${video_ext}}_16-9.jpg" "${out}" 75 printf '%s\n' "$out" 76 fi 77 done