Subversion Repositories LCARS

Rev

Rev 20 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 20 Rev 21
1
#!/bin/sh
1
#!/bin/sh
2
appname="${0##*/}"
2
appname="${0##*/}"
3
ver="0.6.1.2006031907"
3
ver="0.6.1.2007011316"
4
copy="2005, 2006"
4
copy="2005-2007"
5
mail_feedback="dvd@PointedEars.de"
5
mail_feedback="dvd@PointedEars.de"
6
# ----------------------------------------------------------------------------
6
# ----------------------------------------------------------------------------
7
# DVD Subtitles 0.6.1 -- Extracts subtitles from Video DVD data to a text file
7
# DVD Subtitles 0.6.1 -- Extracts subtitles from DVD-Video data to a text file
8
# Copyright (C) 2005, 2006  Thomas Lahn <PointedEars@gmx.de>
8
# Copyright (C) 2005, 2006  Thomas Lahn <PointedEars@gmx.de>
9
#
9
#
10
#     This program is free software; you can redistribute it and/or modify it
10
#     This program is free software; you can redistribute it and/or modify it
11
#     under the terms of the GNU General Public License (GPL) as published
11
#     under the terms of the GNU General Public License (GPL) as published
12
#     by the Free Software Foundation; either version 2 of the License, or
12
#     by the Free Software Foundation; either version 2 of the License, or
13
#     (at your option) any later version.
13
#     (at your option) any later version.
14
#
14
#
15
#     This program is distributed in the hope that it will be useful,
15
#     This program is distributed in the hope that it will be useful,
16
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
16
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
17
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
#     GNU General Public License for more details.
18
#     GNU General Public License for more details.
19
#
19
#
20
#     You should have received a copy of the GNU GPL along with this
20
#     You should have received a copy of the GNU GPL along with this
21
#     program; if not, write to the Free Software Foundation, Inc.,
21
#     program; if not, write to the Free Software Foundation, Inc.,
22
#     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
22
#     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
23
#
23
#
24
## Standard shell script disclaimer blurb thing:
24
## Standard shell script disclaimer blurb thing:
25
##
25
##
26
## This script is a hack.  It's brute force.  It's horrible.
26
## This script is a hack.  It's brute force.  It's horrible.
27
## It doesn't use Artificial Intelligence.  It doesn't use Virtual Reality.
27
## It doesn't use Artificial Intelligence.  It doesn't use Virtual Reality.
28
## It's not perl.  It's not python.  It probably won't work unchanged on
28
## It's not perl.  It's not python.  It probably won't work unchanged on
29
## the "other" thousands of unices.  But it worksforme.  --ramiro
29
## the "other" thousands of unices.  But it worksforme.  --ramiro
30
# (from /usr/local/mozilla/run-mozilla.sh)
30
# (from /usr/local/mozilla/run-mozilla.sh)
31
#
31
#
32
#     This is work in progress.  If you have an improvement, patch,
32
#     This is work in progress.  If you have an improvement, patch,
33
#     idea, whatever, on how to make this script better, please
33
#     idea, whatever, on how to make this script better, please
34
#     send it to <dvd@PointedEars.de>
34
#     send it to <dvd@PointedEars.de>
35
35
36
_title ()
36
_title ()
37
{
37
{
38
  echo "\
38
  echo "\
39
${extd}DVD Subtitles $ver
39
${extd}DVD Subtitles $ver
40
Copyright (C) $copy  Thomas Lahn <$mail_feedback>$norm
40
Copyright (C) $copy  Thomas Lahn <$mail_feedback>$norm
41
Distributed under the terms of the GNU General Public License (GPL), see
41
Distributed under the terms of the GNU General Public License (GPL), see
42
COPYING file or http://www.gnu.org/licenses/licenses.html#GPL for details.
42
COPYING file or http://www.gnu.org/licenses/licenses.html#GPL for details.
43
"
43
"
44
}
44
}
45
45
46
_help ()
46
_help ()
47
{
47
{
48
  echo "\
48
  echo "\
49
Extracts a subtitle stream from Video DVD data and converts it to a text file.
49
Extracts a subtitle stream from DVD-Video data and converts it to a text file.
50

50

51
$extd$appname$norm [options] ${ital}SOURCE$norm
51
$extd$appname$norm [options] ${ital}SOURCE$norm
-
 
52

-
 
53
Deprecated:
52
$extd$appname$norm [$extd-hVkl$norm] [${ital}SOURCE$norm [${ital}TITLE$norm\
54
  $extd$appname$norm [$extd-hVkl$norm] [${ital}SOURCE$norm [${ital}TITLE$norm\
53
 [${ital}SUBTITLE$norm [${ital}TARGET$norm [${ital}GREY_LEVELS$norm]]]]]
55
 [${ital}SUBTITLE$norm [${ital}TARGET$norm [${ital}GREY_LEVELS$norm]]]]]
54
         
56
         
55
Any option argument is overwritten by the respective additional program
57
Any option argument is overwritten by the respective additional program
56
argument.  Options may be given in any order, and are also considered
58
argument.  Options may be given in any order, and are also considered
57
options if located after the first program argument.  Too many program
59
options if located after the first program argument.  Too many program
58
arguments are silently ignored.
60
arguments are silently ignored.
59

61

60
$extd-c$norm, $extd--compile$norm ${ital}FILE$norm | ${ital}DIRECTORY$norm
62
$extd-c$norm, $extd--compile$norm ${ital}FILE$norm | ${ital}DIRECTORY$norm
61
             Compile subtitle text files according to subtitle index\
63
             Compile subtitle text files according to subtitle index\
62
 ${ital}FILE$norm
64
 ${ital}FILE$norm
63
             or to subtitle index files in ${ital}DIRECTORY$norm to\
65
             or to subtitle index files in ${ital}DIRECTORY$norm to\
-
 
66
 ${ital}TARGET$norm.  Clean up
64
 ${ital}TARGET$norm.  Clean up if this is successful, then exit.
67
             if this is successful, then exit.
65

68

66
$extd-k$norm, $extd--keep$norm   Keep subtitle stream file even if\
69
$extd-k$norm, $extd--keep$norm   Keep subtitle stream file even if\
67
 conversion is successful.
70
 conversion is successful.
68

71

69
$extd-l$norm, $extd--list$norm   List subtitles for TITLE using\
72
$extd-l$norm, $extd--list$norm   List subtitles for TITLE using\
70
 ${extd}mplayer$norm(1) and exit.
73
 ${extd}mplayer$norm(1) and exit.
71
               If TITLE is not provided or \`$extd-$norm', list subtitles for
74
               If TITLE is not provided or \`$extd-$norm', list subtitles for
72
               title #2 (as title #1 may be an intro without subtitles)
75
               title #2 (as title #1 may be an intro without subtitles)
73
               and exit.
76
               and exit.
74

77

75
SOURCE       Video DVD data source, i.e. a device (usually /dev/dvd),
78
SOURCE       Video DVD data source, i.e. a device (usually /dev/dvd),
76
               a directory (e.g. one containing content created via
79
               a directory (e.g. one containing content created via
77
               ${extd}dvdbackup$norm(1)) or a Video DVD image file.
80
               ${extd}dvdbackup$norm(1)) or a Video DVD image file.
78
               If \`$extd-$norm', a previously created subtitle stream file\
81
               If \`$extd-$norm', a previously created subtitle stream file\
79
 named
82
 named
80
               ${extd}subtitle_stream-$norm*$extd-${norm}TITLE${extd}-${norm}SUBTITLE\
83
               ${extd}subtitle_stream-$norm*$extd-${norm}TITLE${extd}-${norm}SUBTITLE\
81
 in the current working
84
 in the current working
82
               directory will be used for only the stream-to-graphics-
85
               directory will be used for only the stream-to-graphics-
83
               to-text conversion instead.  Both TITLE and SUBTITLE
86
               to-text conversion instead.  Both TITLE and SUBTITLE
84
               must not be \`$extd-$norm' in that case.
87
               must not be \`$extd-$norm' in that case.
85
               The default is \`$extd/dev/dvd$norm'.
88
               The default is \`$extd/dev/dvd$norm'.
86

89

87
$extd-t$norm, $extd--title$norm
90
$extd-t$norm, $extd--title$norm
88
  TITLE        Number of the title (1-n) which will be accessed for
91
  TITLE        Number of the title (1-n) which will be accessed for
89
               subtitle stream extraction.  If left out or \`$extd-$norm', the
92
               subtitle stream extraction.  If left out or \`$extd-$norm', the
90
               program uses ${extd}mplayer$norm(1) to detect how many titles are
93
               program uses ${extd}mplayer$norm(1) to detect how many titles are
91
               available on the DVD data source and asks for the
94
               available on the DVD data source and asks for the
92
               title to be accessed.
95
               title to be accessed.
93

96

94
$extd-s$norm, $extd--subtitle-id$norm
97
$extd-s$norm, $extd--subtitle-id$norm
95
  SUBTITLE     ID of the subtitle stream to be extracted (0-n).
98
  SUBTITLE     ID of the subtitle stream to be extracted (0-n).
96
               If left out or \`$extd-$norm', the program uses its\
99
               If left out or \`$extd-$norm', the program uses its\
97
 ${extd}-l$norm option to detect
100
 ${extd}-l$norm option to detect
98
               which subtitles are available for the given TITLE and asks
101
               which subtitles are available for the given TITLE and asks
99
               for the ID to be used.
102
               for the ID to be used.
100

103

101
$extd-o$norm, $extd--output-target$norm
104
$extd-o$norm, $extd--output-target$norm
102
  TARGET       Name of the resulting subtitles text file.
105
  TARGET       Name of the resulting subtitles text file.
103
               If not provided, the file is named after the subtitle stream
106
               If not provided, the file is named after the subtitle stream
104
               file.  NOTE: Unlike previous versions, this version appends
107
               file.  NOTE: Unlike previous versions, this version appends
105
               the filename suffix $extd.srt$norm automagically ONLY in that\
108
               the filename suffix $extd.srt$norm automagically ONLY in that\
106
 case.
109
 case.
107
               
110
               
108
$extd-g$norm, $extd--grey-levels$norm
111
$extd-g$norm, $extd--grey-levels$norm
109
  GREY_LEVELS  Optional grey-levels value\
112
  GREY_LEVELS  Optional grey-levels value\
110
 (\`c0$extd,${norm}c1$extd,${norm}c2$extd,${norm}c3' with 0 <= cN <= 255,
113
 (\`c0$extd,${norm}c1$extd,${norm}c2$extd,${norm}c3' with 0 <= cN <= 255,
111
               where 0 is black and 255 is white) to be used for converting
114
               where 0 is black and 255 is white) to be used for converting
112
               the subtitle stream graphics to text via OCR.  The default is
115
               the subtitle stream graphics to text via OCR.  The default is
113
               \`${extd}255,255,0,255$norm'.  Unfortunately, the\
116
               \`${extd}255,255,0,255$norm'.  Unfortunately, the\
114
 ${extd}subtitle2pgm$norm program,
117
 ${extd}subtitle2pgm$norm program,
115
               which requires this value, appears to be poorly documented;
118
               which requires this value, appears to be poorly documented;
116
               if you find a more detailed, working documentation, please
119
               if you find a more detailed, working documentation, please
117
               refer to it and inform this program's author about it.
120
               refer to it and inform this program's author about it.
118

121

119
$extd-h$norm, $extd--help$norm     Display this help and exit.
122
$extd-h$norm, $extd--help$norm     Display this help and exit.
120
$extd-v$norm, $extd--verbose$norm  Be verbose.  The number of ${extd}-v$norm\
123
$extd-v$norm, $extd--verbose$norm  Be verbose.  The number of ${extd}-v$norm\
121
 options specify the level of
124
 options specify the level of
122
                 verbosity.
125
                 verbosity.
123
$extd-V$norm, $extd--version$norm  Display version information and exit.
126
$extd-V$norm, $extd--version$norm  Display version information and exit.
124
               
127
               
125
${extd}EXIT STATUS$norm
128
${extd}EXIT STATUS$norm
126
  ${extd}  0$norm  Successful program execution
129
  ${extd}  0$norm  Successful program execution
127
  ${extd}  1$norm  Error detecting/extracting subtitle stream, or cancelled
130
  ${extd}  1$norm  Error detecting/extracting subtitle stream, or cancelled
128
         without selecting a title number or subtitle ID
131
         without selecting a title number or subtitle ID
129
  ${extd}  2$norm  Unable to convert subtitle stream to image files
132
  ${extd}  2$norm  Unable to convert subtitle stream to image files
130
  ${extd}  3$norm  Cancelled due to ${extd}gocr$norm(1) error or without\
133
  ${extd}  3$norm  Cancelled due to ${extd}gocr$norm(1) error or without\
131
 entering another
134
 entering another
132
         grey-levels value
135
         grey-levels value
133
  ${extd}  4$norm  Unable to compile to text file
136
  ${extd}  4$norm  Unable to compile to text file
134
  ${extd}  5$norm  Unable to clean up
137
  ${extd}  5$norm  Unable to clean up
135
  ${extd}127$norm  Insufficient number of arguments / help was displayed
138
  ${extd}127$norm  Insufficient number of arguments / help was displayed
136
 
139
 
137
See the $extd$appname$norm(1) manpage for complete documentation."
140
See the $extd$appname$norm(1) manpage for complete documentation."
138
}
141
}
139
                                                     
142
                                                     
140
if test -z "$LINES" -o -z "$COLUMNS" ; then
143
if test -z "$LINES" -o -z "$COLUMNS" ; then
141
    eval `stty size 2>/dev/null | (read L C; \
144
    eval `stty size 2>/dev/null | (read L C; \
142
    echo LINES=${L:-24} COLUMNS=${C:-80})`
145
    echo LINES=${L:-24} COLUMNS=${C:-80})`
143
fi
146
fi
144
test $LINES   -eq 0 && LINES=24
147
test $LINES   -eq 0 && LINES=24
145
test $COLUMNS -eq 0 && COLUMNS=80
148
test $COLUMNS -eq 0 && COLUMNS=80
146
149
147
if test "$TERM" != "raw" && stty size >/dev/null 2>&1 ; then
150
if test "$TERM" != "raw" && stty size >/dev/null 2>&1 ; then
148
# esc=`echo -en "\033"`
151
# esc=`echo -en "\033"`
149
# extd="${esc}[1m"
152
# extd="${esc}[1m"
150
  extd=`tput bold 2>/dev/null`
153
  extd=`tput bold 2>/dev/null`
151
  ital=`tput sitm 2>/dev/null`
154
  ital=`tput sitm 2>/dev/null`
152
# norm=`echo -en "${esc}[m\017"`
155
# norm=`echo -en "${esc}[m\017"`
153
  norm=`tput sgr0 2>/dev/null`
156
  norm=`tput sgr0 2>/dev/null`
154
else
157
else
155
  esc=""
158
  esc=""
156
  extd=""
159
  extd=""
157
  norm=""
160
  norm=""
158
fi
161
fi
159
162
160
# Note that we use `"$@"' to let each command-line parameter expand to a
163
# Note that we use `"$@"' to let each command-line parameter expand to a
161
# separate word. The quotes around `$@' are essential!
164
# separate word. The quotes around `$@' are essential!
162
# We need `tmp' as the `eval set --' would nuke the return value of getopt.
165
# We need `tmp' as the `eval set --' would nuke the return value of getopt.
163
166
164
[ "$1" = "-vv" ] && echo "$extd
167
[ "$1" = "-vv" ] && echo "$extd
165
Debug output for POSIX conform command-line parsing
168
Debug output for POSIX conform command-line parsing
166

169

167
Original arguments: $*" >&2
170
Original arguments: $*" >&2
168
if `getopt -T >/dev/null 2>&1` ; [ $? = 4 ] ; then
171
if `getopt -T >/dev/null 2>&1` ; [ $? = 4 ] ; then
169
  getopt_type=long
172
  getopt_type=long
170
  [ "$1" = "-vv" ] && echo "getopt(1) type:     enhanced" >&2
173
  [ "$1" = "-vv" ] && echo "getopt(1) type:     enhanced" >&2
171
  tmp=`getopt -o c:klg:o:S::s:t:hVv \
174
  tmp=`getopt -o c:klg:o:S::s:t:hVv \
172
              -l compile:,keep-stream,list,grey-levels:,output-target:\
175
              -l compile:,keep-stream,list,grey-levels:,output-target:\
173
,spell-check,subtitle-id:,title:,help,verbose,version \
176
,spell-check,subtitle-id:,title:,help,verbose,version \
174
              -n "$appname" -s sh \
177
              -n "$appname" -s sh \
175
              -- "$@"`
178
              -- "$@"`
176
else
179
else
177
  getopt_type=short
180
  getopt_type=short
178
  [ "$1" = "-vv" ] && echo "getopt(1) type:     old" >&2
181
  [ "$1" = "-vv" ] && echo "getopt(1) type:     old" >&2
179
  tmp=`getopt c:klg:o:S:s:t:hVv "$@"`
182
  tmp=`getopt c:klg:o:S:s:t:hVv "$@"`
180
fi
183
fi
181
184
182
# exit status
185
# exit status
183
ESUCCESS=0
186
ESUCCESS=0
184
ECANTEXTRACT=1
187
ECANTEXTRACT=1
185
ECANTCONVERT=2
188
ECANTCONVERT=2
186
EOCRERROR=3
189
EOCRERROR=3
187
ECANTCOMPILE=4
190
ECANTCOMPILE=4
188
ECANTCLEANUP=5
191
ECANTCLEANUP=5
189
EARGERROR=127
192
EARGERROR=127
190
193
191
getopt_exit_code=$?
194
getopt_exit_code=$?
192
help=0
195
help=0
193
verbose=0
196
verbose=0
194
version=0
197
version=0
195
list=0
198
list=0
196
source='/dev/dvd'
199
source='/dev/dvd'
197
title='-'
200
title='-'
198
sid='-'
201
sid='-'
199
target='-'
202
target='-'
200
args=''
203
args=''
201
keep=0
204
keep=0
202
compile=0
205
compile=0
203
if [ $getopt_exit_code -eq 0 ]; then
206
if [ $getopt_exit_code -eq 0 ]; then
204
##     getopt  returns  error  code 0 for successful parsing, 1 if
207
##     getopt  returns  error  code 0 for successful parsing, 1 if
205
##     getopt(3) returns errors, 2 if it does not understand  its
208
##     getopt(3) returns errors, 2 if it does not understand  its
206
##     own parameters, 3 if an internal error occurs like out-of-
209
##     own parameters, 3 if an internal error occurs like out-of-
207
##     memory, and 4 if it is called with -T.
210
##     memory, and 4 if it is called with -T.
208
#
211
#
209
# Note the quotes around `$tmp': they are essential!
212
# Note the quotes around `$tmp': they are essential!
210
#  echo $tmp
213
#  echo $tmp
211
# remove "--"
214
# remove "--"
212
#  for i in $tmp; do if [ "$i" != "--" ]; then tmp2="${tmp2} $i"; fi; done
215
#  for i in $tmp; do if [ "$i" != "--" ]; then tmp2="${tmp2} $i"; fi; done
213
  eval set -- "$tmp"
216
  eval set -- "$tmp"
214
  [ "$1" = "-vv" ] && echo "New arguments:      $*$norm
217
  [ "$1" = "-vv" ] && echo "New arguments:      $*$norm
215
" >&2
218
" >&2
216
  while true ; do
219
  while true ; do
217
    case "$1" in
220
    case "$1" in
218
      -h | --help)
221
      -h | --help)
219
        help=1
222
        help=1
220
        shift;;
223
        shift;;
221
       
224
       
222
      -v | --verbose)
225
      -v | --verbose)
223
        let verbose++
226
        let verbose++
224
        shift;;
227
        shift;;
225
       
228
       
226
      -V | --version)
229
      -V | --version)
227
        version=1
230
        version=1
228
        shift;;
231
        shift;;
229
     
232
     
230
      -c | --compile)
233
      -c | --compile)
231
        compile=1
234
        compile=1
232
        source=$2
235
        source=$2
233
        shift 2;;
236
        shift 2;;
234
     
237
     
235
      -k | --keep)
238
      -k | --keep)
236
        keep=1
239
        keep=1
237
        shift;;
240
        shift;;
238
       
241
       
239
      -l | --list)
242
      -l | --list)
240
        list=1
243
        list=1
241
        shift;;
244
        shift;;
242
       
245
       
243
      -g | --grey-levels)
246
      -g | --grey-levels)
244
        grey_levels=$2
247
        grey_levels=$2
245
        shift 2;;
248
        shift 2;;
246
       
249
       
247
      -o | --output-target)
250
      -o | --output-target)
248
        target=$2
251
        target=$2
249
        shift 2;;
252
        shift 2;;
250
       
253
       
251
      -s | --subtitle-id)
254
      -s | --subtitle-id)
252
        sid=$2
255
        sid=$2
253
        shift 2;;
256
        shift 2;;
254
       
257
       
255
      -t | --title)
258
      -t | --title)
256
        title=$2
259
        title=$2
257
        shift 2;;
260
        shift 2;;
258
       
261
       
259
      --)
262
      --)
260
        shift
263
        shift
261
        break;;
264
        break;;
262
    esac
265
    esac
263
  done
266
  done
264
  [ -n "$*" ] && args=$args" $*"
267
  [ -n "$*" ] && args=$args" $*"
265
  set -- $args
268
  set -- $args
266
else
269
else
267
  [ $verbose -gt 1 ] && echo "getopt exited: $getopt_exit_code
270
  [ $verbose -gt 1 ] && echo "getopt exited: $getopt_exit_code
268
  " >&2
271
  " >&2
269
  if [ $getopt_exit_code -eq 1 -o $getopt_exit_code -eq 2 ]; then
272
  if [ $getopt_exit_code -eq 1 -o $getopt_exit_code -eq 2 ]; then
270
    help=1
273
    help=1
271
  else
274
  else
272
    exit $getopt_exit_code
275
    exit $getopt_exit_code
273
  fi
276
  fi
274
fi
277
fi
275
278
276
[ $list -eq 0 ] && _title
279
[ $list -eq 0 ] && _title
277
[ $version -eq 1 ] && exit $ESUCCESS
280
[ $version -eq 1 ] && exit $ESUCCESS
278
[ $help -eq 1 ] &&
281
[ $help -eq 1 ] &&
279
{
282
{
280
  _help "$0"
283
  _help "$0"
281
  exit $EARGERROR
284
  exit $EARGERROR
282
}
285
}
283
286
284
result=$ESUCCESS
287
result=$ESUCCESS
285
[ $compile -eq 0 ] &&
288
[ $compile -eq 0 ] &&
286
{
289
{
287
  [ -n "$1"                      ] && source=$1
290
  [ -n "$1"                      ] && source=$1
288
  [ -z "$title"       -a -n "$2" ] && title=$2
291
  [ -z "$title"       -a -n "$2" ] && title=$2
289
  [ -z "$sid"         -a -n "$3" ] && sid=$3
292
  [ -z "$sid"         -a -n "$3" ] && sid=$3
290
  [ -z "$target"      -a -n "$4" ] && target=$4
293
  [ -z "$target"      -a -n "$4" ] && target=$4
291
  [ -z "$grey_levels" -a -n "$5" ] && grey_levels=$5
294
  [ -z "$grey_levels" -a -n "$5" ] && grey_levels=$5
292
 
295
 
293
  getsubtitles ()
296
  getsubtitles ()
294
  {
297
  {
295
    mplayer -dvd-device "$1" -vo null -ao null -frames 0 \
298
    mplayer -dvd-device "$1" -vo null -ao null -frames 0 \
296
            -v "dvd://${2:-2}" 2>&1 |
299
            -v "dvd://${2:-2}" 2>&1 |
297
      sed -n '/sid/ s/^[^:]\{1,\}:[[:space:]]//p'
300
      sed -n '/sid/ s/^[^:]\{1,\}:[[:space:]]//p'
298
  # echo "$subtitles"
301
  # echo "$subtitles"
299
  }
302
  }
300
 
303
 
301
  [ $list -eq 1 ] &&
304
  [ $list -eq 1 ] &&
302
  {
305
  {
303
    # first title may be only an intro
306
    # first title may be only an intro
304
    [ "$title" = '-' ] && title=2
307
    [ "$title" = '-' ] && title=2
305
    tmp=`getsubtitles $source $title`
308
    tmp=`getsubtitles $source $title`
306
    if [ -n "$tmp" ]; then
309
    if [ -n "$tmp" ]; then
307
      echo "${extd}The following subtitles are available for title #$title:$norm
310
      echo "${extd}The following subtitles are available for title #$title:$norm
308
$tmp"
311
$tmp"
309
      exit $ESUCCESS
312
      exit $ESUCCESS
310
    else
313
    else
311
      exit $ECANTEXTRACT
314
      exit $ECANTEXTRACT
312
    fi
315
    fi
313
  }
316
  }
314
317
315
  [ "$sid" != '-' -a "$title" != '-' ] &&
318
  [ "$sid" != '-' -a "$title" != '-' ] &&
316
  {
319
  {
317
    subtitles=`getsubtitles $source $title`
320
    subtitles=`getsubtitles $source $title`
318
    [ -n "$subtitles" ] &&
321
    [ -n "$subtitles" ] &&
319
      st_descr=`echo "$subtitles" | grep "^$sid[[:space:]]" |
322
      st_descr=`echo "$subtitles" | grep "^$sid[[:space:]]" |
320
                  cut -f 2- -d ' '`
323
                  cut -f 2- -d ' '`
321
  }
324
  }
322
 
325
 
323
  if [ "$source" = '-' ]; then
326
  if [ "$source" = '-' ]; then
324
    stream_file=`ls subtitle_stream-*-$title-$sid 2>/dev/null | head -n 1`
327
    stream_file=`ls subtitle_stream-*-$title-$sid 2>/dev/null | head -n 1`
325
    if [ $? -eq 0 ]; then
328
    if [ $? -eq 0 ]; then
326
      read -r -s -p "Use '$stream_file' [Y/n]? " -n 1
329
      read -r -s -p "Use '$stream_file' [Y/n]? " -n 1
327
      case $REPLY in
330
      case $REPLY in
328
        [Nn])
331
        [Nn])
329
          echo $REPLY
332
          echo $REPLY
330
          exit 1;;
333
          exit 1;;
331
        *)
334
        *)
332
          echo Y
335
          echo Y
333
      esac
336
      esac
334
      echo
337
      echo
335
   
338
   
336
      id=${stream_file#*-}
339
      id=${stream_file#*-}
337
    else
340
    else
338
      echo "$appname: No such file: subtitle_stream-*-$title-$sid" >&2
341
      echo "$appname: No such file: subtitle_stream-*-$title-$sid" >&2
339
      exit $ECANTEXTRACT
342
      exit $ECANTEXTRACT
340
    fi
343
    fi
341
  else
344
  else
342
    read_error ()
345
    read_error ()
343
    {
346
    {
344
      case $1 in
347
      case $1 in
345
        0) subject='titles available on this DVD source.';;
348
        0) subject='titles available on this DVD source.';;
346
        *) subject='subtitles available for this title.';;
349
        *) subject='subtitles available for this title.';;
347
      esac
350
      esac
348
351
349
      echo >&2 "\
352
      echo >&2 "\
350
Sorry, there are no $subject
353
Sorry, there are no $subject
351
Please verify that the DVD data source is available and
354
Please verify that the DVD data source is available and
352
that its filesystem is consistent."
355
that its filesystem is consistent."
353
356
354
      unset subject
357
      unset subject
355
      exit $ECANTEXTRACT
358
      exit $ECANTEXTRACT
356
    }
359
    }
357
   
360
   
358
    if [ "$title" = '-' ]; then
361
    if [ "$title" = '-' ]; then
359
      titles=`mplayer -dvd-device "$source" -vo null -ao null -frames 0 \
362
      titles=`mplayer -dvd-device "$source" -vo null -ao null -frames 0 \
360
                      -v dvd:// 2>&1 | egrep '[0-9]+ titles'`
363
                      -v dvd:// 2>&1 | egrep '[0-9]+ titles'`
361
      num_titles=`echo "$titles" | awk '{print $3}'`
364
      num_titles=`echo "$titles" | awk '{print $3}'`
362
 
365
 
363
      [ $(($num_titles)) -lt 1 ] && read_error 0
366
      [ $(($num_titles)) -lt 1 ] && read_error 0
364
 
367
 
365
      echo "$titles"
368
      echo "$titles"
366
      while true
369
      while true
367
      do
370
      do
368
        read -r -p "\
371
        read -r -p "\
369
${extd}Enter title# (1-$num_titles), or nothing to abort: $norm"
372
${extd}Enter title# (1-$num_titles), or nothing to abort: $norm"
370
        if [ -n "$REPLY" ]; then
373
        if [ -n "$REPLY" ]; then
371
          title=$(($REPLY))
374
          title=$(($REPLY))
372
          [ $title -ge 1 -a $title -le $num_titles ] && break
375
          [ $title -ge 1 -a $title -le $num_titles ] && break
373
        else
376
        else
374
          exit $ECANTEXTRACT
377
          exit $ECANTEXTRACT
375
        fi
378
        fi
376
      done
379
      done
377
      echo
380
      echo
378
    fi
381
    fi
379
 
382
 
380
    if [ "$sid" = '-' ]; then
383
    if [ "$sid" = '-' ]; then
381
      if [ -z "$subtitles" ]; then subtitles=`"$0" -lt "$title" "$source"`; fi
384
      if [ -z "$subtitles" ]; then subtitles=`"$0" -lt "$title" "$source"`; fi
382
      if [ $? -eq 0 ]; then
385
      if [ $? -eq 0 ]; then
383
        sid_max=`echo "$subtitles" | tail -n 1 | awk '{print $1}'`      
386
        sid_max=`echo "$subtitles" | tail -n 1 | awk '{print $1}'`      
384
        echo "$subtitles"
387
        echo "$subtitles"
385
        while true; do
388
        while true; do
386
          read -r -p "\
389
          read -r -p "\
387
${extd}Enter ID of subtitle stream (0-$sid_max) to extract, or nothing to abort: $norm"
390
${extd}Enter ID of subtitle stream (0-$sid_max) to extract, or nothing to abort: $norm"
388
          if [ -n "$REPLY" ]; then
391
          if [ -n "$REPLY" ]; then
389
            sid=$(($REPLY))
392
            sid=$(($REPLY))
390
            [ $sid -ge 0 -a $sid -lt $sid_max ] && break
393
            [ $sid -ge 0 -a $sid -lt $sid_max ] && break
391
          else
394
          else
392
            exit $ECANTEXTRACT
395
            exit $ECANTEXTRACT
393
          fi
396
          fi
394
        done
397
        done
395
      else
398
      else
396
        read_error 1
399
        read_error 1
397
      fi
400
      fi
398
    fi
401
    fi
399
 
402
 
400
    # remove trailing /
403
    # remove trailing /
401
    source=${source%/}
404
    source=${source%/}
402
 
405
 
403
    vol=`(echo $(volname $source 2>/dev/null); exit $?;) || echo ${source##*/}`
406
    vol=`(echo $(volname $source 2>/dev/null); exit $?;) || echo ${source##*/}`
404
    id=$vol-$title-$sid
407
    id=$vol-$title-$sid
405
    stream_file=subtitle_stream-$id
408
    stream_file=subtitle_stream-$id
406
   
409
   
407
    unset REPLY
410
    unset REPLY
408
    [ -f "$stream_file" ] &&
411
    [ -f "$stream_file" ] &&
409
    {
412
    {
410
      read -r -s -p "${extd}Use existing '$stream_file' [Y/n]? $norm" -n 1
413
      read -r -s -p "${extd}Use existing '$stream_file' [Y/n]? $norm" -n 1
411
      case $REPLY in
414
      case $REPLY in
412
        [Nn])
415
        [Nn])
413
          echo $REPLY
416
          echo $REPLY
414
          read -r -s -p "${extd}Overwrite existing '$stream_file' [y/N]? $norm"\
417
          read -r -s -p "${extd}Overwrite existing '$stream_file' [y/N]? $norm"\
415
               -n 1 REPLY2
418
               -n 1 REPLY2
416
          case $REPLY2 in
419
          case $REPLY2 in
417
            [Yy]) echo $REPLY2;;
420
            [Yy]) echo $REPLY2;;
418
            *)
421
            *)
419
              echo N
422
              echo N
420
              id=$vol-$title-$sid-$$
423
              id=$vol-$title-$sid-$$
421
              stream_file=subtitle_stream-$id
424
              stream_file=subtitle_stream-$id
422
              echo "Using '$stream_file'"
425
              echo "Using '$stream_file'"
423
          esac
426
          esac
424
          echo
427
          echo
425
          unset REPLY2;;
428
          unset REPLY2;;
426
        *)
429
        *)
427
          echo Y
430
          echo Y
428
          REPLY='y'
431
          REPLY='y'
429
      esac
432
      esac
430
      echo
433
      echo
431
    }
434
    }
432
   
435
   
433
    [ "$target" = '-' ] && target="$stream_file.srt"
436
    [ "$target" = '-' ] && target="$stream_file.srt"
434
         
437
         
435
    [ -z "$REPLY" -o "$REPLY" == 'N' -o "$REPLY" == 'n' ] &&
438
    [ -z "$REPLY" -o "$REPLY" == 'N' -o "$REPLY" == 'n' ] &&
436
    {
439
    {
437
      echo "\
440
      echo "\
438
${extd}Extracting subtitle stream $norm$sid${st_descr:+ ($st_descr)}$extd
441
${extd}Extracting subtitle stream $norm$sid${st_descr:+ ($st_descr)}$extd
439
of title $norm#$title$extd
442
of title $norm#$title$extd
440
on $norm$source$extd
443
on $norm$source$extd
441
to \"$norm$target$extd\" ...$norm
444
to \"$norm$target$extd\" ...$norm
442
" >&2
445
" >&2
443
     
446
     
444
      > "$stream_file"
447
      > "$stream_file"
445
      tccat -i "$source" -T "$title" -L |
448
      tccat -i "$source" -T "$title" -L |
446
        tcextract -x ps1 -t vob -a 0x2$sid > "$stream_file"
449
        tcextract -x ps1 -t vob -a 0x2$sid > "$stream_file"
447
    }
450
    }
448
  fi
451
  fi
449
 
452
 
450
  if [ -f "$stream_file" -a -s "$stream_file" ]; then
453
  if [ -f "$stream_file" -a -s "$stream_file" ]; then
451
    echo "${extd}... done.$norm"
454
    echo "${extd}... done.$norm"
452
  else
455
  else
453
    echo "${extd}... failed.$norm"
456
    echo "${extd}... failed.$norm"
454
    [ -f "$stream_file" ] && rm ./"$stream_file"
457
    [ -f "$stream_file" ] && rm ./"$stream_file"
455
    exit $ECANTEXTRACT
458
    exit $ECANTEXTRACT
456
  fi
459
  fi
457
 
460
 
458
  result=$ESUCCESS
461
  result=$ESUCCESS
459
  while true
462
  while true
460
  do
463
  do
461
    echo -n "
464
    echo -n "
462
${extd}Converting subtitle stream \"$norm$stream_file$extd\"
465
${extd}Converting subtitle stream \"$norm$stream_file$extd\"
463
to Netpbm Portable Greymaps (PGMs) ... $norm" | fold -s >&2
466
to Netpbm Portable Greymaps (PGMs) ... $norm" | fold -s >&2
464
    subtitle2pgm -o ./${id}- ${grey_levels:+-c "$grey_levels"} < $stream_file
467
    subtitle2pgm -o ./${id}- ${grey_levels:+-c "$grey_levels"} < $stream_file
465
    result=$?
468
    result=$?
466
    if [ $result -eq 0 ]; then
469
    if [ $result -eq 0 ]; then
467
      echo "${extd}done.$norm
470
      echo "${extd}done.$norm
468
 
471
 
469
${extd}Converting PGMs to text files (TXTs) using GNU OCR (gocr) ... $norm"
472
${extd}Converting PGMs to text files (TXTs) using GNU OCR (gocr) ... $norm"
470
      st_lang=$(echo "$st_descr" | sed 's/.*language: \([a-z]\{2\}\)/\1/')
473
      st_lang=$(echo "$st_descr" | sed 's/.*language: \([a-z]\{2\}\)/\1/')
471
      pgm2txt ${st_lang:+-f $st_lang} ./${id}-
474
      pgm2txt ${st_lang:+-f $st_lang} ./${id}-
472
      result=$?
475
      result=$?
473
      if [ $result -eq 0 ]; then
476
      if [ $result -eq 0 ]; then
474
        echo "${extd}done, using a grey-levels value of\
477
        echo "${extd}done, using a grey-levels value of\
475
 \`$norm${grey_levels:-255,255,0,255}$extd'.$norm"
478
 \`$norm${grey_levels:-255,255,0,255}$extd'.$norm"
476
        break
479
        break
477
      else
480
      else
478
        echo "${extd}failed.
481
        echo "${extd}failed.
479
 
482
 
480
If the conversion was cancelled due to inappropriate grey-levels value
483
If the conversion was cancelled due to inappropriate grey-levels value
481
\`${grey_levels:-255,255,0,255}', you may try another value,\
484
\`${grey_levels:-255,255,0,255}', you may try another value,\
482
 else you should abort:
485
 else you should abort:
483
$norm"
486
$norm"
484
        select grey_levels in \
487
        select grey_levels in \
485
            `[ "$grey_levels" != '0,255,255,255' ] && echo 0,255,255,255` \
488
            `[ "$grey_levels" != '0,255,255,255' ] && echo 0,255,255,255` \
486
            `[ "$grey_levels" != '255,0,255,255' ] && echo 255,0,255,255` \
489
            `[ "$grey_levels" != '255,0,255,255' ] && echo 255,0,255,255` \
487
            `[ -n "$grey_levels" -a "$grey_levels" != '255,255,0,255' ] &&
490
            `[ -n "$grey_levels" -a "$grey_levels" != '255,255,0,255' ] &&
488
              echo 255,255,0,255` \
491
              echo 255,255,0,255` \
489
            `[ "$grey_levels" != '255,255,255,0' ] && echo 255,255,255,0` \
492
            `[ "$grey_levels" != '255,255,255,0' ] && echo 255,255,255,0` \
490
            Other \
493
            Other \
491
            Abort
494
            Abort
492
        do
495
        do
493
          case $grey_levels in
496
          case $grey_levels in
494
            Other)
497
            Other)
495
              read -r -p "
498
              read -r -p "
496
${extd}Enter new value (\`c0$extd,${norm}c1$extd,${norm}c2$extd,${norm}c3'\
499
${extd}Enter new value (\`c0$extd,${norm}c1$extd,${norm}c2$extd,${norm}c3'\
497
 with 0 <= cN <= 255), or nothing to select a value:
500
 with 0 <= cN <= 255), or nothing to select a value:
498
$norm" grey_levels
501
$norm" grey_levels
499
              [ -n "$grey_levels" ] && break;;
502
              [ -n "$grey_levels" ] && break;;
500
             
503
             
501
            Abort)
504
            Abort)
502
              result=$EOCRERROR
505
              result=$EOCRERROR
503
              break;;
506
              break;;
504
 
507
 
505
            *)
508
            *)
506
              break
509
              break
507
          esac
510
          esac
508
        done
511
        done
509
      fi
512
      fi
510
    else
513
    else
511
      echo "${extd}failed.$norm"
514
      echo "${extd}failed.$norm"
512
      result=$ECANTCONVERT
515
      result=$ECANTCONVERT
513
      break
516
      break
514
    fi
517
    fi
515
  done
518
  done
516
 
519
 
517
  echo -n "${extd}Cleaning up PGMs ... $norm"
520
  echo -n "${extd}Cleaning up PGMs ... $norm"
518
  rm ./${id}-*.pgm
521
  rm ./${id}-*.pgm
519
  if [ $? -eq 0 ]; then
522
  if [ $? -eq 0 ]; then
520
    echo "${extd}done.$norm"
523
    echo "${extd}done.$norm"
521
  else
524
  else
522
    echo "${extd}failed.$norm"
525
    echo "${extd}failed.$norm"
523
  fi
526
  fi
524
}
527
}
525

528

526
[ $result -eq $ESUCCESS ] &&
529
[ $result -eq $ESUCCESS ] &&
527
{
530
{
528
  if [ $compile -eq 1 ]; then
531
  if [ $compile -eq 1 ]; then
529
    try_file ()
532
    try_file ()
530
    {
533
    {
531
      [ ! -f "$source" ] && source="$source.srtx"
534
      [ ! -f "$source" ] && source="$source.srtx"
532
      [ -f "$source" ]
535
      [ -f "$source" ]
533
    }
536
    }
534
 
537
 
535
    if [ -d "$source" ]; then
538
    if [ -d "$source" ]; then
536
# TODO: loop through all .srtx files in the directory
539
# TODO: loop through all .srtx files in the directory
537
      if [ "$source" != '.' ]; then cd "$source"; fi
540
      if [ "$source" != '.' ]; then cd "$source"; fi
538
      [ $? -eq 0 ] &&
541
      [ $? -eq 0 ] &&
539
      {
542
      {
540
        ls "$source"/*.srtx 2>/dev/null
543
        ls "$source"/*.srtx 2>/dev/null
541
      }
544
      }
542
      echo >&2 "$appname: $source: Directory compile is not yet supported."
545
      echo >&2 "$appname: $source: Directory compile is not yet supported."
543
      exit $ECANTCOMPILE
546
      exit $ECANTCOMPILE
544
    elif try_file; then
547
    elif try_file; then
545
      d=${source%/*}
548
      d=${source%/*}
546
      if [ -a -d "$d" -a "$d" != '.' ]; then cd "$d"; fi
549
      if [ -a -d "$d" -a "$d" != '.' ]; then cd "$d"; fi
547
      id=${source%-*}
550
      id=${source%-*}
548
      stream_file=subtitle_stream-$id
551
      stream_file=subtitle_stream-$id
549
      source="./${source##*/}"
552
      source="./${source##*/}"
550
    else
553
    else
551
      echo >&2 "$appname: $source: No such file or directory."
554
      echo >&2 "$appname: $source: No such file or directory."
552
      exit $ECANTCOMPILE
555
      exit $ECANTCOMPILE
553
    fi
556
    fi
554
  else
557
  else
555
    source="${id}-.srtx"
558
    source="${id}-.srtx"
556
  fi
559
  fi
557
 
560
 
558
  unset REPLY
561
  unset REPLY
559
  [ -f "$target" ] &&
562
  [ -f "$target" ] &&
560
  {
563
  {
561
# TODO: allow for diff
564
# TODO: allow for diff
562
    read -r -s -p "${extd}'$target' exists.
565
    read -r -s -p "${extd}'$target' exists.
563
Append, overwrite, create new file, or abort [a/o/n/Esc]? $norm" \
566
Append, overwrite, create new file, or abort [a/o/n/Esc]? $norm" \
564
         -n 1
567
         -n 1
565
    case $REPLY in
568
    case $REPLY in
566
      [Oo]) echo $REPLY;;
569
      [Oo]) echo $REPLY;;
567
      [Aa]) echo $REPLY;;
570
      [Aa]) echo $REPLY;;
568
      [Nn])
571
      [Nn])
569
        echo $REPLY
572
        echo $REPLY
570
        target="${target%.*}-$$.${target##*.}";;
573
        target="${target%.*}-$$.${target##*.}";;
571
      *)
574
      *)
572
        REPLY=Abort
575
        REPLY=Abort
573
        echo $REPLY
576
        echo $REPLY
574
        exit $ECANTCOMPILE;;
577
        exit $ECANTCOMPILE;;
575
    esac
578
    esac
576
  }
579
  }
577
 
580
 
578
  echo "
581
  echo "
579
${extd}Compiling TXTs into \"$norm$target$extd\" ... $norm"
582
${extd}Compiling TXTs into \"$norm$target$extd\" ... $norm"
580

583

581
  case "$REPLY" in
584
  case "$REPLY" in
582
    [Oo]) > "$target";;
585
    [Oo]) > "$target";;
583
    [Aa])
586
    [Aa])
584
      # append new content marker here
587
      # append new content marker here
585
      echo "
588
      echo "
586
-- `whoami`@`hostname` -- `date` --
589
-- `whoami`@`hostname` -- `date` --
587
" >> "$target"
590
" >> "$target"
588
  esac
591
  esac
589
592
590
  (
593
  (
591
# sed: thx to Erkan Yanar <erkan.yanar@t-online.de>, see
594
# sed: thx to Erkan Yanar <erkan.yanar@t-online.de>, see
592
# message ID <lduohb.v74.ln@510002093148-0001.dialin.t-online.de>
595
# message ID <lduohb.v74.ln@510002093148-0001.dialin.t-online.de>
593
    srttool -s -i "$source"
596
    srttool -s -i "$source"
594
597
595
    # only if srttool is not available
598
    # only if srttool is not available
596
    if [ $? -gt 1 ]; then
599
    if [ $? -gt 1 ]; then
597
      sed -n 's,^\(\([^/]*\)\(/\)\(.*\.pgm\.txt\)\)$,/^\2\\\3\4$/ { \
600
      sed -n 's,^\(\([^/]*\)\(/\)\(.*\.pgm\.txt\)\)$,/^\2\\\3\4$/ { \
598
          r \1 \
601
          r \1 \
599
          d \
602
          d \
600
        },gp' "$source" | sed -f - "$source"
603
        },gp' "$source" | sed -f - "$source"
601
    fi
604
    fi
602
  ) >> "$target"
605
  ) >> "$target"
603
606
604
  if [ $? -eq 0 ]; then
607
  if [ $? -eq 0 ]; then
605
    echo "${extd}... done.$norm"
608
    echo "${extd}... done.$norm"
606
  else
609
  else
607
    echo "${extd}... failed.$norm"
610
    echo "${extd}... failed.$norm"
608
    exit $ECANTCOMPILE
611
    exit $ECANTCOMPILE
609
  fi
612
  fi
610
613
611
  echo -n "${extd}Cleaning up
614
  echo -n "${extd}Cleaning up
612
  ${id}-*.pgm.txt files ... $norm"
615
  ${id}-*.pgm.txt files ... $norm"
613
  rm ./"${id}"-*.pgm.txt
616
  rm ./"${id}"-*.pgm.txt
614
  if [ $? -eq 0 ]; then
617
  if [ $? -eq 0 ]; then
615
    echo "${extd}done.$norm"
618
    echo "${extd}done.$norm"
616
  else
619
  else
617
    echo "${extd}failed.$norm"
620
    echo "${extd}failed.$norm"
618
    result=$ECANTCLEANUP
621
    result=$ECANTCLEANUP
619
  fi
622
  fi
620
 
623
 
621
  echo -n "  ${extd}Subtitle index file '${id}-.srtx' ... $norm"
624
  echo -n "  ${extd}Subtitle index file '${id}-.srtx' ... $norm"
622
  rm ./"${id}-.srtx" # "$target.srtx"
625
  rm ./"${id}-.srtx" # "$target.srtx"
623
  if [ $? -eq 0 ]; then
626
  if [ $? -eq 0 ]; then
624
    echo "${extd}done.$norm"
627
    echo "${extd}done.$norm"
625
  else
628
  else
626
    echo "${extd}failed.$norm"
629
    echo "${extd}failed.$norm"
627
    result=$ECANTCLEANUP
630
    result=$ECANTCLEANUP
628
  fi
631
  fi
629
   
632
   
630
  [ $keep -eq 0 -a -f "./$stream_file" ] &&
633
  [ $keep -eq 0 -a -f "./$stream_file" ] &&
631
  {
634
  {
632
    echo -n "  ${extd}Subtitle stream file '${stream_file}' ... $norm"
635
    echo -n "  ${extd}Subtitle stream file '${stream_file}' ... $norm"
633
    rm ./"$stream_file"
636
    rm ./"$stream_file"
634
   
637
   
635
    if [ $? -eq 0 ]; then
638
    if [ $? -eq 0 ]; then
636
      echo "${extd}done.$norm"
639
      echo "${extd}done.$norm"
637
    else
640
    else
638
      echo "${extd}failed.$norm"
641
      echo "${extd}failed.$norm"
639
      result=$ECANTCLEANUP
642
      result=$ECANTCLEANUP
640
    fi
643
    fi
641
  }
644
  }
642
645
643
  exit $result
646
  exit $result
644
}
647
}
645
 
648