Home > Back-end >  Recursive script in bash to convert photos to videos
Recursive script in bash to convert photos to videos

Time:11-12

I am not a shell expert and I would like to know how to write a small algorithm (I think it is possible) to solve my problem.

I have an output directory which itself contains several folders for example data_1 , data_2, etc. These folders also contain different versions, for example version_1, version_2. And finally these versions all contain an image folder photos which contains several thousand images in the form 000001.jpg, 000002.jpg, ... I'm looking to convert all these photos folders into a video that takes the photos frame by frame. For example for the 2nd version of the dataset data_1 I will do the following commands:

ffmpeg -i data_1/version_1/photos/m.jpg data_1/version_1/data_1_ version_1.mov

rm -r data_1/version_1/photos

But this implies that I have to rewrite by hand the command once the program is finished for a folder by changing the folder names and also the .mov file which must imperatively be of the form data_version.mov and saved at data/version/data_version.mov.

I would like a script that automates this procedure by going through all the data folders to create the videos BUT also by checking that if the video exists the script is not run on the current version.

Thank you in advance for any help

CodePudding user response:

Assuming the directory name photos is fixed, would you please try:

while IFS= read -r dir; do                              # assign "dir" to the path to "photos"
    dir2=${dir%/photos}                                 # remove trailing "photos" dirname
    name=${dir2#*/}                                     # remove leading slash
    name=${name//\//_}                                  # convert slashes to underscores
    echo ffmpeg -i "$dir/m.jpg" "$dir2/${name}.mov"   # execute ffmpeg
    echo rm -rf -- "$dir"                               # rm "photos" directories
done < <(find . -type d -name "photos")                 # find dir named "photos" recursively

If the output looks good, drop echo and execute.

CodePudding user response:

I would go with a glob expansion instead of using find, as its easier and more portable to force a specific path; the rest would be almost identical as @tshiono answer.

shopt -s nullglob extglob

photos_dirpaths=(data_ ([[:digit:]])/version_ ([[:digit:]])/photos/)

if [ ${#photos_dirpaths[@]} -eq 0 ]
then
    echo 'error: run this script inside the output directory' 1>&2
    exit 1 
fi

for dirpath in "${photos_dirpaths[@]%/}"
do
    filepath="${dirpath%/photos}"
    filename="${filepath//\//_}.mov"
    echo ffmpeg -i "$dirpath/m.jpg" "$filename"
    # or?
    echo ffmpeg -i "$dirpath/m.jpg" "$filepath/$filename"

    [ $? -eq 0 ] && echo rm -rf "$dirpath"
done
  • Related