improve help text, add duration clipping
This commit is contained in:
+36
-17
@@ -22,24 +22,30 @@ fn main() {
|
||||
let argv =
|
||||
clap::App::new("srtune")
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.about("Modify a .srt file to match a video. Input and output can be a file or stream, \
|
||||
so you pipe multiple invocations to create more complex operations. However, a single \
|
||||
.about("\
|
||||
'srtune' helps you edit a .srt file to match a video. Input and output can be either a file, or a stream, \
|
||||
so you can pipe multiple invocations to create more complex operations. However, a single \
|
||||
invocation should suffice in most cases.\n\
|
||||
\n\
|
||||
Times are specified with colons and always include seconds (HH:MM:SS, MM:SS, 0:SS). \
|
||||
Decimal point can be either period or comma, so times can be copied directly from the \
|
||||
Times are specified with colons (required) and always include seconds (HH:MM:SS, MM:SS, 0:SS, :SS). \
|
||||
Decimal point in the seconds part, if needed, can be either a period or a comma; times can be copied from the \
|
||||
.srt file. Numbers without colons are assumed to be subtitle indices.\n\
|
||||
\n\
|
||||
The tool can be used iteratively, adjusting the invocation until the generated \
|
||||
subtitle file matches the audio track. As such, times accepted by its parameters \
|
||||
are, by default, the ones seen in the output file (after shifts and moving), while \
|
||||
indices are those from the input file.\n\
|
||||
subtitle file matches the audio track. You can reload the file in VLC by dragging it \
|
||||
onto the player window. To make this work, subtitle times specified in arguments are the \
|
||||
ones seen in the output file (after shifts and moving), while entry indices are those from the input file.\n\
|
||||
\n\
|
||||
Using indices makes it easier to specify a subtitle to alter, but it is tied to the one .srt file. \
|
||||
Times are harder to write, but the one configuration will work for any locatization or variant of the file,\
|
||||
so long as it is intended for the same version of the movie. Enable debug logging with '-v' to see times \
|
||||
you can use in place of indices.
|
||||
\n\
|
||||
Indices are normally not renumbered, so the output file can be used as a reference \
|
||||
for both times and indices. The flag '--renumber' will give each output entry a new \
|
||||
sequential number. Please note that, once renumbered, the indices in the output file \
|
||||
should no longer be used in the command invocation, as there can be a mismatch. They \
|
||||
can be used when piped into a new process, of course.
|
||||
for both times and indices when you work out the right set of arguments. The flag '--renumber' \
|
||||
will give each output entry a new sequential number. Please note that, once renumbered, \
|
||||
the indices in the output file should no longer be used in the command invocation, \
|
||||
as there can be (and often will be) differences from the original file.\
|
||||
")
|
||||
.arg(clap::Arg::with_name("input")
|
||||
.value_name("INFILE")
|
||||
@@ -210,7 +216,6 @@ fn main() {
|
||||
}
|
||||
None => (/* no automoves */)
|
||||
}
|
||||
debug!("Automove: {:?}", automove);
|
||||
|
||||
let inf = argv.value_of("input");
|
||||
let outf = argv.value_of("output");
|
||||
@@ -359,11 +364,13 @@ enum AutoMoveTag {
|
||||
ByIndex(u32, SubInstant)
|
||||
}
|
||||
|
||||
#[derive(Debug,Default,Clone,Copy)]
|
||||
#[derive(Debug,Default,Clone)]
|
||||
struct IterState {
|
||||
start_time : Option<SubInstant>,
|
||||
renumber_i : u32,
|
||||
timeline_head : SubInstant,
|
||||
/// Queue last item for duration clipping
|
||||
queued : Option<Subtitle>,
|
||||
}
|
||||
|
||||
fn transform_subtitles<'a>(mut lines : Box<dyn SubsInput + 'a>, mut outfile : Box<dyn SubsOutput + 'a>, mut opts : TransformOpts) {
|
||||
@@ -443,11 +450,8 @@ fn transform_subtitles<'a>(mut lines : Box<dyn SubsInput + 'a>, mut outfile : Bo
|
||||
|
||||
subtitle.dur *= opts.durscale;
|
||||
|
||||
// TODO prevent durations overlap (will need to buffer one entry)
|
||||
|
||||
let would_be_shifted_start = subtitle.start + opts.shift;
|
||||
|
||||
// TODO use drain_filter when stable
|
||||
let mut to_drop = vec![];
|
||||
for (i, amove) in opts.automove.iter().enumerate() {
|
||||
match amove {
|
||||
@@ -502,7 +506,17 @@ fn transform_subtitles<'a>(mut lines : Box<dyn SubsInput + 'a>, mut outfile : Bo
|
||||
istate.renumber_i += 1;
|
||||
subtitle.num = istate.renumber_i;
|
||||
}
|
||||
outfile.emit(subtitle);
|
||||
|
||||
if let Some(mut q) = istate.queued.take() {
|
||||
if q.start + q.dur > subtitle.start {
|
||||
let clipped = subtitle.start - q.start;
|
||||
debug!("Clipping duration of #{} ({}) to avoid overlap: {} -> {}", q.num, q.start, q.dur, clipped);
|
||||
q.dur = clipped;
|
||||
}
|
||||
outfile.emit(q);
|
||||
}
|
||||
|
||||
istate.queued = Some(subtitle);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -514,6 +528,11 @@ fn transform_subtitles<'a>(mut lines : Box<dyn SubsInput + 'a>, mut outfile : Bo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// emit the last entry
|
||||
if let Some(q) = istate.queued.take() {
|
||||
outfile.emit(q);
|
||||
}
|
||||
}
|
||||
|
||||
//region Time types
|
||||
|
||||
Reference in New Issue
Block a user