aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes/ui/player.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-04-27 19:25:11 +0200
committermetamuffin <metamuffin@disroot.org>2025-04-27 19:25:11 +0200
commit11a585b3dbe620dcc8772e713b22f1d9ba80d598 (patch)
tree44f8d97137412aefc79a2425a489c34fa3e5f6c5 /server/src/routes/ui/player.rs
parentd871aa7c5bba49ff55170b5d2dac9cd440ae7170 (diff)
downloadjellything-11a585b3dbe620dcc8772e713b22f1d9ba80d598.tar
jellything-11a585b3dbe620dcc8772e713b22f1d9ba80d598.tar.bz2
jellything-11a585b3dbe620dcc8772e713b22f1d9ba80d598.tar.zst
move files around
Diffstat (limited to 'server/src/routes/ui/player.rs')
-rw-r--r--server/src/routes/ui/player.rs200
1 files changed, 0 insertions, 200 deletions
diff --git a/server/src/routes/ui/player.rs b/server/src/routes/ui/player.rs
deleted file mode 100644
index 2bb439b..0000000
--- a/server/src/routes/ui/player.rs
+++ /dev/null
@@ -1,200 +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 super::{
- account::session::{token, Session},
- layout::LayoutPage,
- node::{get_similar_media, DatabaseNodeUserDataExt, NodePage},
- sort::NodeFilterSort,
-};
-use crate::{
- database::Database,
- routes::{
- locale::AcceptLanguage,
- ui::{error::MyResult, layout::DynLayoutPage},
- },
-};
-use anyhow::anyhow;
-use jellybase::CONF;
-use jellycommon::{
- stream::{StreamContainer, StreamSpec},
- user::{PermissionSet, PlayerKind},
- Node, NodeID, SourceTrackKind, TrackID, Visibility,
-};
-use markup::DynRender;
-use rocket::{get, response::Redirect, Either, FromForm, State, UriDisplayQuery};
-use std::sync::Arc;
-
-#[derive(FromForm, Default, Clone, Debug, UriDisplayQuery)]
-pub struct PlayerConfig {
- pub a: Option<TrackID>,
- pub v: Option<TrackID>,
- pub s: Option<TrackID>,
- pub t: Option<f64>,
- pub kind: Option<PlayerKind>,
-}
-
-impl PlayerConfig {
- pub fn seek(t: f64) -> Self {
- Self {
- t: Some(t),
- ..Default::default()
- }
- }
-}
-
-fn jellynative_url(action: &str, seek: f64, secret: &str, node: &str, session: &str) -> String {
- let protocol = if CONF.tls { "https" } else { "http" };
- let host = &CONF.hostname;
- let stream_url = format!(
- "/n/{node}/stream{}",
- StreamSpec::HlsMultiVariant {
- segment: 0,
- container: StreamContainer::Matroska
- }
- .to_query()
- );
- format!("jellynative://{action}/{secret}/{session}/{seek}/{protocol}://{host}{stream_url}",)
-}
-
-#[get("/n/<id>/player?<conf..>", rank = 4)]
-pub fn r_player(
- session: Session,
- lang: AcceptLanguage,
- db: &State<Database>,
- id: NodeID,
- conf: PlayerConfig,
-) -> MyResult<Either<DynLayoutPage<'_>, Redirect>> {
- let AcceptLanguage(lang) = lang;
- let (node, udata) = db.get_node_with_userdata(id, &session)?;
-
- let mut parents = node
- .parents
- .iter()
- .map(|pid| db.get_node_with_userdata(*pid, &session))
- .collect::<anyhow::Result<Vec<_>>>()?;
-
- let mut similar = get_similar_media(&node, db, &session)?;
-
- similar.retain(|(n, _)| n.visibility >= Visibility::Reduced);
- parents.retain(|(n, _)| n.visibility >= Visibility::Reduced);
-
- let native_session = |action: &str| {
- Ok(Either::Right(Redirect::temporary(jellynative_url(
- action,
- conf.t.unwrap_or(0.),
- &session.user.native_secret,
- &id.to_string(),
- &token::create(
- session.user.name,
- PermissionSet::default(), // TODO
- chrono::Duration::hours(24),
- ),
- ))))
- };
-
- match conf.kind.unwrap_or(session.user.player_preference) {
- PlayerKind::Browser => (),
- PlayerKind::Native => {
- return native_session("player-v2");
- }
- PlayerKind::NativeFullscreen => {
- return native_session("player-fullscreen-v2");
- }
- }
-
- // TODO
- // let spec = StreamSpec {
- // track: None
- // .into_iter()
- // .chain(conf.v)
- // .chain(conf.a)
- // .chain(conf.s)
- // .collect::<Vec<_>>(),
- // format: StreamFormat::Matroska,
- // webm: Some(true),
- // ..Default::default()
- // };
- // let playing = false; // !spec.track.is_empty();
- // let conf = player_conf(node.clone(), playing)?;
-
- Ok(Either::Left(LayoutPage {
- title: node.title.to_owned().unwrap_or_default(),
- class: Some("player"),
- content: markup::new! {
- // @if playing {
- // // video[src=uri!(r_stream(&node.slug, &spec)), controls, preload="auto"]{}
- // }
- // @conf
- @NodePage {
- children: &[],
- parents: &parents,
- filter: &NodeFilterSort::default(),
- node: &node,
- udata: &udata,
- player: true,
- similar: &similar,
- lang: &lang
- }
- },
- }))
-}
-
-pub fn player_conf<'a>(item: Arc<Node>, playing: bool) -> anyhow::Result<DynRender<'a>> {
- let mut audio_tracks = vec![];
- let mut video_tracks = vec![];
- let mut sub_tracks = vec![];
- let tracks = item
- .media
- .clone()
- .ok_or(anyhow!("node does not have media"))?
- .tracks
- .clone();
- for (tid, track) in tracks.into_iter().enumerate() {
- match &track.kind {
- SourceTrackKind::Audio { .. } => audio_tracks.push((tid, track)),
- SourceTrackKind::Video { .. } => video_tracks.push((tid, track)),
- SourceTrackKind::Subtitles => sub_tracks.push((tid, track)),
- }
- }
-
- Ok(markup::new! {
- form.playerconf[method = "GET", action = ""] {
- h2 { "Select tracks for " @item.title }
-
- fieldset.video {
- legend { "Video" }
- @for (i, (tid, track)) in video_tracks.iter().enumerate() {
- input[type="radio", id=tid, name="v", value=tid, checked=i==0];
- label[for=tid] { @format!("{track}") } br;
- }
- input[type="radio", id="v-none", name="v", value=""];
- label[for="v-none"] { "No video" }
- }
-
- fieldset.audio {
- legend { "Audio" }
- @for (i, (tid, track)) in audio_tracks.iter().enumerate() {
- input[type="radio", id=tid, name="a", value=tid, checked=i==0];
- label[for=tid] { @format!("{track}") } br;
- }
- input[type="radio", id="a-none", name="a", value=""];
- label[for="a-none"] { "No audio" }
- }
-
- fieldset.subtitles {
- legend { "Subtitles" }
- @for (_i, (tid, track)) in sub_tracks.iter().enumerate() {
- input[type="radio", id=tid, name="s", value=tid];
- label[for=tid] { @format!("{track}") } br;
- }
- input[type="radio", id="s-none", name="s", value="", checked=true];
- label[for="s-none"] { "No subtitles" }
- }
-
- input[type="submit", value=if playing { "Change tracks" } else { "Start playback" }];
- }
- })
-}