/* 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) 2023 metamuffin */ use super::{account::session::Session, layout::LayoutPage}; use crate::{ library::{Item, Library}, routes::{ stream::stream_uri, ui::{error::MyResult, layout::DynLayoutPage}, }, }; use jellycommon::SourceTrackKind; use rocket::{get, FromForm, State}; use std::{path::PathBuf, sync::Arc}; pub fn player_uri(path: &PathBuf) -> String { format!("/player/{}", path.to_str().unwrap()) } #[derive(FromForm, Default, Clone, Debug)] pub struct PlayerConfig { pub a: Option, pub v: Option, pub s: Option, pub webm: bool, } #[get("/player/?", rank = 4)] pub fn r_player( _sess: Session, library: &State, path: PathBuf, conf: PlayerConfig, ) -> MyResult> { let item = library.nested_path(&path)?.get_item()?; if conf.a.is_none() && conf.v.is_none() && conf.s.is_none() { return player_conf(item.clone()); } let tracks = conf .a .into_iter() .chain(conf.v.into_iter()) .chain(conf.s.into_iter()) .collect::>(); Ok(LayoutPage { title: item.info.title.to_owned(), content: markup::new! { video[src=stream_uri(&item.lib_path, &tracks, true), controls]; }, }) } pub fn player_conf<'a>(item: Arc) -> MyResult> { let mut audio_tracks = vec![]; let mut video_tracks = vec![]; let mut sub_tracks = vec![]; for (tid, track) in item.info.tracks.clone() { 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(LayoutPage { title: "Configure Player".to_string(), content: markup::new! { // img.backdrop[src=uri!(r_item_assets(&item.lib_path)).to_string()]; form.playerconf[method = "GET", action = ""] { h2 { "Select tracks for " @item.info.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, checked=i==0]; label[for=tid] { @format!("{track}") } br; } input[type="radio", id="s-none", name="s", value=""]; label[for="s-none"] { "No subtitles" } } input[type="submit", value="Start playback"]; } }, }) }