2

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.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
kuruvi
  • 641
  • 1
  • 11
  • 28

2 Answers2

3

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

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
  • works beautifully, none of my methods work (after correcting the mistakes that you pointed here), it just hangs after the first encoding (Enter command: |all – kuruvi Feb 10 '17 at 16:24
3

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)

Community
  • 1
  • 1
l'L'l
  • 44,951
  • 10
  • 95
  • 146