aboutsummaryrefslogtreecommitdiff
path: root/stream/types/src/path.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-03-07 04:02:48 +0100
committermetamuffin <metamuffin@disroot.org>2026-03-07 04:02:48 +0100
commit4ce6d64648634bd8d22e8ed0676e0e5b22947dc3 (patch)
treec1df9c9f623603651157006b9fd249de6d63fc7b /stream/types/src/path.rs
parentd3ed810656a563fc733771e760b2abbb05bd98cb (diff)
downloadjellything-4ce6d64648634bd8d22e8ed0676e0e5b22947dc3.tar
jellything-4ce6d64648634bd8d22e8ed0676e0e5b22947dc3.tar.bz2
jellything-4ce6d64648634bd8d22e8ed0676e0e5b22947dc3.tar.zst
new media path format
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"),
+ }
+ }
+ }
+ }
+ }
+ }
+}