summary refs log tree commit diff
path: root/src/subtitles/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/subtitles/mod.rs')
-rw-r--r--src/subtitles/mod.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/subtitles/mod.rs b/src/subtitles/mod.rs
new file mode 100644
index 0000000..a545d52
--- /dev/null
+++ b/src/subtitles/mod.rs
@@ -0,0 +1,86 @@
+pub mod extraction;
+pub mod state;
+
+use std::collections::BTreeMap;
+
+use relm4::SharedState;
+
+pub type StreamIndex = usize;
+
+#[derive(Debug, Clone)]
+pub struct MetadataCollection {
+    pub audio: BTreeMap<StreamIndex, TrackMetadata>,
+    pub subtitles: BTreeMap<StreamIndex, TrackMetadata>,
+}
+
+#[derive(Debug, Clone)]
+pub struct TrackMetadata {
+    pub language: Option<isolang::Language>,
+    pub title: Option<String>,
+}
+
+#[derive(Debug, Clone)]
+pub struct SubtitleCue {
+    pub text: String,
+    pub start_time: gst::ClockTime,
+    pub end_time: gst::ClockTime,
+}
+
+#[derive(Debug, Clone)]
+pub struct SubtitleTrack {
+    pub metadata: TrackMetadata,
+    // SoA of cue text, start timestamp, end timestamp
+    pub texts: Vec<String>,
+    pub start_times: Vec<gst::ClockTime>,
+    pub end_times: Vec<gst::ClockTime>,
+}
+
+pub static SUBTITLE_TRACKS: SharedState<BTreeMap<StreamIndex, SubtitleTrack>> = SharedState::new();
+
+impl TrackMetadata {
+    pub fn from_ffmpeg_stream(stream: &ffmpeg::Stream) -> Self {
+        let language_code = stream.metadata().get("language").map(|s| s.to_string());
+        let title = stream.metadata().get("title").map(|s| s.to_string());
+
+        Self {
+            language: language_code.and_then(|code| isolang::Language::from_639_2b(&code)),
+            title,
+        }
+    }
+}
+
+impl SubtitleTrack {
+    pub fn new(metadata: TrackMetadata) -> Self {
+        Self {
+            metadata,
+            texts: Vec::new(),
+            start_times: Vec::new(),
+            end_times: Vec::new(),
+        }
+    }
+
+    pub fn push_cue(&mut self, cue: SubtitleCue) {
+        let SubtitleCue {
+            text,
+            start_time,
+            end_time,
+        } = cue;
+
+        self.texts.push(text);
+        self.start_times.push(start_time);
+        self.end_times.push(end_time);
+    }
+
+    pub fn iter_cloned_cues(&self) -> impl Iterator<Item = SubtitleCue> {
+        self.texts
+            .iter()
+            .cloned()
+            .zip(self.start_times.iter().cloned())
+            .zip(self.end_times.iter().cloned())
+            .map(|((text, start_time), end_time)| SubtitleCue {
+                text,
+                start_time,
+                end_time,
+            })
+    }
+}