kuruvi
kuruvi

Reputation: 653

Loop recursively for specific extension and subfolders

I have been trying to convert flac to m4a, I have the below script that does the job but it is not recursive:

for f in *.flac; do
    ffmpeg -i "$f"  -vf "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${f%.flac}.m4a"
done

For recursive, I did try several ways but none worked, here is what I tried (space on file name is the problem here)

for f in `find . $PWD -iname *.flac`; do
    ffmpeg -i "$f"  -vf "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${f%.flac}.m4a"
done

and this

find . -type f -iname "*.flac" -print0 |
    while IFS= read -r -d $'\0' line; do
        echo "$line"
        ffmpeg -i "$line"  -vf "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${f%.flac}.m4a"; done   
    done

None of them work.

Upvotes: 2

Views: 1822

Answers (2)

Benjamin W.
Benjamin W.

Reputation: 52102

The second try fails because of word splitting: the output of find gets split up.

Your last try would work, but there is one done too many, and you use $f in "${f%.flac}.m4a" where it should be ${line%.flac}.m4a".

I'd use a glob instead (requires shopt -s globstar):

for fname in **/*.flac; do
    ffmpeg -i "$fname"  -vf "crop=((in_w/2)*2):((in_h/2)*2)" \
        -c:a alac "${fname%.flac}.m4a"
done

This searches the whole subtree of the current directory without the need for find.


1 Bash 4.0 or newer

Upvotes: 3

l'L'l
l'L'l

Reputation: 47159

Using the -execdir option with find:

find . -name "*.flac" -execdir bash -c 'ffmpeg -i "$0"  -vf \
"crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${0%.flac}.m4a"' {} \;

Recursively matches/re-encodes .flac files as .m4a and saves them in the same directory. Using -exec instead of -execdir any re-encoded files would be saved to the location the command above is being executed from — which likely isn't what you would want.

The -execdir primary is identical to the -exec primary with the exception that utility will be executed from the directory that holds the current file.

This solution works nicely, especially if your version of bash doesn't include shopt's globstar.

Another example of ffmpeg re-encoding using find and -execdir. (more complex)

Upvotes: 3

Related Questions