aboutsummaryrefslogtreecommitdiff
path: root/stream/src
diff options
context:
space:
mode:
Diffstat (limited to 'stream/src')
-rw-r--r--stream/src/cues.rs8
-rw-r--r--stream/src/fragment.rs16
-rw-r--r--stream/src/fragment_index.rs12
-rw-r--r--stream/src/hls.rs8
-rw-r--r--stream/src/lib.rs7
-rw-r--r--stream/src/metadata.rs8
-rw-r--r--stream/src/stream_info.rs10
7 files changed, 36 insertions, 33 deletions
diff --git a/stream/src/cues.rs b/stream/src/cues.rs
index fbcb341..2fd4d70 100644
--- a/stream/src/cues.rs
+++ b/stream/src/cues.rs
@@ -4,8 +4,8 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use anyhow::{anyhow, Result};
-use jellycache::{cache_memory, HashKey};
+use anyhow::{Result, anyhow};
+use jellycache::{Cache, HashKey};
use jellyremuxer::demuxers::create_demuxer_autodetect;
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, fs::File, path::Path, sync::Arc};
@@ -28,8 +28,8 @@ pub struct StatsAndCues {
pub cues: Vec<GeneratedCue>,
}
-pub fn generate_cues(path: &Path) -> Result<Arc<StatsAndCues>> {
- cache_memory(
+pub fn generate_cues(cache: &Cache, path: &Path) -> Result<Arc<StatsAndCues>> {
+ cache.cache_memory(
&format!("media/generated-cues/{}.json", HashKey(path)),
move || {
let media = File::open(path)?;
diff --git a/stream/src/fragment.rs b/stream/src/fragment.rs
index 3f6ed98..6902d77 100644
--- a/stream/src/fragment.rs
+++ b/stream/src/fragment.rs
@@ -4,16 +4,17 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
use crate::{
- cues::{generate_cues, GeneratedCue},
- stream_info, SMediaInfo,
+ SMediaInfo,
+ cues::{GeneratedCue, generate_cues},
+ stream_info,
};
-use anyhow::{anyhow, Result};
+use anyhow::{Result, anyhow};
use jellycache::HashKey;
use jellyremuxer::{
+ ContainerFormat,
demuxers::create_demuxer_autodetect,
matroska::{self, Segment},
muxers::write_fragment,
- ContainerFormat,
};
use jellystream_types::{FormatNum, IndexNum, StreamContainer, TrackNum};
use jellytranscoder::fragment::transcode;
@@ -24,13 +25,13 @@ use std::{
};
pub fn fragment_stream(
- info: Arc<SMediaInfo>,
+ sinfo: Arc<SMediaInfo>,
track: TrackNum,
index: IndexNum,
format_num: FormatNum,
container: StreamContainer,
) -> Result<Box<dyn Read + Send + Sync>> {
- let (iinfo, info) = stream_info(info)?;
+ let (iinfo, info) = stream_info(&sinfo)?;
let (file_index, track_num) = *iinfo
.track_to_file
@@ -54,7 +55,7 @@ pub fn fragment_stream(
let timestamp_scale = iinfo.metadata[file_index].info.timestamp_scale;
let total_duration = iinfo.metadata[file_index].info.duration;
- let cue_stat = generate_cues(&media_path)?;
+ let cue_stat = generate_cues(&sinfo.cache, &media_path)?;
let start_cue = cue_stat
.cues
.get(index)
@@ -121,6 +122,7 @@ pub fn fragment_stream(
if !format.remux {
segment = transcode(
+ &sinfo.cache,
track.kind,
&format!("{}-T{track_num}-I{index}", HashKey(media_path)),
format,
diff --git a/stream/src/fragment_index.rs b/stream/src/fragment_index.rs
index 58e5bd7..e2adf41 100644
--- a/stream/src/fragment_index.rs
+++ b/stream/src/fragment_index.rs
@@ -3,8 +3,8 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{cues::generate_cues, stream_info, SMediaInfo};
-use anyhow::{anyhow, Result};
+use crate::{SMediaInfo, cues::generate_cues, stream_info};
+use anyhow::{Result, anyhow};
use jellystream_types::TrackNum;
use std::{
io::{Cursor, Read},
@@ -12,14 +12,14 @@ use std::{
sync::Arc,
};
-pub fn fragment_index(info: Arc<SMediaInfo>, track: TrackNum) -> Result<Vec<Range<f64>>> {
- let (iinfo, info) = stream_info(info)?;
+pub fn fragment_index(sinfo: &SMediaInfo, track: TrackNum) -> Result<Vec<Range<f64>>> {
+ let (iinfo, info) = stream_info(&sinfo)?;
let (file_index, _) = *iinfo
.track_to_file
.get(track)
.ok_or(anyhow!("track not found"))?;
- let cue_stat = generate_cues(&iinfo.paths[file_index])?;
+ let cue_stat = generate_cues(&sinfo.cache, &iinfo.paths[file_index])?;
Ok(cue_stat
.cues
@@ -42,6 +42,6 @@ pub fn fragment_index_stream(
track: TrackNum,
) -> Result<Box<dyn Read + Send + Sync>> {
Ok(Box::new(Cursor::new(serde_json::to_string(
- &fragment_index(info, track)?,
+ &fragment_index(&info, track)?,
)?)))
}
diff --git a/stream/src/hls.rs b/stream/src/hls.rs
index 20f452c..5557e48 100644
--- a/stream/src/hls.rs
+++ b/stream/src/hls.rs
@@ -4,7 +4,7 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{fragment_index::fragment_index, stream_info, SMediaInfo};
+use crate::{SMediaInfo, fragment_index::fragment_index, stream_info};
use anyhow::Result;
use jellystream_types::{FormatNum, StreamContainer, StreamSpec, TrackKind, TrackNum};
use std::{
@@ -18,7 +18,7 @@ pub fn hls_multivariant_stream(
info: Arc<SMediaInfo>,
container: StreamContainer,
) -> Result<Box<dyn Read + Send + Sync>> {
- let (_iinfo, info) = stream_info(info)?;
+ let (_iinfo, info) = stream_info(&info)?;
let mut out = String::new();
writeln!(out, "#EXTM3U")?;
@@ -53,8 +53,8 @@ pub fn hls_variant_stream(
format: FormatNum,
container: StreamContainer,
) -> Result<Box<dyn Read + Send + Sync>> {
- let frags = fragment_index(info.clone(), track)?;
- let (_, info) = stream_info(info)?;
+ let frags = fragment_index(&info, track)?;
+ let (_, info) = stream_info(&info)?;
let mut out = String::new();
writeln!(out, "#EXTM3U")?;
diff --git a/stream/src/lib.rs b/stream/src/lib.rs
index 717225e..20a5e1c 100644
--- a/stream/src/lib.rs
+++ b/stream/src/lib.rs
@@ -12,10 +12,11 @@ pub mod metadata;
mod stream_info;
mod webvtt;
-use anyhow::{anyhow, bail, Context, Result};
+use anyhow::{Context, Result, anyhow, bail};
use fragment::fragment_stream;
use fragment_index::fragment_index_stream;
use hls::{hls_multivariant_stream, hls_variant_stream};
+use jellycache::Cache;
use jellystream_types::{StreamContainer, StreamSpec};
use serde::{Deserialize, Serialize};
use std::{
@@ -47,10 +48,10 @@ static CONF: LazyLock<Config> = LazyLock::new(|| {
.expect("stream config not preloaded. logic error")
});
-#[derive(Debug)]
pub struct SMediaInfo {
pub title: Option<String>,
pub files: BTreeSet<PathBuf>,
+ pub cache: Arc<Cache>,
}
pub struct StreamHead {
@@ -114,7 +115,7 @@ fn original_stream(
track: usize,
range: Range<u64>,
) -> Result<Box<dyn Read + Send + Sync>> {
- let (iinfo, _info) = stream_info(info)?;
+ let (iinfo, _info) = stream_info(&info)?;
let (file_index, _) = *iinfo
.track_to_file
.get(track)
diff --git a/stream/src/metadata.rs b/stream/src/metadata.rs
index 640b851..4dedb76 100644
--- a/stream/src/metadata.rs
+++ b/stream/src/metadata.rs
@@ -4,13 +4,13 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use anyhow::{anyhow, Result};
-use jellycache::{cache_memory, HashKey};
+use anyhow::{Result, anyhow};
+use jellycache::{Cache, HashKey};
use jellyremuxer::{demuxers::create_demuxer_autodetect, matroska::Segment};
use std::{fs::File, path::Path, sync::Arc};
-pub fn read_metadata(path: &Path) -> Result<Arc<Segment>> {
- cache_memory(
+pub fn read_metadata(cache: &Cache, path: &Path) -> Result<Arc<Segment>> {
+ cache.cache_memory(
&format!("media/stream-metadata/{}.json", HashKey(path)),
move || {
let media = File::open(path)?;
diff --git a/stream/src/stream_info.rs b/stream/src/stream_info.rs
index 216c968..4a2605e 100644
--- a/stream/src/stream_info.rs
+++ b/stream/src/stream_info.rs
@@ -3,7 +3,7 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{cues::generate_cues, metadata::read_metadata, SMediaInfo, CONF};
+use crate::{CONF, SMediaInfo, cues::generate_cues, metadata::read_metadata};
use anyhow::Result;
use jellyremuxer::matroska::{self, Segment, TrackEntry, TrackType};
use jellystream_types::{
@@ -22,14 +22,14 @@ pub(crate) struct InternalStreamInfo {
}
// TODO cache mem
-pub(crate) fn stream_info(info: Arc<SMediaInfo>) -> Result<(InternalStreamInfo, StreamInfo)> {
+pub(crate) fn stream_info(info: &SMediaInfo) -> Result<(InternalStreamInfo, StreamInfo)> {
let mut tracks = Vec::new();
let mut track_to_file = Vec::new();
let mut metadata_arr = Vec::new();
let mut paths = Vec::new();
for (i, path) in info.files.iter().enumerate() {
- let metadata = read_metadata(path)?;
- let cue_stat = generate_cues(path)?;
+ let metadata = read_metadata(&info.cache, path)?;
+ let cue_stat = generate_cues(&info.cache, path)?;
if let Some(t) = &metadata.tracks {
let duration = media_duration(&metadata.info);
for t in &t.entries {
@@ -158,7 +158,7 @@ fn containers_by_codec(codec: &str) -> Vec<StreamContainer> {
}
pub(crate) fn write_stream_info(info: Arc<SMediaInfo>) -> Result<Box<dyn Read + Send + Sync>> {
- let (_, info) = stream_info(info)?;
+ let (_, info) = stream_info(&info)?;
Ok(Box::new(Cursor::new(serde_json::to_vec(&info)?)))
}