mirror of
https://git.pumpin.online/funkpower/catena.git
synced 2026-10-23 11:17:13 +00:00
cuekit and cuenorm: three subtitle formats, one cue stream
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
//! Collapsing the repetition automatic captioning produces.
|
||||
|
||||
use crate::cue::Cue;
|
||||
|
||||
/// Merge consecutive cues whose text is identical, keeping the earliest start
|
||||
/// and the latest end.
|
||||
///
|
||||
/// Automatic captioning emits a rolling window: the same line appears in cue
|
||||
/// after cue as the window slides, so a ten-minute stretch of speech can
|
||||
/// arrive as three times as many cues as there are sentences. Indexed as they
|
||||
/// come, every one of those is a separate hit for the same words at almost
|
||||
/// the same timestamp, which buries everything else in a result list.
|
||||
pub fn merge_repeats(cues: &[Cue]) -> Vec<Cue> {
|
||||
let mut merged: Vec<Cue> = Vec::with_capacity(cues.len());
|
||||
for cue in cues {
|
||||
match merged.last_mut() {
|
||||
Some(previous) if previous.text == cue.text => {
|
||||
previous.end = previous.end.max(cue.end);
|
||||
}
|
||||
_ => merged.push(cue.clone()),
|
||||
}
|
||||
}
|
||||
merged
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_repeated_line_becomes_one_cue_spanning_both() {
|
||||
let cues = [
|
||||
Cue::new(0.0, 2.0, "the mill stood"),
|
||||
Cue::new(1.0, 3.0, "the mill stood"),
|
||||
Cue::new(3.0, 4.0, "at the northern end"),
|
||||
];
|
||||
let merged = merge_repeats(&cues);
|
||||
assert_eq!(merged.len(), 2);
|
||||
assert_eq!(merged[0].start, 0.0);
|
||||
assert_eq!(merged[0].end, 3.0);
|
||||
assert_eq!(merged[1].text, "at the northern end");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_line_that_comes_back_later_is_kept_separately() {
|
||||
let cues = [
|
||||
Cue::new(0.0, 1.0, "yes"),
|
||||
Cue::new(1.0, 2.0, "no"),
|
||||
Cue::new(2.0, 3.0, "yes"),
|
||||
];
|
||||
assert_eq!(merge_repeats(&cues).len(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_end_that_goes_backwards_does_not_shorten_the_merged_cue() {
|
||||
let cues = [Cue::new(0.0, 9.0, "x"), Cue::new(1.0, 2.0, "x")];
|
||||
let merged = merge_repeats(&cues);
|
||||
assert_eq!(merged.len(), 1);
|
||||
assert_eq!(merged[0].end, 9.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nothing_in_nothing_out() {
|
||||
assert!(merge_repeats(&[]).is_empty());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user