aboutsummaryrefslogtreecommitdiff
path: root/stream/src/fragment_index.rs
blob: 9d82cd7e4e71654144b1903f8bf81701498922df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2025 metamuffin <metamuffin.org>
*/
use crate::{cues::generate_cues, stream_info, SMediaInfo};
use anyhow::{anyhow, Result};
use jellystream_types::TrackNum;
use std::{
    io::{Cursor, Read},
    ops::Range,
    sync::Arc,
};

pub fn fragment_index(info: Arc<SMediaInfo>, track: TrackNum) -> Result<Vec<Range<f64>>> {
    let (iinfo, info) = stream_info(info)?;
    let (file_index, _) = *iinfo
        .track_to_file
        .get(track)
        .ok_or(anyhow!("track not found"))?;

    let cue_stat = generate_cues(&iinfo.paths[file_index])?;

    Ok(cue_stat
        .cues
        .iter()
        .map(|c| c.time as f64 / 1_000_000_000.)
        .zip(
            cue_stat
                .cues
                .iter()
                .skip(1)
                .map(|c| c.time as f64 / 1_000_000_000.)
                .chain([info.duration]),
        )
        .map(|(start, end)| start..end)
        .collect())
}

pub fn fragment_index_stream(
    info: Arc<SMediaInfo>,
    track: TrackNum,
) -> Result<Box<dyn Read + Send + Sync>> {
    Ok(Box::new(Cursor::new(serde_json::to_string(
        &fragment_index(info, track)?,
    )?)))
}