diff options
Diffstat (limited to 'stream/types/src/path.rs')
| -rw-r--r-- | stream/types/src/path.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/stream/types/src/path.rs b/stream/types/src/path.rs new file mode 100644 index 0000000..4a91457 --- /dev/null +++ b/stream/types/src/path.rs @@ -0,0 +1,79 @@ +/* + 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) 2026 metamuffin <metamuffin.org> +*/ + +use crate::{FormatNum, IndexNum, StreamContainer, StreamSpec, TrackKind, TrackNum}; + +impl StreamSpec { + pub fn to_path(&self) -> String { + match self { + StreamSpec::HlsMultiVariant => format!("stream.m3u8"), + StreamSpec::Dash => format!("stream.mpd"), + StreamSpec::Info => format!("formats.json"), + StreamSpec::HlsVariant { track, format } => format!("{track}/{format}/variant.m3u8"), + StreamSpec::FragmentIndex { track } => format!("{track}/fragindex.json"), + StreamSpec::FragmentInit { + track, + container, + format, + } => format!( + "{track}/{format}/init.{}", + container.file_ext(TrackKind::Video) + ), + StreamSpec::Fragment { + track, + index, + container, + format, + } => format!( + "{track}/{format}/frag/{index}.{}", + container.file_ext(TrackKind::Video) + ), + _ => todo!(), + } + } + pub fn from_path(segments: &[&str]) -> Result<Self, &'static str> { + let mut segs = segments.into_iter(); + match *segs.next().ok_or("no path")? { + "stream.mpd" => Ok(Self::Dash), + "stream.m3u8" => Ok(Self::HlsMultiVariant), + "formats.json" => Ok(Self::Info), + track => { + let track = track.parse::<TrackNum>().ok().ok_or("invalid track")?; + match *segs.next().ok_or("<track> is a directory")? { + "fragindex.json" => Ok(Self::FragmentIndex { track }), + format => { + let format = format.parse::<FormatNum>().ok().ok_or("invalid format")?; + match *segs.next().ok_or("<track>/<format> is a directory")? { + "variant.m3u8" => Ok(Self::HlsVariant { track, format }), + f if let Some(ext) = f.strip_prefix("init.") + && let Some(container) = StreamContainer::from_file_ext(ext) => + { + Ok(Self::FragmentInit { + track, + container, + format, + }) + } + f if let Some(rest) = f.strip_prefix("frag") + && let Some((index, ext)) = rest.split_once(".") + && let Ok(index) = index.parse::<IndexNum>() + && let Some(container) = StreamContainer::from_file_ext(ext) => + { + Ok(Self::Fragment { + track, + container, + format, + index, + }) + } + _ => Err("not found"), + } + } + } + } + } + } +} |