aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Cargo.toml1
-rw-r--r--common/src/jhls.rs9
-rw-r--r--common/src/lib.rs2
-rw-r--r--common/src/stream.rs279
4 files changed, 2 insertions, 289 deletions
diff --git a/common/Cargo.toml b/common/Cargo.toml
index 90372bc..7baed9f 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -9,3 +9,4 @@ bincode = { version = "2.0.0-rc.3", features = ["derive"] }
chrono = { version = "0.4.39", features = ["serde"] }
blake3 = "1.5.5"
hex = "0.4.3"
+jellystream-types = { path = "../stream/types" }
diff --git a/common/src/jhls.rs b/common/src/jhls.rs
index 90f48f5..104d9a5 100644
--- a/common/src/jhls.rs
+++ b/common/src/jhls.rs
@@ -3,12 +3,3 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
-use bincode::{Decode, Encode};
-use serde::{Deserialize, Serialize};
-
-#[derive(Debug, Serialize, Deserialize, Encode, Decode)]
-pub struct SubtitleCue {
- pub start: f64,
- pub end: f64,
- pub content: String,
-}
diff --git a/common/src/lib.rs b/common/src/lib.rs
index 14c82fc..903d519 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -10,8 +10,8 @@ pub mod helpers;
pub mod r#impl;
pub mod jhls;
pub mod routes;
-pub mod stream;
pub mod user;
+pub use jellystream_types as stream;
pub use chrono;
diff --git a/common/src/stream.rs b/common/src/stream.rs
deleted file mode 100644
index b60b349..0000000
--- a/common/src/stream.rs
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- 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 <metamuffin.org>
-*/
-use serde::{Deserialize, Serialize};
-use std::{collections::BTreeMap, fmt::Display, str::FromStr};
-
-pub type SegmentNum = usize;
-pub type TrackNum = usize;
-pub type FormatNum = usize;
-pub type IndexNum = usize;
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-pub enum StreamSpec {
- // Whep {
- // track: TrackNum,
- // seek: u64,
- // },
- // WhepControl {
- // token: String,
- // },
- Remux {
- tracks: Vec<usize>,
- container: StreamContainer,
- },
- Original {
- track: TrackNum,
- },
- HlsSuperMultiVariant {
- container: StreamContainer,
- },
- HlsMultiVariant {
- segment: SegmentNum,
- container: StreamContainer,
- },
- HlsVariant {
- segment: SegmentNum,
- track: TrackNum,
- container: StreamContainer,
- format: FormatNum,
- },
- Info {
- segment: Option<u64>,
- },
- FragmentIndex {
- segment: SegmentNum,
- track: TrackNum,
- },
- Fragment {
- segment: SegmentNum,
- track: TrackNum,
- index: IndexNum,
- container: StreamContainer,
- format: FormatNum,
- },
- // Track {
- // segment: SegmentNum,
- // track: TrackNum,
- // container: StreamContainer,
- // foramt: FormatNum,
- // },
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-pub struct StreamInfo {
- pub name: Option<String>,
- pub segments: Vec<StreamSegmentInfo>,
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-pub struct StreamSegmentInfo {
- pub name: Option<String>,
- pub duration: f64,
- pub tracks: Vec<StreamTrackInfo>,
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize)]
-pub struct StreamTrackInfo {
- pub name: Option<String>,
- pub kind: TrackKind,
- pub formats: Vec<StreamFormatInfo>,
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize, Serialize)]
-#[serde(rename_all = "snake_case")]
-pub enum TrackKind {
- Video,
- Audio,
- Subtitle,
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize, Default)]
-pub struct StreamFormatInfo {
- pub codec: String,
- pub bitrate: f64,
- pub remux: bool,
- pub containers: Vec<StreamContainer>,
-
- pub width: Option<u64>,
- pub height: Option<u64>,
- pub samplerate: Option<f64>,
- pub channels: Option<usize>,
- pub bit_depth: Option<u8>,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
-#[serde(rename_all = "lowercase")]
-pub enum StreamContainer {
- WebM,
- Matroska,
- WebVTT,
- MPEG4,
- JVTT,
-}
-
-impl StreamSpec {
- pub fn to_query(&self) -> String {
- match self {
- StreamSpec::Remux { tracks, container } => {
- format!(
- "?remux&tracks={}&container={container}",
- tracks
- .iter()
- .map(|t| t.to_string())
- .collect::<Vec<String>>()
- .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 } => "?info".to_string(),
- 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}"),
- }
- }
- pub fn to_query_short(&self) -> String {
- match self {
- StreamSpec::Remux { tracks, container } => {
- format!(
- "?remux&ts={}&c={container}",
- tracks
- .iter()
- .map(|t| t.to_string())
- .collect::<Vec<String>>()
- .join(",")
- )
- }
- StreamSpec::Original { track } => format!("?original&t={track}"),
- StreamSpec::HlsSuperMultiVariant { container } => {
- format!("?hlssupermultivariant&c={container}")
- }
- StreamSpec::HlsMultiVariant { segment, container } => {
- format!("?hlsmultivariant&s={segment}&c={container}")
- }
- StreamSpec::HlsVariant {
- segment,
- track,
- container,
- format,
- } => format!("?hlsvariant&s={segment}&t={track}&c={container}&f={format}"),
- StreamSpec::Info {
- segment: Some(segment),
- } => format!("?info&s={segment}"),
- StreamSpec::Info { segment: None } => "?info".to_string(),
- StreamSpec::FragmentIndex { segment, track } => {
- format!("?fragmentindex&s={segment}&t={track}")
- }
- StreamSpec::Fragment {
- segment,
- track,
- index,
- container,
- format,
- } => format!("?fragment&s={segment}&t={track}&i={index}&c={container}&f={format}"),
- }
- }
- pub fn from_query_kv(query: &BTreeMap<String, String>) -> Result<Self, &'static str> {
- let get_num = |k: &'static str, ks: &'static str| {
- query
- .get(k)
- .or(query.get(ks))
- .ok_or(k)
- .and_then(|a| a.parse().map_err(|_| "invalid number"))
- };
- let get_container = || {
- query
- .get("container")
- .or(query.get("c"))
- .ok_or("container")
- .and_then(|s| s.parse().map_err(|()| "unknown container"))
- };
- if query.contains_key("info") {
- Ok(Self::Info {
- segment: get_num("segment", "s").ok(),
- })
- } else if query.contains_key("hlssupermultivariant") {
- Ok(Self::HlsSuperMultiVariant {
- container: get_container().ok().unwrap_or(StreamContainer::Matroska),
- })
- } else if query.contains_key("hlsmultivariant") {
- Ok(Self::HlsMultiVariant {
- segment: get_num("segment", "s")? as SegmentNum,
- container: get_container()?,
- })
- } else if query.contains_key("hlsvariant") {
- Ok(Self::HlsVariant {
- segment: get_num("segment", "s")? as SegmentNum,
- track: get_num("track", "t")? as TrackNum,
- format: get_num("format", "f")? as FormatNum,
- container: get_container()?,
- })
- } else if query.contains_key("fragment") {
- Ok(Self::Fragment {
- segment: get_num("segment", "s")? as SegmentNum,
- track: get_num("track", "t")? as TrackNum,
- format: get_num("format", "f")? as FormatNum,
- index: get_num("index", "i")? as IndexNum,
- container: get_container()?,
- })
- } else if query.contains_key("fragmentindex") {
- Ok(Self::FragmentIndex {
- segment: get_num("segment", "s")? as SegmentNum,
- track: get_num("track", "t")? as TrackNum,
- })
- } else {
- Err("invalid stream spec")
- }
- }
-}
-
-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",
- StreamContainer::MPEG4 => "mpeg4",
- })
- }
-}
-impl FromStr for StreamContainer {
- type Err = ();
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- Ok(match s {
- "webm" => StreamContainer::WebM,
- "matroska" => StreamContainer::Matroska,
- "webvtt" => StreamContainer::WebVTT,
- "jvtt" => StreamContainer::JVTT,
- "mpeg4" => StreamContainer::MPEG4,
- _ => return Err(()),
- })
- }
-}