3

I have videos with dts audio I can convert to ac3 separately, but I need to batch convert a bunch, but can't figure out how.

This is my working ffmpeg for separate files:

for f in *.mkv; 
do 
    ffmpeg -i "$f" -metadata:s:a:0 language=eng -metadata:s:a:0 title="AC3 5.1" -map 0:v -map 0:a:0 -map 0:a -map 0:s -c:v copy -c:a copy -c:s copy -c:a:0 ac3 -b:a:0 640k "/srv/dev-disk-by-label-hel/temp/${f%.mkv}".mkv;
done

All videos are located in separate folders under my main ”media” folder. Some folders with spaces in them. In the working script the file gets processed to separate temp dir.

I need help with:

  • For ffmpeg to convert all mkvs recursively.

  • for ffmmpeg to process the separate converted mkvs to my temp dir.

Also next step if anyone has ideas:

  • Use the processed videos in temp dir to replace original unconverted files.
1
  • What do you mean by "process" the separate converted mkvs in your temp dir? Do you just want to save them to a temp dir so you can then overwrite the original? Or is there some more processing?
    – terdon
    Dec 30, 2019 at 14:51

1 Answer 1

4

To make it recursive, you can either use find or activate the globstar bash option:

  1. find -exec:

    find . -name '*.mkv' -exec ffmpeg -i {} -metadata:s:a:0 language=eng -metadata:s:a:0 title="AC3 5.1" -map 0:v -map 0:a:0 -map 0:a -map 0:s -c:v copy -c:a copy -c:s copy -c:a:0 ac3 -b:a:0 640k /srv/dev-disk-by-label-hel/temp/{} \;
    

    The {} inside the -exec will be converted to the current file name. I didn't bother with your ${f%.mkv}".mkv; since that is identical to the input file name, you're removing a .mkv and then adding it, so I assumed that was a mistake.

  2. globstar. This option lets ** recurse into 0 or more subdirectories.

    shopt -s globstar
    for f in **/*.mkv; 
    do 
        fname="${f##*/}"
        ffmpeg -i "$f" -metadata:s:a:0 language=eng -metadata:s:a:0 title="AC3 5.1" -map 0:v -map 0:a:0 -map 0:a -map 0:s -c:v copy -c:a copy -c:s copy -c:a:0 ac3 -b:a:0 640k "/srv/dev-disk-by-label-hel/temp/"$fname";
    done
    

    This is the one you can most easily make copy the files back to the original. As long as you don't mind overwriting the originals, you can do:

    shopt -s globstar
    for f in **/*.mkv; 
    do 
        fname="${f##*/}"
        ffmpeg -i "$f" -metadata:s:a:0 language=eng -metadata:s:a:0 title="AC3 5.1" -map 0:v -map 0:a:0 -map 0:a -map 0:s -c:v copy -c:a copy -c:s copy -c:a:0 ac3 -b:a:0 640k "/srv/dev-disk-by-label-hel/temp/$fname" &&
        mv "/srv/dev-disk-by-label-hel/temp/$fname" "$f"
    done
    
2
  • This is great, i am using youre globstar with the mv command. I just changed the line: ´for f in .mkv;´ To: ´for f in **/.mkv;´ Otherwise no file would be found. Edit: there should be a star before my .mkv , but it doent show for some reason
    – Set
    Dec 30, 2019 at 22:33
  • @Set d'oh! I'm an idiot, I completely forgot to add it when writing the answer, I just copied the glob from yours. Thanks for spotting it! Note that you want **/*.mkv, not **/.mkv, but I guess you already figured that out.
    – terdon
    Dec 31, 2019 at 10:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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