/* 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 */ 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 { 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::().ok().ok_or("invalid track")?; match *segs.next().ok_or(" is a directory")? { "fragindex.json" => Ok(Self::FragmentIndex { track }), format => { let format = format.parse::().ok().ok_or("invalid format")?; match *segs.next().ok_or("/ 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::() && let Some(container) = StreamContainer::from_file_ext(ext) => { Ok(Self::Fragment { track, container, format, index, }) } _ => Err("not found"), } } } } } } }