Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

ffmpeg - Bash script to recursive find and convert movies

in my large movie collection I would like to search for movies with the primary (first) audio track with DTS coding to be converted to Dolby.

My problem would be the first track I think. My current bash script will list any movie containing a DTS track, but does not specify which track.

#!/bin/bash
# My message to create DTS list
find /home/Movies -name '*.mkv' | while read f
do
if mediainfo "$f" | grep A_DTS; then
echo $f 
fi
done

After that I would like to run this command

ffmpeg -i $f -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 $f

or is there a way to move all the audio tracks down and adding the new AAC track?

###Progress

Thanks to @llogan I have finetuned the bash to find the required files.

#!/bin/bash
# My DTS conversion script
# credits to llogan

find /Mymovies -name '*.mkv' | while read f
do
 if ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 "$f" | grep dts; then
 echo "$f"
fi
done

Now digging into the command I think I may have a working command. Anybody spot a problem?

ffmpeg -i $f
      -map 0:v -c:v copy
      -map 0:a:0? -c:a:0 ac3
      -map 0:a:0? -c:a:1 copy
      -map 0:a:1? -c:a:2 copy
      -map 0:a:2? -c:a:3 copy
      -map 0:a:3? -c:a:4 copy
      -map 0:a:4? -c:a:5 copy
      -map 0:a:5? -c:a:6 copy
      -map 0:a:6? -c:a:7 copy
      -map 0:a:7? -c:a:8 copy
      -map 0:a:8? -c:a:9 copy
      -map 0:s? -c copy
      -b:a:0 640k
/tmp/output.mkv
mv $f /home/DTS_BACKUP/
mv /tmp/output.mkv $f
rm /tmp/output.mkv

So the end result would look like:

#!/bin/bash
# My DTS conversion script
# credits to llogan
find /Mymovies -name '*.mkv' | while read f
do
 if ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 "$f" | grep dts; then

ffmpeg -i $f
          -map 0:v -c:v copy
          -map 0:a:0? -c:a:0 ac3
          -map 0:a:0? -c:a:1 copy
          -map 0:a:1? -c:a:2 copy
          -map 0:a:2? -c:a:3 copy
          -map 0:a:3? -c:a:4 copy
          -map 0:a:4? -c:a:5 copy
          -map 0:a:5? -c:a:6 copy
          -map 0:a:6? -c:a:7 copy
          -map 0:a:7? -c:a:8 copy
          -map 0:a:8? -c:a:9 copy
          -map 0:s? -c copy
          -b:a:0 640k
/tmp/output.mkv
mv $f /home/DTS_BACKUP/
mv /tmp/output.mkv $f
rm /tmp/output.mkv

fi
done
question from:https://stackoverflow.com/questions/65617649/bash-script-to-recursive-find-and-convert-movies

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, so i finetuned the script to seperate dts and dts-hd. I came to the conclusion this was not needed because i cant decode dts-hd to e-ac3 and may as well also encode it to ac3. But i had fun in bash.

Current bash:

#!/bin/bash
# My DTS conversion script
# credits to llogan

find /MyMovies -name '*.mkv' | while read f
do

function codec_profile {
ffprobe -v error -select_streams a:0 -show_entries stream=$1 -of csv=p=0 "$f"
}

#first check for audio format
if [ "$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 "$f")" = "dts" ]; then
    if [ "$(codec_profile "profile")" = "DTS" ]; then
      echo "$f" >> dts.txt
      codec_profile "profile" >> dts.txt
      codec_profile "channels" >> dts.txt
      if [ "$(codec_profile "channels")" -gt 5 ]; then
        echo "check" >> dts.txt; else
        echo "stereo" >> dts.txt;
      fi
    else [ "$(ffprobe -v error -select_streams a:0 -show_entries stream=profile -of csv=p=0 "$f")" = "DTS-HD MA" ]; 
      echo "$f" >> dts-hd.txt
      codec_profile "profile" >> dts-hd.txt
      codec_profile "channels" >> dts-hd.txt    
    fi
fi
done

I checked the created txt files and the result is spot op. I also tested the command that @llogan gave me and works perfect.

ffmpeg -i "$f" -map 0 -map -0:a -map 0:a:0 -map 0:a -c copy -c:a:0 ac3 -b:a:0 640k /tmp/output.mkv

Last thing to figure out is how to check the exit code on this and replace the text file creation with this command

The idea:

ffmpeg -i "$f" -map 0 -map -0:a -map 0:a:0 -map 0:a -c copy -c:a:0 ac3 -b:a:0 640k /tmp/output.mkv
RC=$?
if [ "${RC}" -ne "0" ]; then
    # list error in txt file and move on to next
else
# mv output file to overwrite original file
fi

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...