/* 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) 2025 metamuffin */ use serde::{Deserialize, Serialize}; use std::fmt::Display; #[derive(Debug, Clone, Deserialize, Serialize)] pub enum StreamSpec { Whep { track: usize, seek: u64, }, WhepControl { token: String, }, Remux { tracks: Vec, container: StreamContainer, }, Original { track: usize, }, HlsSuperMultiVariant { container: StreamContainer, }, HlsMultiVariant { segment: u64, container: StreamContainer, }, HlsVariant { segment: u64, track: usize, container: StreamContainer, format: usize, }, Info { segment: Option, }, FragmentIndex { segment: u64, track: usize, }, Fragment { segment: u64, track: usize, index: u64, container: StreamContainer, format: usize, }, } #[derive(Debug, Clone, Copy, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] pub enum StreamContainer { WebM, Matroska, WebVTT, JVTT, } impl StreamSpec { pub fn to_query(&self) -> String { match self { StreamSpec::Whep { track, seek } => format!("?whep&track={track}&seek={seek}"), StreamSpec::WhepControl { token } => format!("?whepcontrol&token={token}"), StreamSpec::Remux { tracks, container } => { format!( "?remux&tracks={}&container={container}", tracks .iter() .map(|t| t.to_string()) .collect::>() .join(",") ) } StreamSpec::Original { track } => format!("?original&track={track}"), StreamSpec::HlsSuperMultiVariant { container } => { format!("?hlssupermultivariant&container={container}") } StreamSpec::HlsMultiVariant { segment, container } => { format!("?hlsmultivariant&segment={segment}&container={container}") } StreamSpec::HlsVariant { segment, track, container, format, } => format!( "?hlsvariant&segment={segment}&track={track}&container={container}&format={format}" ), StreamSpec::Info { segment: Some(segment), } => format!("?info&segment={segment}"), StreamSpec::Info { segment: None } => format!("?info"), StreamSpec::FragmentIndex { segment, track } => { format!("?fragmentindex&segment={segment}&track={track}") } StreamSpec::Fragment { segment, track, index, container, format, } => format!("?fragment&segment={segment}&track={track}&index={index}&container={container}&format={format}"), } } } impl Display for StreamContainer { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(match self { StreamContainer::WebM => "webm", StreamContainer::Matroska => "matroska", StreamContainer::WebVTT => "webvtt", StreamContainer::JVTT => "jvtt", }) } }