mkvsubext.sh

egyszer csak szükség lett rá :))
most már van ilyen (is).


#!/bin/bash
# Extract subtitles from each MKV file in the given directory

# If no directory is given, work in local dir
if [ "$1" = "" ]; then
  DIR="."
else
  DIR="$1"
fi

# Get all the MKV files in this dir and its subdirs
find "$DIR" -type f -name '*.mkv' | while read filename
do
  # Find out which tracks contain the subtitles
  mkvmerge -i "$filename" | grep 'subtitles' | while read subline
  do
    # Grep the number of the subtitle track
    tracknumber=`echo $subline | egrep -o "[0-9]{1,2}" | head -1`

    # Do a super-primitive language guess: ENGLISH
    # Corrected
    tracklanguage=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.* language:\([a-z]\{3\}\) .*/\1/p'`
    [ "$tracklanguage" ] || tracklanguage="unknown"

    # Get base name for subtitle
    subtitlename=${filename%.*}

    # Extract the track to a .tmp file
    mkvextract tracks "$filename" $tracknumber:"$subtitlename.srt.tmp" > /dev/null 2>&1
    chmod g+rw "$subtitlename.srt.tmp"

    # Rename to the final name
    mv "$subtitlename.srt.tmp" "$subtitlename-t$tracknumber-$tracklanguage.srt" > /dev/null 2>&1

  done
done

nem egyedül csináltam, egy deszkamodell már létezik v.hol a neten :)

Hozzászólások

Ha egysoros a if then es else aga is azt en igy szoktam irni, szerintem atlathatobb es rovidebb is:


if [ "$1" = "" ]
  then DIR="."
  else DIR="$1"
fi

Egyebkent azt, hogy a string nem ures-e, az a [ "$1" = "" ] helyett lehet igy is: [ -n "$1" ] vagy a szmomra jobban olvashato formaban: [ ! "$1" ] aminek a negalasabol es az if megforditasabol ki is jon, hogy:


if [ "$1" ]
  then DIR="$1"
  else DIR="."
fi

De valojaban bashban (!szoval csak ha biztos, hogy bash!) default erteket igy erdemes:


DIR=${1:-.}

man bash:

${parameter:-word}
Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.

mondjuk így is működik, és jól, valamint sem jobb, sem gyorsabb nem lenne a változtatással.

ha változtatnék, és miért ne? akkor valami ilyesmit csinálnék:


if [ "$1" = "-h" ]; then
  usage
  exit 0
elif [ "$2" ]; then
  usage
  exit 1
# If no directory is given, work in local dir
elif [ ! "$1" ]; then
  DIR="."
elif [ -e "$1" ]; then
  DIR="$1"
else
  usage
  echo
  echo "  ERROR: $1 ..."
  exit 1
fi

valamint:


  mkvmerge -i "$filename" | sed -n -e 's/^Track ID \([0-9]\+\): subtitles .*$/\1/p' | while read tracknumber
  do

    tracklanguage=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.* language:\([a-z]\{3\}\) .*/\1/p'`
    [ "$tracklanguage" ] || tracklanguage="unknown"

    subtitlename=${filename%.*}

    mkvextract tracks "$filename" $tracknumber:"$subtitlename.srt.tmp" > /dev/null 2>&1
    chmod g+rw "$subtitlename.srt.tmp"

    mv "$subtitlename.srt.tmp" "$subtitlename-t$tracknumber-$tracklanguage.srt" > /dev/null 2>&1

  done

ezzel viszont gyorsabb lenne..
nem mintha ez számítana:)

a végén a .tmp fájlba mentést, meg az átnevezését azt meghagynám, csak kilépnék ha sikertelen az átnevezés.

de gyorsan kellett és jól műkodik :))

mert ma reggel kellett, azóta nem nagyon volt rá időm, este meg kedvem nem nagyon volt..
:)

de most, hogy lenyugodtak a do'gok és erről beszélünk, plusz lesz valami erős javítás, akkor átírom, mint ahogy mindenki magának, ha egyáltalán :)

egyébként meg én is innen másoltam ki az otthoni gépemre :))

"mondjuk így is működik, és jól, valamint sem jobb, sem gyorsabb nem lenne a változtatással."

Jajj, hat veled ne kelljen soha egyutt dolgoznom. Latom mar, te vagy az a szigszalagos srac. ;)

Na, de mindegy, engem ennyivel nem alitasz meg. Folytassuk az argumentumkezelessel. ;)

Mondjuk en elegge utalom az elif-et, hacsak lehet kerulom, szerintem atlathatatlanna teszi a kodot. Arumentumokat egy while ciklusban case-zel szepen lehet kezelni es akkor a kapcsolok sorrenje se szamit (a te kododban pl a -h csak az elso helyen lehet):


DIR=""
while [ "$1" ]; do
  case "$1" in
    "-h"|"--help")
          usage
          exit 0
    "*")
          if [ "$DIR" ]; then
            usage
            exit 1
          else
            DIR=$1
          fi
  esac
  shift
done
DIR=${1:-.}

#!/bin/bash
# Extract subtitles from each MKV file in the given directory

usage()
{ 
  echo "$(basename $0 .sh) [options] [<filename1|dirname1>]"
}

sublist() {
:
}

subext() {
  local tracknumber
  local tracklanguage
  local subtitlename
  local subtypename
  local tracktype
  local extension
  local DIR=$1

  # Get all the MKV files in this dir and its subdirs
  find "$DIR" -type f -name '*.mkv' | while read filename
  do

    # Find out which tracks contain the subtitles
    # and get the number of the subtitle track 
    mkvmerge -i "$filename" | sed -n -e 's/^Track ID \([0-9]\+\): subtitles .*$/\1/p' | while read tracknumber
    do

      # Do a super-primitive language guess: ENGLISH
      # Corrected
      tracklanguage=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.* language:\([a-z]\{3\}\) .*/\1/p'`
      [ "$tracklanguage" ] || tracklanguage="unknown"

      # Get base name for subtitle
      subtitlename=${filename%.*}

      # Get type for subtitle
      subtypename=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.*(\(.*\)) .*/\1/p'`
      tracktype=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.*codec_id:\([a-zA-Z\/_]*\) .*/\1/p'`
      [ "$subtypename" ] || subtypename=`echo ${tracktype} | sed -n 's/^\(.*\)\/.*$/\1/p'`

      # Determine extension from the subtitle type
      extension=`echo ${tracktype} | sed -n 's/^.*\/\(.*\)$/\L\1/p'`
      [ "$extension" ] || extension=`echo ${subtypename} | sed -n 's/^.*\/\(.*\)$/\L\1/p'`
      [ "$extension" ] || extension="txt"

# Adobe Encore DCD | FAB Subtitle | SubCreator 1.x / .txt
# Advanced Sub Station Alpha / .ass
# AQ Title / .aqt
# DKS Subtitle Format / .dks
# Karaoke Lyrics LRC / .lrc
# Karaoke Lyrics VKT / .vkt
# MacSUB / .scr
# Micro DVD | MPSub | Sofni | SubViewer 1.0 | SubViewer 2.0 / .sub
# MPlayer | MPlayes2 / .mpl
# Panimator / .pan
# Phoenix Japanimation Society / .pjs
# Power DivX / .psb
# SubRip / .srt
# Sub Station Alpha / .ssa
# ViPlay Subtitle File / .vfs

      # Extract the track to a .tmp file
      mkvextract tracks "$filename" $tracknumber:"$subtitlename.$extension.tmp" > /dev/null 2>&1
      chmod g+rw "$subtitlename.$extension.tmp"

      # Rename to the final name
      mv "$subtitlename.$extension.tmp" "$subtitlename-t$tracknumber-$tracklanguage.$extension" > /dev/null 2>&1

    done
  done
}

if [ ! "$(whereis -b mkvmerge | sed -n 's/^.*: \(.*\)/\1/p')" ]; then
  usage
  echo
  echo "  mkvmerge not found!"
  exit 1
fi

LIST=
FILE="."

# set -x

while (($#));do
  case $1 in
    -h|--help|-help)
        usage
        exit 0
        ;;
    -l|--list|-list)
        LIST=1
        ;;
     *) if [ -e "$1" ]; then
          FILE="$1"
        else
          usage
          echo
          echo "  ERROR: file or directory does not exist $1"
          exit 1
       fi
       ;;
  esac
  shift
done

[ "$LIST" ] && sublist "$FILE" || subext "$FILE"

:/


sublist() {
  local filename
  local tracknumber
  local tracklanguage
  local tracktype
  local trackname
  local subtype
  local DIR=$1

  # Get all the MKV files in this dir and its subdirs
  find "$DIR" -type f -name '*.mkv' | sort | while read filename
  do
#    if mkvmerge -i "$filename" | grep -q "^Track ID [0-9]\+: subtitles"; then
      echo "`basename $filename`"
      mkvmerge -i "$filename" | sed -n -e 's/^Track ID \([0-9]\+\): subtitles .*$/\1/p' | while read tracknumber
      do
        # Get subtitle track properties
        subtype=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.*(\(.*\)) .*/\1/p'`
        tracklanguage=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.* language:\([a-z]\{3\}\) .*/\1/p'`
        trackname=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.*track_name:\(.*\) uid.*/\1/p'`
        tracktype=`mkvmerge -F verbose-text -i "$filename" | sed -n -e '/^Track ID '"$tracknumber"':/s/.*codec_id:\([a-zA-Z\/_]*\) .*/\1/p'`
        if [ ! "$tracktype" ]; then
           tracktype="$subtype"
           subtype=`echo $tracktype | sed -n 's/^\(.*\)\/.*/\1/p'`
        fi
        echo "  Track ID $tracknumber: language:$tracklanguage trackname:$trackname type:$subtype - $tracktype"
      done
      echo
#    fi
  done
}

ez még elég kusza :))
de


$ mkvsubext.sh -l
**********-S01E01-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S01E02-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S01E03-*.mkv
  Track ID 2: language:und trackname: type:SubRip - SubRip/SRT

**********-S01E04-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S01E05-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S01E06-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S01E07-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S01E08-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S01E09-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S01E10-*.mkv
  Track ID 2: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********-S02E00.mkv
  Track ID 2: language:eng trackname:English type:SubStationAlpha - S_TEXT/ASS
  Track ID 3: language:hun trackname:Hungarian type:SubRip - SubRip/SRT

**********.s02e01.***.mkv
  Track ID 2: language:eng trackname: type:SubStationAlpha - S_TEXT/ASS

**********.s02e02.***.mkv
  Track ID 2: language:eng trackname: type:SubStationAlpha - S_TEXT/ASS

$ mkvsubext.sh -l **********-S02E00.mkv 
**********-S02E00.mkv
  Track ID 2: language:eng trackname:English type:SubStationAlpha - S_TEXT/ASS
  Track ID 3: language:hun trackname:Hungarian type:SubRip - SubRip/SRT
$

Szerintem a csillag az idézőjelben nem jó, a while feltétele meg azért rossz, mert elakad a paraméterek feldolgozása, ha valaki betesz a paraméterek közé egy üres stringet. Inkább így csinálnám:

while [ $# -gt 0 ]; do

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Én ki szoktam írni az idézőjeleket, törekszem arra, hogy minél általánosabb legyen a scriptem. Ugyanakkor mindenre nem készülök fel, például arra, ha newline karakter van filenévben. Most próbáltam ki, meg lehet csinálni. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE