aboutsummaryrefslogtreecommitdiff
path: root/stream/types/src/path.rs
diff options
context:
space:
mode:
Diffstat (limited to 'stream/types/src/path.rs')
-rw-r--r--stream/types/src/path.rs79
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"),
+ }
+ }
+ }
+ }
+ }
+ }
+}