I'm using immich to manage my media library with photos and videos but appropriate video thumbnails are black or do not have an appropriate thumbnails for my family to view. As a test, I decided to manually recreate the thumbnails and then update appropriate thumbs files in the exact directory; replacing the auto-generated ones by Immich using ffmpeg. The following script works fine but one by one will take forever.
#!/bin/bash
file=(formula1 "aust_gp_00'23'41_2022_1858658849.mp4" f2dfse3-34gd-23ff-6hdd-p3h4kk/a3/10/a399-dj88-ah29 00:00:30.000)
# create jpeg + webp and replace existing
sudo ffmpeg -i /mnt/f1/"${file[0]}"/"${file[1]}" -ss "${file[3]}" -frames:v 1 /immich/app/thumbs/"${file[2]}"-preview.jpeg -y \
&& \
sudo ffmpeg -i /mnt/f1/"${file[0]}"/"${file[1]}" -ss "${file[3]}" -frames:v 1 /immich/app/thumbs/"${file[2]}"-thumbnail.webp -y
My goal is to put all the needed files in a text file use "readarry" to read each line as an array, use the appropriate index and then repeat for the next line. This is where I am stuck. How could I loop through each line where each line is a new file, keep the same indexes, and repeat? Anyone familiar with how to accomplish this or if there is a better way using bash? I was hoping to only use bash instead of python.
For example...
#files.txt
file=(formula1 "aust_gp_00'23'41_2022.mp4" f2dfse3-34gd-23ff-6hdd-p3h4kk/a3/10/a399-dj88-ah29 00:00:30.000)
file=(formula1 "belg_gp_00'13'31_2022.mp4" f2dfse3-34gd-23ff-6hdd-p3h4kk/q4/6/mhf-846d-zpyf 00:00:30.000)
file=(formula1 "melb_gp_00'05'11_2022.mp4" f2dfse3-34gd-23ff-6hdd-p3h4kk/b9/2/q3dd-0988-vr2t 00:00:30.000)
# genthumb.sh
#!/bin/bash
readarray -t lines < files.txt &&
for line in "${!lines[@]}"; do
sudo ffmpeg -i /mnt/f1/"${lines[0]}"/"${lines[1]}" -ss "${lines[3]}" -frames:v 1 /immich/app/thumbs/"${lines[2]}"-preview.jpeg -y \
&& \
sudo ffmpeg -i /mnt/f1/"${file[0]}"/"${file[1]}" -ss "${file[3]}" -frames:v 1 /immich/app/thumbs/"${file[2]}"-thumbnail.webp -y
done
bash
doesn't have 2-dimensional arrays. readarray
reads the entire file into a single array, each line is a single string element. So you can't use it to process each line as an array.
Get rid of the file=(...)
stuff in the file, just put the data without quotes. Then you can use a while read
loop to read each field into a different variable, and substitute those into your commands.
So change the file to:
formula1 aust_gp_00'23'41_2022.mp4 f2dfse3-34gd-23ff-6hdd-p3h4kk/a3/10/a399-dj88-ah29 00:00:30.000
formula1 belg_gp_00'13'31_2022.mp4 f2dfse3-34gd-23ff-6hdd-p3h4kk/q4/6/mhf-846d-zpyf 00:00:30.000
formula1 melb_gp_00'05'11_2022.mp4 f2dfse3-34gd-23ff-6hdd-p3h4kk/b9/2/q3dd-0988-vr2t 00:00:30.000
Then use
while read -r name filename uid time; do
sudo ffmpeg -i /mnt/f1/"$name"/"$filename" -ss "$time" -frames:v 1 /immich/app/thumbs/"$uid"-preview.jpeg -y </dev/null \
&& \
sudo ffmpeg -i /mnt/f1/"$name"/"$filename" -ss "$time" -frames:v 1 /immich/app/thumbs/"$uid"-thumbnail.webp -y </dev/null
done < files.txt