aboutsummaryrefslogtreecommitdiff
path: root/remuxer/src/snippet.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-01-26 03:46:05 +0100
committermetamuffin <metamuffin@disroot.org>2024-01-26 03:46:05 +0100
commit2e41b2b373d5a057061a7694aa5e83001efeaf0f (patch)
treefd9c82fcaf7a8100698b162f9c21ba1852becc88 /remuxer/src/snippet.rs
parent9918784ba0b71b406e98e069a4e2be10bf72f02e (diff)
downloadjellything-2e41b2b373d5a057061a7694aa5e83001efeaf0f.tar
jellything-2e41b2b373d5a057061a7694aa5e83001efeaf0f.tar.bz2
jellything-2e41b2b373d5a057061a7694aa5e83001efeaf0f.tar.zst
fix a bunch of stupid things regarding subtitles. still doesnt work
Diffstat (limited to 'remuxer/src/snippet.rs')
-rw-r--r--remuxer/src/snippet.rs80
1 files changed, 61 insertions, 19 deletions
diff --git a/remuxer/src/snippet.rs b/remuxer/src/snippet.rs
index 4c3c47f..5b271e4 100644
--- a/remuxer/src/snippet.rs
+++ b/remuxer/src/snippet.rs
@@ -9,7 +9,7 @@ use crate::{
segment_extractor::SegmentExtractIter,
};
use anyhow::{anyhow, Context, Result};
-use jellycommon::{LocalTrack, NodePublic};
+use jellycommon::{LocalTrack, NodePublic, SourceTrackKind};
use jellymatroska::{read::EbmlReader, write::EbmlWriter, Master, MatroskaTag};
use log::{debug, info};
use std::{
@@ -25,6 +25,7 @@ pub fn snippet_index(
path_base: &Path,
item: &NodePublic,
local_track: &LocalTrack,
+ track_index: usize,
) -> Result<Vec<Range<f64>>> {
let media_info = item.media.as_ref().unwrap();
let source_path = path_base.join(&local_track.path);
@@ -32,20 +33,46 @@ pub fn snippet_index(
let index = index
.get(&(local_track.track as u64))
.ok_or(anyhow!("seek index track missing"))?;
- let average_kf_interval = media_info.duration / index.keyframes.len() as f64;
+
+ // everything is a keyframe (even though nothing is...)
+ let force_kf = matches!(
+ media_info.tracks[track_index].kind,
+ SourceTrackKind::Subtitles { .. }
+ );
+
+ let n_kf = if force_kf {
+ index.blocks.len()
+ } else {
+ index.keyframes.len()
+ };
+
+ let average_kf_interval = media_info.duration / n_kf as f64;
let kf_per_snip = (SNIPPET_LENGTH / average_kf_interval).ceil() as usize;
debug!("average keyframe interval: {average_kf_interval}");
debug!(" => keyframes per snippet {kf_per_snip}");
- let n_snips = index.keyframes.len().div_ceil(kf_per_snip);
+ let n_snips = n_kf.div_ceil(kf_per_snip);
Ok((0..n_snips)
.map(|i| {
- let start = index.blocks[index.keyframes[i * kf_per_snip]].pts as f64 / 1000.;
- let end = index
- .keyframes
- .get((i + 1) * kf_per_snip)
- .map(|i| index.blocks[*i].pts as f64 / 1000.)
- .unwrap_or(media_info.duration);
+ let start = index.blocks[if force_kf {
+ i * kf_per_snip
+ } else {
+ index.keyframes[i * kf_per_snip]
+ }]
+ .pts as f64
+ / 1000.;
+ let end = if force_kf {
+ let n = (i + 1) * kf_per_snip;
+ if n >= index.blocks.len() {
+ None
+ } else {
+ Some(n)
+ }
+ } else {
+ index.keyframes.get((i + 1) * kf_per_snip).copied()
+ }
+ .map(|i| index.blocks[i].pts as f64 / 1000.)
+ .unwrap_or(media_info.duration);
start..end
})
.collect())
@@ -62,7 +89,6 @@ pub fn write_snippet_into(
) -> anyhow::Result<()> {
info!("writing snippet {n} of {:?} (track {track})", item.title);
let mut output = EbmlWriter::new(BufWriter::new(writer), 0);
-
let media_info = item.media.as_ref().unwrap();
let info = media_info
.tracks
@@ -85,19 +111,33 @@ pub fn write_snippet_into(
debug!("\t seek index: {} blocks loaded", index.blocks.len());
let mut reader = EbmlReader::new(file);
- let average_kf_interval = media_info.duration / index.keyframes.len() as f64;
+ let force_kf = matches!(info.kind, SourceTrackKind::Subtitles { .. });
+ let n_kf = if force_kf {
+ index.blocks.len()
+ } else {
+ index.keyframes.len()
+ };
+
+ let average_kf_interval = media_info.duration / n_kf as f64;
let kf_per_snip = (SNIPPET_LENGTH / average_kf_interval).ceil() as usize;
debug!("average keyframe interval: {average_kf_interval}");
debug!(" => keyframes per snippet {kf_per_snip}");
- let start_block_index = *index
- .keyframes
- .get(n * kf_per_snip)
- .ok_or(anyhow!("snippet index out of range"))?;
- let end_block_index = *index
- .keyframes
- .get((n + 1) * kf_per_snip)
- .unwrap_or(&index.blocks.len());
+ let (start_block_index, end_block_index) = if force_kf {
+ (n * kf_per_snip, (n + 1) * kf_per_snip)
+ } else {
+ (
+ *index
+ .keyframes
+ .get(n * kf_per_snip)
+ .ok_or(anyhow!("snippet index out of range"))?,
+ *index
+ .keyframes
+ .get((n + 1) * kf_per_snip)
+ .unwrap_or(&index.blocks.len()),
+ )
+ };
+
let start_block = &index.blocks[start_block_index];
let last_block = &index.blocks[end_block_index - 1];
@@ -152,5 +192,7 @@ pub fn write_snippet_into(
}
output.write_tag(&MatroskaTag::Segment(Master::End))?;
+
+ debug!("wrote {} bytes", output.position());
Ok(())
}