This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 2.1 kB View raw
1use crate::{Video, ui::Log}; 2use axum::{Router, extract::Path, response::Html, routing}; 3use std::sync::Arc; 4 5pub struct VideoServer { 6 pub router: Router, 7} 8 9const PREVIEW_HTML: &str = include_str!("preview.html"); 10 11impl VideoServer { 12 pub fn new<C: 'static + Default>(video: Arc<Video<C>>) -> Self { 13 let _ = video.progress.clear(); 14 15 let total_frames_count = video.ms_to_frames(video.total_duration_ms()); 16 17 let router = Router::new() 18 .route("/", routing::get(async move || Html(PREVIEW_HTML.replace("%frames_count%", &total_frames_count.to_string())))) 19 .route("/frame/{number_dot_svg}", routing::get(async move |Path(number_dot_svg): Path<String>| { 20 let number: usize = number_dot_svg 21 .strip_suffix(".svg") 22 .expect("Expecting /frame/{number}.svg, didn't find .svg at the end") 23 .parse() 24 .expect("Expecting /frame/{number}.svg, couldn't parse {number} to an integer"); 25 26 println!(""); 27 println!("Frame number requested: {number}"); 28 29 match video.render_frame(number, 500) { 30 // Ok((timecode, svg)) => svg.to_string().replace( 31 // "</svg>", 32 // &format!(r#"<meta name="shapemaker:timecode" content="{timecode}" /></svg>"#) 33 // ), 34 Ok(svg) => svg.to_string(), 35 Err(err) => format!("{err:?}"), 36 } 37 }), 38 ); 39 40 Self { router } 41 } 42 43 pub async fn start(self, address: &str) { 44 axum::serve( 45 tokio::net::TcpListener::bind(address).await.unwrap(), 46 self.router, 47 ) 48 .await 49 .unwrap(); 50 } 51} 52 53impl<C: 'static + Default> Video<C> { 54 pub async fn serve(self, address: &str) { 55 self.progress_bars 56 .loading 57 .log_cyan("Listening", &format!("on {address}")); 58 VideoServer::new(Arc::new(self)).start(address).await; 59 } 60}