Script to Convert .mkv to .mp4

For help and support with issues specific to Linux/Unix
Forum rules
Please make sure you follow the Problem Reporting Guidelines before posting if you want a reply.

Script to Convert .mkv to .mp4

Postby Wutangrza » Mon Nov 15, 2010 4:49 pm

Just something I've been using to convert some of my mkv's to mp4's without losing any quality. It's fast as it just remuxes them instead of reencoding them. The advantage is that the ps3 will play these files natively without the need for any on the fly remuxing with mencoder/tsmuxer, which for some might be convenient. I've commented out 3 lines at that bottom that if uncommented will erase the source mkv file when completed, if you are happy with the results of the script, you can uncomment those lines to fully automate everything.

Anyway, here's the script, it will recursively remux all your mkv's to mp4's. It might not work with every mkv you find, but most of the "scene" stuff uses either AC3/AAC/DTS audio, and it will work for those. If you run into any problems, let me know, I'll try and make the script work as well as possible. I did once run into a problem where ffmpeg hosed up the audio in the resultant mp4, that's why there are those commented lines using mplayer and faac. If you find that ffmpeg is not converting the audio properly, comment the two lines that contain
Code: Select all
ffmpeg -i "${title}".ac3 -acodec libfaac -ab 576k "${title}".aac
and uncomment the mplayer and faac lines.


Code: Select all
#!/bin/bash

find . -type f | grep .mkv$ | while read file
do
 directory=`dirname "$file"`
 title=`basename "$file" .mkv`
 AC3=`mkvinfo "$file" | grep AC3` #check if it's AC3 audio or DTS
 AAC=`mkvinfo "$file" | grep AAC`
 order=`mkvinfo "$file" | grep "Track type" | sed 's/.*://' | head -n 1 | tr -d " "` #check if the video track is first or the audio track
 if [ "$order" = "video" ]; then
  fps=`mkvinfo "$file" | grep duration | sed 's/.*(//' | sed 's/f.*//' | head -n 1` #store the fps of the video track
  if [ -n "$AC3" ]; then
   mkvextract tracks "$file" 1:"${title}".264 2:"${title}".ac3
   ffmpeg -i "${title}".ac3 -acodec libfaac -ab 576k "${title}".aac
 #  mplayer -ao pcm:file="${title}".wav:fast "${title}".ac3
 #  faac -o "${title}".aac "${title}".wav
  elif [ -n "$AAC" ]; then
   mkvextract tracks "$file" 1:"${title}".264 2:"${title}".aac
  else
   mkvextract tracks "$file" 1:"${title}".264 2:"${title}".dts
   ffmpeg -i "${title}".dts -acodec libfaac -ab 576k "${title}".aac
  fi
 else
  fps=`mkvinfo "$file" | grep duration | sed 's/.*(//' | sed 's/f.*//' | tail -n 1`
  if [ -n "$AC3" ]; then
   mkvextract tracks "$file" 1:"${title}".ac3 2:"${title}".264
   ffmpeg -i "${title}".ac3 -acodec libfaac -ab 576k "${title}".aac
  # mplayer -ao pcm:file="${title}".wav:fast "${title}".ac3
  # faac -o "${title}".aac "${title}".wav
  elif [ -n "$AAC" ]; then
   mkvextract tracks "$file" 1:"${title}".264 2:"${title}".aac
  else
   mkvextract tracks "$file" 1:"${title}".dts 2:"${title}".264
   ffmpeg -i "${title}".dts -acodec libfaac -ab 576k "${title}".aac
  fi
 fi
 MP4Box -new "${directory}/${title}".mp4 -add "${title}".264 -add "${title}".aac -fps $fps
 rm -f "$title".aac "$title".dts "$title".ac3 "$title".264 "${title}".wav
# if [ -f "${directory}/${title}".mp4 ]; then
 # rm -f "$file"
# fi
done
Wutangrza
 
Posts: 12
Joined: Tue Nov 09, 2010 6:35 pm

Re: Script to Convert .mkv to .mp4

Postby idoru » Sat Mar 26, 2011 11:08 pm

Firstly, many thanks to Wutangrza for the script - i've been searching for something like this for a while now.

It works great for 1 file in a directory but doesn't seem to go any further.

i,e, i have several season directories filled with MKV files 1 to 10. 1 will be converted and work flawlessly but the script wont attempt files 2 to 10.

any ideas?
idoru
 
Posts: 1
Joined: Sat Mar 26, 2011 11:01 pm

Re: Script to Convert .mkv to .mp4

Postby Taraman » Fri Mar 30, 2012 10:33 am

Hi,

I just stumbled upon your script.
I had to change two lines to fit my german translated mkvinfo, but otherwise it works fine.

unfortunately the audio gets out of sync while remuxing (I'm using mplayer & faac because my linux distribution does not supply a ffmpeg with libaac enabled)

Has anyone an idea how one could improve the sync?

Best regards Taraman
Taraman
 
Posts: 5
Joined: Thu Mar 29, 2012 9:43 pm

Re: Script to Convert .mkv to .mp4

Postby mafps3 » Sun Jun 10, 2012 4:20 pm

Hi, thx for nice script. Work fine for me with mplayer extract. But i have one question for you.

How to modify your script to include in video more than one audio tracks?
mafps3
 
Posts: 1
Joined: Sun Jun 10, 2012 4:15 pm

Re: Script to Convert .mkv to .mp4

Postby sikko » Mon Jun 18, 2012 5:20 am

Nice script.

Ubuntu, among other distributions, does not support libfaac natively with ffmpeg.

The following link provides information on how to enable it for Ubuntu.
http://ubuntuforums.org/showthread.php?t=1117283
sikko
 
Posts: 2
Joined: Mon Jun 18, 2012 5:14 am

Re: Script to Convert .mkv to .mp4

Postby sikko » Mon Jun 18, 2012 7:46 am

For idoru,

I also experienced the same problem with processing files. Here is my updated version using a different (array based) method of processing the file list.

FYI - I'm using this to bulk remux mkv files to mp4 for streaming 720p media to iPhone and iPad via the AirPlay app while using mediatomb. I'm still having some minor issues with sync also, as I test and determine the problem I may post a fix for that - depending on how major the issue is.

Code: Select all
#!/bin/bash
DIR="$1"
 
# failsafe - fall back to current directory
[ "$DIR" == "" ] && DIR="."
 
# save and change IFS
OLDIFS=$IFS
IFS=$'\n'
 
# read all file name into an array
fileArray=($(find $DIR -type f | grep .mkv$))
#fileArray=($(find $DIR -type f ))
 
# restore it
IFS=$OLDIFS
 
# get length of an array
tLen=${#fileArray[@]}
 
# use for loop read all filenames
for (( i=0; i<${tLen}; i++ ));
do

   echo "${fileArray[$i]}"
     echo Pre proc ${fileArray[$i]}
     directory=`dirname "${fileArray[$i]}"`
     title=`basename "${fileArray[$i]}" .mkv`
     AC3=`mkvinfo "${fileArray[$i]}" | grep AC3` #check if it's AC3 audio or DTS
     AAC=`mkvinfo "${fileArray[$i]}" | grep AAC`
     order=`mkvinfo "${fileArray[$i]}" | grep "Track type" | sed 's/.*://' | head -n 1 | tr -d " "` #check if the video track is first or the audio track
     if [ "$order" = "video" ]; then
      fps=`mkvinfo "${fileArray[$i]}" | grep duration | sed 's/.*(//' | sed 's/f.*//' | head -n 1` #store the fps of the video track
      if [ -n "$AC3" ]; then
       mkvextract tracks "${fileArray[$i]}" 1:"${title}".264 2:"${title}".ac3
       ffmpeg -i "${title}".ac3 -acodec libfaac -ab 576k "${title}".aac
#       mplayer -ao pcm:file="${title}".wav:fast "${title}".ac3
#       faac -o "${title}".aac "${title}".wav
      elif [ -n "$AAC" ]; then
       mkvextract tracks "${fileArray[$i]}" 1:"${title}".264 2:"${title}".aac
      else
       mkvextract tracks "${fileArray[$i]}" 1:"${title}".264 2:"${title}".dts
      ffmpeg -i "${title}".dts -acodec libfaac -ab 576k "${title}".aac
      fi
     else
      fps=`mkvinfo "${fileArray[$i]}" | grep duration | sed 's/.*(//' | sed 's/f.*//' | tail -n 1`
      if [ -n "$AC3" ]; then
       mkvextract tracks "${fileArray[$i]}" 1:"${title}".ac3 2:"${title}".264
       ffmpeg -i "${title}".ac3 -acodec libfaac -ab 576k "${title}".aac
#       mplayer -ao pcm:file="${title}".wav:fast "${title}".ac3
#       faac -o "${title}".aac "${title}".wav
      elif [ -n "$AAC" ]; then
       mkvextract tracks "${fileArray[$i]}" 1:"${title}".264 2:"${title}".aac
      else
       mkvextract tracks "${fileArray[$i]}" 1:"${title}".dts 2:"${title}".264
       ffmpeg -i "${title}".dts -acodec libfaac -ab 576k "${title}".aac
      fi
     fi
     MP4Box -new "${directory}/${title}".mp4 -add "${title}".264 -add "${title}".aac -fps $fps
     rm -f "$title".aac "$title".dts "$title".ac3 "$title".264 "${title}".wav
    # if [ -f "${directory}/${title}".mp4 ]; then
     # rm -f "${fileArray[$i]}"
    # fi
echo ${fileArray[$i]}
 
 
done
sikko
 
Posts: 2
Joined: Mon Jun 18, 2012 5:14 am


Return to Linux/Unix Support

Who is online

Users browsing this forum: No registered users and 2 guests