aboutsummaryrefslogtreecommitdiff
path: root/stream/src/lib.rs
blob: 867b3101ca1c228b364d42a31d46f1279e66a288 (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
48
49
50
51
52
53
54
55
56
57
58
59
use anyhow::{anyhow, bail, Result};
use jellybase::CONF;
use jellycommon::{
    stream::{StreamFormat, StreamSpec},
    LocalTrack, MediaSource, Node,
};
use std::ops::Range;
use tokio::io::{duplex, DuplexStream};
use tokio_util::io::SyncIoBridge;

pub async fn stream(node: Node, spec: StreamSpec, range: Range<usize>) -> Result<DuplexStream> {
    let (a, b) = duplex(4096);

    let track_sources = match node
        .private
        .source
        .as_ref()
        .ok_or(anyhow!("node has no media"))?
    {
        MediaSource::Local { tracks } => tracks.to_owned(),
        _ => bail!("node tracks are not local"),
    };

    match spec.format {
        StreamFormat::Original => todo!(),
        StreamFormat::Matroska | StreamFormat::Webm => {
            remux_stream(node, track_sources, spec, range, b).await?
        }
        StreamFormat::Hls => todo!(),
        StreamFormat::Jhls => todo!(),
        StreamFormat::Segment => todo!(),
    }

    Ok(a)
}

async fn remux_stream(
    node: Node,
    track_sources: Vec<LocalTrack>,
    spec: StreamSpec,
    range: Range<usize>,
    b: DuplexStream,
) -> Result<()> {
    let b = SyncIoBridge::new(b);

    tokio::task::spawn_blocking(move || {
        jellyremuxer::remux_stream_into(
            b,
            range,
            CONF.library_path.to_owned(),
            node.public,
            track_sources,
            spec.tracks,
            spec.format == StreamFormat::Webm,
        )
    });

    Ok(())
}