2

I don't have a good level in bash but with some knowledge I made this script which allows me to compress a serie I ripped from a Bluray :

#!/bin/bash

files=(*.mkv)
AUDIOCOUNTER=0
AUDIOFRCOUNTER=0
# Find out which tracks contain the audio
mkvmerge --identify --identification-format json "${files[0]}" | jq '.tracks[] | select(.type=="audio").properties.language' | ( while read audio_tracks
do
  # Grep the number of audio tracks
  if [[ "$audio_tracks" = "fre" ]];then
    let AUDIOFRCOUNTER++
  fi
  let AUDIOCOUNTER++
done
if [[ "$AUDIOCOUNTER" -gt 1 && "$AUDIOFRCOUNTER" -gt 0 ]];then
  read -p 'encode MULTi ? (y/n) : ' multi
fi)

read -p 'CRF cible : ' crf
read -p 'Qualité audio : ' audioquality
read -p 'Convertir en stereo ? (y/n) : ' audiostereo

for FILE in *.mkv
do
  file=${FILE%.*}
  if [ $multi = "y" ]
  then
    if [ $audiostereo = "y" ]
    then
      ffmpeg -i "$file.mkv" -vn -c:a libfdk_aac -profile:a aac_he_v2 -vbr $audioquality -map a -map -m:language:fre -af "pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR" "encoded/$file.fr.m4a"
      ffmpeg -i "$file.mkv" -vn -c:a libfdk_aac -profile:a aac_he_v2 -vbr $audioquality -map a -map -m:language:eng -af "pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR" "encoded/$file.en.m4a"
    else 
      ffmpeg -i "$file.mkv" -vn -c:a libfdk_aac -profile:a aac_he_v2 -vbr $audioquality -map a -map -m:language:fre "encoded/$file.fr.m4a"
      ffmpeg -i "$file.mkv" -vn -c:a libfdk_aac -profile:a aac_he_v2 -vbr $audioquality -map a -map -m:language:eng "encoded/$file.en.m4a"
    fi
  else
    if [ $audiostereo = "y" ]
    then
      ffmpeg -i "$file.mkv" -vn -c:a libfdk_aac -profile:a aac_he_v2 -vbr $audioquality -af "pan=stereo|FL < 1.0*FL + 0.707*FC + 0.707*BL|FR < 1.0*FR + 0.707*FC + 0.707*BR" "encoded/$file.en.m4a"
    else 
      ffmpeg -i "$file.mkv" -vn -c:a libfdk_aac -profile:a aac_he_v2 -vbr $audioquality "encoded/$file.en.m4a"
    fi
  fi


  subtitle_param=""
  mkvmerge --identify --identification-format json "$file.mkv" | jq '.tracks[] | select(.codec=="SubRip/SRT" and (.properties.language=="fre" or .properties.language=="eng")).properties.number' | ( while read subtitle_track_number
  do
    echo "$subtitle_track_number"
    let subtitle_param+="-map 0:$subtitle_track_number "    
    echo "$subtitle_param"
  done)

  echo "subtitle param : $subtitle_param"

  read -p 'Continue ? : '

  if [ $subtitle_param = "" ]
  then
    ffmpeg -i "$file.mkv" -map 0:v -c:v libx265 -crf $crf -preset  medium -pix_fmt yuv420p -an "encoded/$file.mkv"
  else
    ffmpeg -i "$file.mkv" -map 0:v -c:v libx265 -crf $crf -preset  medium -pix_fmt yuv420p -map -0:a "$subtitle_param" -c:s copy "encoded/$file.mkv"
  fi
  
  if [ $multi = "y" ]
  then
    mkvmerge -o "remuxed/$file.mkv" "encoded/$file.mkv" --language 0:fre "encoded/$file.fr.m4a" --language 0:eng "encoded/$file.en.m4a"
    mkvpropedit "remuxed/$file.mkv" --tags all:"" --delete title --edit track:a1 --set flag-default=1 --delete name --edit track:a2 --set flag-default=0 --delete name --edit track:s1 --delete name --set flag-default=1 --set flag-forced=1 --edit track:s2 --delete name --set flag-default=0
    rm -f "encoded/$file-fr.m4a"
  else
    mkvmerge -o "remuxed/$file.mkv" --no-subtitles "encoded/$file.mkv" --language 0:eng "encoded/$file.en.m4a"
    mkvpropedit "remuxed/$file.mkv" --tags all:"" --delete title --edit track:a1 --set flag-default=1 --delete name
  fi 
  
  rm -f "encoded/$file.mkv"  
  rm -f "encoded/$file.en.m4a"
done

Everythings works until this block of code :

  subtitle_param=""
  mkvmerge --identify --identification-format json "$file.mkv" | jq '.tracks[] | select(.codec=="SubRip/SRT" and (.properties.language=="fre" or .properties.language=="eng")).properties.number' | ( while read subtitle_track_number
  do
    echo "$subtitle_track_number"
    let subtitle_param+="-map 0:$subtitle_track_number "    
    echo "$subtitle_param"
  done)

I'm detecting language using the infos returned by mkvmerge in json using another shell instance, I need to get the track number of all subtitles that matche Fr or English language, so I use let to acces the subtitle_param outside of this shell instance in the main instance. But it throws the error :

let: syntax error in expression ( symbol error is << 0:6 >> )

Any suggestion ? :)

1 Answer 1

1

let evaluates arithmetic expressions. When you want to concatenate strings, you don't need arithmetic expressions, so drop the let.

subtitle_param+="-map 0:$subtitle_track_number "    
Sign up to request clarification or add additional context in comments.

8 Comments

That's what I did before but I can't access it outside the while read loop
Because you change the variable in a subshell. Subshell environment doesn't propagate back to the parent shell.
There's no way to propagate to the parent shell ? Or do you know another way to read the json and get the infos that I want ?
The common trick is to use process substitution: while read ... done < <(generate the data here).
by "generate the data here" you mean I have to put a command to store the output in a var ? I can't just directly put it in var ? Like : while read ... done < <($my_var)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.