Results 1 to 4 of 4

Thread: mkvextract Error:Invalid track ID/file name specificatio script to convert MKV to MP4

  1. #1
    Junior Member
    Join Date
    May 2012
    Posts
    2
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Rep Power
    0

    Default mkvextract Error:Invalid track ID/file name specificatio script to convert MKV to MP4

    I'm working on a script that will search through a directory for MKV files and remux them to MP4. I found a few other scripts around the net that do this, but they all have limitations that don't always get the job done. The main limitation I've found is that most scripts look for the video track in either the first track or the last track, which isn't always true. So I wanted a script that would work with any MKV file, no matter what track the video is on, and also copy all the audio/subtitle tracks, not just one audio and one video.


    Whenever I run the script I get the following error for every file it tries to extract the tracks from using mkvextract:


    Error: Invalid track ID/file name specification in argument '4.mkv"'.

    Whenever I type in the mkvextract command and run it myself it works perfect, so I'm not sure why the script has problems executing it.


    It's a long script, and could probably be written better, but this is my first attempt at a bash script. I've only ever worked with web programming languages in the past, so it hasn't been too difficult for me to get this far, but now I'm stuck...


    Code:
    #!/bin/bash
    
    
    find . -type f | grep .mkv$ | while read file
    do
     echo $file
     ## Gather some information about the file
     directory=`dirname "$file"`
     title=`basename "$file" .mkv`
     tracks=`mkvinfo "$file" | grep "Track type" | sed 's/.*: //'`
     maxarray=`mkvinfo "$file" | grep "Track number" | sed 's/.*: //' | tail -n 1`
    
    
     ## Put each of the tracks from the file into an array
     n=1
     for i in $tracks; do track[$n]=$i ; let n=n+1 ; done
    
    
     ## Loop through each track to figure out what codec it is
     ## Then store it in an array with the same location as the track
     codecs=`mkvinfo "$file" | grep "Codec ID" | sed 's/.*: //'`
     n=1
     for i in $codecs; do
      if [ "$i" == "V_MPEG4/ISO/AVC" ]; then
       type[$n]='264'
      elif [ "$i" == "A_DTS" ]; then
       type[$n]='dts'
      elif [ "$i" == "A_AC3" ]; then
       type[$n]='ac3'
      elif [ "$i" == "A_AAC" ]; then
       type[$n]='aac'
      elif [ "$i" == "S_TEXT/UTF8" ]; then
       type[$n]='srt'
      else
       echo "Track type unknown."
      fi
      let n=n+1;
     done;
    
    
     ## Loop through the file types and create an array with the file name and track type
     n=1
     for i in "${type[@]}"; do trcktitle[$n]="${title}.$i"; let n=n+1; done
    
    
     ## Loop through the track file names and search for names that are the same
     ## If they are the same, then change the file name with an incremental number
     ## This is done so that when extracting the tracks, each track has it's own file name
     ## To prevent overwriting tracks of the same type that were already extracted
     n=1
     for i in "${trcktitle[@]}"; do
      q=0
      z=1
      for p in "${trcktitle[@]}"; do
       if [ "$i" == "$p" ]; then
        if [ -n "$sametitle" ]; then
         sametitle=("${sametitle[@]}" "$z")
        else
         sametitle=("$n" "$z");
        fi
        let q=q+1
       fi
      let z=z+1
      done
      if [ $q -gt 1 ]; then
       t=0
       for i in "${sametitle[@]}"; do
        trcktitle[$i]="${title}${t}.${type[$i]}"
        let t=t+1
       done
      fi
      q=0
      let n=n+1
      unset sametitle
     done
    
    
     ## Let's figure out the FPS of the video track
     ## Some MKV files don't always put the video track in the same location, so we gather all the FPS information in the file
     ## Then we figure out which FPS belongs to the video track
     ## This is done by looping through both the FPS array and the type array
     ## Assigning the same location in each array based on file type
     ## If the type is SRT, move on in the type array but stay at the same location in the FPS array
     ## If AC3, AAC, or DTS, move in in both arrays; if 264 (the video track) assign FPS from array to vfps and leave the loop
     trckfps=`mkvinfo "$file" | grep duration | sed 's/.*(//' | sed 's/f.*//'`
     n=1
     for i in ${trckfps[@]}; do fps[$n]=$i; let n=n+1; done
     if [ ${#type[@]} != ${#fps[@]} ]; then
      n=1
      z=1
      for i in ${type[@]}; do
       if [ "$i" == "srt" ]; then
        let n=n+1
       elif [ "$i" == "264" ]; then
        vfps=${fps[$z]}
        break
       else
        let z=z+1
        let n=n+1
       fi
      done
     else
      n=1
      for i in ${type[@]}; do
       if [ "$i" == "264" ]; then
        vfps=${fps[$n]}
        break
       fi
       let n=n+1
      done
     fi
    
    
     ## Create the options for the MKVEXTRACT command. This will put the track titles in the correct location with track position and type
     n=1
     while [ $n -le $maxarray ]; do
      if [ -n "$extract" ]; then
       extract=" ${extract} ${n}:\"${trcktitle[$n]%.*}\".${type[$n]}"
      else
       extract="mkvextract tracks \"${file}\" ${n}:\"${trcktitle[$n]%.*}\".${type[$n]}"
      fi
      let n=n+1
     done
     echo $extract
     echo `$extract`
    
    
     ## If the type that was extracted is AC3 or DTS, we need to convert it to AAC before putting everything back together in the MP4 container
    # n=1
    # for i in ${type[@]}; do
    #  if ([ "$i" == "ac3" ] || [ "$i" == "dts" ]); then
    #   old=${trcktitle[$n]}
    #   trcktitle[$n]=$old.aac
    #   ffmpeg -i "$old" -acodec libfaac -ab 576k "${trcktitle[$n]}"
    #  fi
    #  let n=n+1
    # done
     #echo $old
     #echo ${trcktitle[@]}
    
    
     ## Create all the options that go into the MP4Box command
     ## Loop through each track title and add it to the input array
    # n=1
    # while [ $n -le $maxarray ]; do
    #  if [ -n "$input" ]; then
    #   input=" $input -add \"${trcktitle[$n]}\""
    #  else
    #   input="-add \"${trcktitle[$n]}\""
    #  fi
    #  let n=n+1
    # done
     #echo $input
    
    
     ## Let's put everything back togehter into an MP4 file
    # MP4Box -new "${directory}/${title}".mp4 $input -fps $vfps
    
    
     ## Now we need to clean up our mess
     ## Delete all of the track title files that we extracted from the MKV file
    # for i in ${trcktitle[@]}; do
    #  rm -f "$i"
    # done
    
    
     ## If there is an MP4 file created, then let's go ahead and delete the original MKV file
     ## I would leave this commented so you can test the MP4 file for quality, then delete the original yourself
     #if [ -f "${directory}/${title}.mp4 ]; then
      #rm -f "$file"
     #fi
    
    
     ## Let's clean up some of the variables we used so they dont get reused in the next file
     n=""
     file=""
     directory=""
     title=""
     tracks=""
     maxarray=""
     codecs=""
     unset type
     unset trcktitle
     extract=""
     input=""
    
    
    done

  2. #2
    Never say die nixcraft's Avatar
    Join Date
    Jan 2005
    Location
    BIOS
    Posts
    4,513
    Thanks
    17
    Thanked 803 Times in 511 Posts
    Rep Power
    10

    Default

    Code:
    find . -type f | grep .mkv$ | while read file
    This is wrong. A file with white spaces is going to fail for sure. Update it as follows:
    Code:
    find . -type f -iname "*.mkv" -print0 | while read -d $'\0' file
    Try it and let us know.
    All [Solved] threads are closed by mods / admin to avoid spam issues. See Howto mark a thread as [Solved]


  3. The Following User Says Thank You to nixcraft For This Useful Post:

    rayne127 (9th May 2012)

  4. #3
    Is that all you got? rockdalinux's Avatar
    Join Date
    May 2005
    Location
    Planet Vegeta
    Posts
    987
    Thanks
    27
    Thanked 71 Times in 62 Posts
    Rep Power
    20

    Default

    Error: Invalid track ID/file name specification in argument '4.mkv"'.



    Read escape section mkvextract -- extract tracks from Matroska files into other files

    If that did not work try sending command to another file and execute it. In the past I've the fixed issue using this technique.


    Code:
    ## Create the options for the MKVEXTRACT command. This will put the track titles in the correct location with track position and type
     n=1
     while [ $n -le $maxarray ]; do
      if [ -n "$extract" ]; then
       extract=" ${extract} ${n}:\"${trcktitle[$n]%.*}\".${type[$n]}"
      else
       extract="mkvextract tracks \"${file}\" ${n}:\"${trcktitle[$n]%.*}\".${type[$n]}"
      fi
      let n=n+1
     done
     echo $extract
     echo `$extract`

    Replace it:
    Code:
    ## Create the options for the MKVEXTRACT command. This will put the track titles in the correct location with track position and type
     n=1
     while [ $n -le $maxarray ]; do
      if [ -n "$extract" ]; then
        ## fixed ##
       extract=" ${extract} ${n}:\"${trcktitle[$n]%.*}.${type[$n]}\""
      else
        ## fixed ##
       extract="mkvextract tracks \"${file}\" ${n}:\"${trcktitle[$n]%.*}.${type[$n]}\""
      fi
      let n=n+1
     done
     ## fixed ##
     >/tmp/yyy
     echo "$extract" > /tmp/yyy
     bash /tmp/yyy
    Update main for loop as suggested by nixcraft.
    Last edited by rockdalinux; 8th May 2012 at 01:51 PM.
    Rocky Jr.
    What's wrong? I hope I am not making you uncomfortable...

    Never send a boy to do a mans job.

  5. The Following User Says Thank You to rockdalinux For This Useful Post:

    rayne127 (9th May 2012)

  6. #4
    Junior Member
    Join Date
    May 2012
    Posts
    2
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Rep Power
    0

    Default

    Thank you so much! I just sent the command to another file and executed it. I didn't feel like making the script any longer or spending any more time on it to escape characters in the file names. I'll just take the easy route out! Thank you again! It's working perfectly =)

Thread Information

Users Browsing this Thread

There are currently 2 users browsing this thread. (0 members and 2 guests)

Similar Threads

  1. [Solved] Shell script to convert log file into a csv formatted text file
    By c00l_chintu in forum Shell scripting
    Replies: 13
    Last Post: 28th September 2012, 12:24 AM
  2. Convert text file into shell script?
    By Ortegadelas in forum Shell scripting
    Replies: 2
    Last Post: 31st January 2011, 08:56 PM
  3. AWK script to convert CIM file into delimited file
    By arpita in forum Shell scripting
    Replies: 5
    Last Post: 16th February 2010, 02:14 PM
  4. Script to track the changes made to a file
    By hariharan.nb in forum Shell scripting
    Replies: 1
    Last Post: 11th June 2009, 03:30 PM
  5. Replies: 0
    Last Post: 9th July 2006, 04:38 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •