1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 let _s x
= _s "Subconv" x
27 let _b x
= _b "Subconv" x
30 FrameInterval
of float * float
33 let framerate = ref 24.
34 let split_frame = ref None
35 let delay_frame = ref 0.
36 let concat_frame = ref None
39 let s = input_line ic
in
40 let len = String.length
s in
41 if len > 0 && s.[len-1] = '
\r'
then
42 String.sub
s 0 (len-1)
49 lprintf
"Error in int_of_string: [%s]\n" s;
52 (*************************************************************************)
56 (*************************************************************************)
58 let srt_time_of_frame frame
=
59 let time = frame
/. !framerate in
60 Printf.sprintf
"%02d:%02d:%02d,%03d"
61 (int_of_float
(time /. 3600.))
62 (int_of_float
(time /. 60.) mod 60)
63 (int_of_float
time mod 60)
64 (int_of_float
(time *. 1000.) mod 1000)
66 let frame_of_srt_time time =
68 match String2.split_simplify
time '
:'
with
69 hours
:: mins
:: secs
:: [] ->
70 let hours = int_of_string hours in
71 let mins = int_of_string mins in
73 match String2.split_simplify
secs '
,'
with
75 int_of_string secs, int_of_string msecs
76 | _
-> raise Not_found
78 ((float_of_int
hours *. 3600. +.
79 float_of_int
mins *. 60. +.
81 float_of_int msecs
/. 1000.) *. !framerate)
82 | _
-> raise Not_found
85 failwith
(Printf.sprintf
"Bad time format [%s]" time)
87 (*************************************************************************)
91 (*************************************************************************)
93 let fprintf_sub oc
(pos
, lines
) frame_offset
=
97 FrameInterval
(frame1, frame2
) ->
101 let frame1 = frame1 +. !delay_frame in
102 let frame2 = frame2 +. !delay_frame in
104 let line = String2.unsplit lines '
|'
in
106 Printf.fprintf oc
"{%d}{%d}%s\n"
107 (int_of_float
(frame1 -. frame_offset
))
108 (int_of_float
(frame2 -. frame_offset
)) line
110 let fprintf_srt oc i
(pos
, lines
) frame_offset
=
114 FrameInterval
(frame1, frame2) ->
118 let frame1 = frame1 +. !delay_frame in
119 let frame2 = frame2 +. !delay_frame in
121 Printf.fprintf oc
"%d\n" i
;
122 Printf.fprintf oc
"%s --> %s\n"
124 (frame1 -. frame_offset
))
126 (frame2 -. frame_offset
));
127 List.iter
(fun line ->
128 Printf.fprintf oc
"%s\n" line) lines
;
129 Printf.fprintf oc
"\n"
131 let output_frames file frame_begin frame_end frame_offset
=
133 match Filename2.last_extension file
with
136 let oc = open_out file
in
138 List.iter
(fun (pos
, lines
) ->
141 FrameInterval
(frame1, frame2) ->
145 let frame1 = frame1 +. !delay_frame in
146 let frame2 = frame2 +. !delay_frame in
148 if frame1 < frame_end
&& frame2 > frame_begin
then
150 fprintf_sub oc (pos
,lines
) frame_offset
157 let oc = open_out file
in
159 let rec iter i list
=
162 | (pos
, lines
) :: tail
->
166 FrameInterval
(frame1, frame2) ->
170 let frame1 = frame1 +. !delay_frame in
171 let frame2 = frame2 +. !delay_frame in
173 if frame1 < frame_end
&& frame2 > frame_begin
then begin
175 fprintf_srt oc i
(pos
,lines
) frame_offset
;
184 | e
-> lprintf
"Unknown extension [%s]\n" e
; exit
2
186 (*************************************************************************)
190 (*************************************************************************)
192 let read_frames file
concat_frame =
194 match Filename2.last_extension file
with
197 let subtitles = ref [] in
198 let ic = open_in file
in
201 let line = input_line ic in
203 let pos1 = String.index
line '
}'
in
204 let pos2 = String.index_from
line (pos1+1) '
}'
in
206 let frame1 = int_of_string (String.sub
line 1 (pos1 - 1)) in
207 let frame2 = int_of_string (String.sub
line
208 (pos1+2) (pos2 - pos1 - 2)) in
210 let sub = String.sub line (pos2+1) (String.length
line - pos2 - 1) in
211 let lines = String2.split
sub '
|'
in
213 subtitles := (FrameInterval
(
214 concat_frame +. float_of_int
frame1,
215 concat_frame +. float_of_int
frame2), lines) ::
220 | e
-> close_in
ic; raise e
227 let subtitles = ref [] in
228 let ic = open_in file
in
232 let line = input_line ic in
233 let i = int_of_string line in
235 let line = input_line ic in
237 match String2.split
line ' '
with
238 time1
:: _
:: time2
:: [] ->
240 concat_frame +. frame_of_srt_time time1
,
241 concat_frame +. frame_of_srt_time time2
244 failwith
(Printf.sprintf
"Bad line [%s]\n" line)
248 let line = input_line ic in
249 if line = "" then List.rev list
else
252 let lines = iter [] in
254 subtitles := (FrameInterval
(frame1, frame2), lines) ::
259 | e
-> close_in
ic; raise e
263 | e
-> lprintf
"Unknown extension [%s]\n" e
; exit
2
265 (*************************************************************************)
269 (*************************************************************************)
274 "-from", Arg2.String
(fun file
->
275 argument := read_frames file
0.;
276 ), " <filename>: read <filename> subtitle file (.sub or .srt file)";
278 "-framerate", Arg2.Float
(fun f
-> framerate := f
),
279 " <framerate>: set the framerate (nb frames/second)";
281 "-delay_frame", Arg2.Float
(fun i -> delay_frame := i),
282 " <frame>: introduce this delay in the subtitles";
284 "-delay_time", Arg2.Float
(fun f
->
285 delay_frame := (f
*. !framerate)),
286 " <time>: introduce this delay in the subtitles";
289 "-remove_delay_frame", Arg2.Float (fun i -> delay_frame := -. i),
290 " <frame>: introduce this delay in the subtitles";
292 "-remove_delay_time", Arg2.Float (fun f ->
293 delay_frame := -. (f *. !framerate)),
294 " <time>: introduce this delay in the subtitles";
297 "-rescale", Arg2.Float
(fun newframerate
->
299 let rescale = !framerate /. newframerate
in
301 let rescale frame
= frame
*. rescale in
303 argument := List2.tail_map
(fun
304 (FrameInterval
(frame1, frame2),lines) ->
305 FrameInterval
(rescale frame1, rescale frame2), lines
308 ) , " <framerate> : rescale the frames on a different frame rate";
310 "-to", Arg2.String
(fun file
->
311 output_frames file min_float max_float
0.
312 ), " <filename>: write <filename> subtitle file (.sub or .srt)";
314 "-split_frame", Arg2.Float
(fun i -> split_frame := Some
i),
315 " <frame>: where to cut the subtitle file";
317 "-split_time", Arg2.Float
(fun f
->
318 split_frame := Some
(f
*. !framerate)),
319 " <time>: where to cut the subtitle file";
321 "-split", Arg2.Array
(2, fun array
->
322 match !split_frame with
323 None
-> lprintf
"No split frame set. You must set one.\n"; exit
2
324 | Some
split_frame ->
326 output_frames array
.(0) min_float
split_frame 0.;
327 output_frames array
.(1) split_frame max_float
split_frame;
329 ), " <filename1> <filename2>: cut subtitles in <filename1> and <filename2>";
331 "-concat_frame", Arg2.Float
(fun i -> concat_frame := Some
i),
332 " <frame>: where to add the subtitle file";
334 "-concat_time", Arg2.Float
(fun f
->
335 concat_frame := Some
(f
*. !framerate)),
336 " <time>: where to add the subtitle file";
338 "-print", Arg2.Unit
(fun _ ->
341 [] -> failwith
"Not enough subtitles"
342 | (pos
, lines) :: _ ->
344 Printf.fprintf
Pervasives.stdout
"FIRST SUBTITLE:\n";
345 fprintf_sub Pervasives.stdout
(pos
, lines) 0.;
346 fprintf_srt Pervasives.stdout
1 (pos
, lines) 0.;
352 Printf.fprintf
Pervasives.stdout
"\n\nLAST SUBTITLE:\n";
353 fprintf_sub Pervasives.stdout
(pos
, lines) 0.;
354 fprintf_srt Pervasives.stdout
1 (pos
, lines) 0.;
356 | _ :: tail
-> iter tail
361 ) , " : print first and last lines of file";
363 "-concat", Arg2.String
(fun file
->
365 match !concat_frame with
366 None
-> lprintf
"No concat frame set. You must set one.\n"; exit
2
367 | Some
concat_frame ->
369 argument := !argument @ read_frames file
concat_frame
371 ) , " <filename> : add these subtitles to the previous ones";
374 lprintf
"Don't know what to do with [%s]\n" e
; exit
2
376 "subconv: modify subtitles files"