3

I am trying to recursively convert all .mkv files in a folder structure with subfolders to .mp4.

I got a standard line that works in just the present folder

for video in *.mkv; do ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4; rm "$video"; done

So I thought I would make something like

for video in $(find . -name *.mp4); do ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mkv; rm "$video"; done

But this seems to fail on folders with spaces in them. Can anyone point out my error?

2

1 Answer 1

10

Your error lies in using find in a command substitution. A command substitution always results in a single string. If you leave the substitution unquoted, that string will undergo splitting on spaces, tabs and newlines (by default). The split-up words will be processed for filename globbing. The resulting strings are what your loop will iterate over, which is not what you want.

Your loop that works for the current directory (fixing the issue with filenames starting with a dash):

for video in ./*.mkv; do
    ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
    rm "$video"
done

Changed to work recursively, by enabling the ** globbing pattern (and using nullglob to avoid running the loop at all if there are no matches):

shopt -s globstar nullglob

for video in ./**/*.mkv; do
    ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
    rm "$video"
done

The two loops above would not care about the filetype and would happily feed ffmpeg with symbolic links, directories, or any other non-regular type of file, as long as the name matched the given pattern.

Alternatively, delegating the recursive generation of pathnames to find (also only selecting regular files):

find . -name '*.mkv' -type f -exec sh -c '
    for video do
        ffmpeg -i "$video" -acodec aac -ac 2 "${video%.*}".mp4
        rm "$video"
    done' sh {} +

The above would also find hidden names matching the pattern, which the first two shell loops would not do (unless you enable the dotglob shell option).

Other relevant questions:

Not the answer you're looking for? Browse other questions tagged or ask your own question.