Subversion Repositories LCARS

Rev

Rev 21 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 21 Rev 198
1
#!/bin/sh
1
#!/bin/sh
2
appname="${0##*/}"
2
appname="${0##*/}"
3
ver="0.6.1.2007011316"
3
ver="0.6.1.2007011316"
4
copy="2005-2007"
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 DVD-Video 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 DVD-Video 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

52

53
Deprecated:
53
Deprecated:
54
  $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\
55
 [${ital}SUBTITLE$norm [${ital}TARGET$norm [${ital}GREY_LEVELS$norm]]]]]
55
 [${ital}SUBTITLE$norm [${ital}TARGET$norm [${ital}GREY_LEVELS$norm]]]]]
56
         
56
         
57
Any option argument is overwritten by the respective additional program
57
Any option argument is overwritten by the respective additional program
58
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
59
options if located after the first program argument.  Too many program
59
options if located after the first program argument.  Too many program
60
arguments are silently ignored.
60
arguments are silently ignored.
61

61

62
$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
63
             Compile subtitle text files according to subtitle index\
63
             Compile subtitle text files according to subtitle index\
64
 ${ital}FILE$norm
64
 ${ital}FILE$norm
65
             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
66
 ${ital}TARGET$norm.  Clean up
67
             if this is successful, then exit.
67
             if this is successful, then exit.
68

68

69
$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\
70
 conversion is successful.
70
 conversion is successful.
71

71

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

77

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

89

90
$extd-t$norm, $extd--title$norm
90
$extd-t$norm, $extd--title$norm
91
  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
92
               subtitle stream extraction.  If left out or \`$extd-$norm', the
92
               subtitle stream extraction.  If left out or \`$extd-$norm', the
93
               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
94
               available on the DVD data source and asks for the
94
               available on the DVD data source and asks for the
95
               title to be accessed.
95
               title to be accessed.
96

96

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

103

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

121

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

169

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

528

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

583

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