use std::sync::Arc; use actix_web::{get, web, HttpResponse, Responder}; use tokio::fs::File; use tokio_util::codec::{BytesCodec, FramedRead}; use futures_util::stream::StreamExt; use uuid::Uuid; use lumiere_application::video::service::VideoService; use lumiere_infrastructure::video::model::TokioVideoFile; use crate::video::model::LibraryItemDto; #[get("/api/download")] pub async fn download_file() -> impl Responder { HttpResponse::Ok() .content_type("application/octet-stream") .streaming(async_stream::stream! { let file = File::open("/home/florian/Videos/Kaamelott_Le_film.avi").await.expect("Failed to open file"); let mut stream = FramedRead::new(file, BytesCodec::new()); while let Some(chunk) = stream.next().await { yield chunk.map(|bytes| bytes.freeze()); } }) } #[get("/api/videos/{video_id}/stream")] pub async fn get_video_stream( video_service: web::Data>, video_id: web::Path ) -> impl Responder { let video_result = video_service.get_video_stream(video_id.into_inner()); match video_result { Ok(video) => { if let Some(tokioVideoFile) = video.file.as_any().downcast_ref::() { HttpResponse::Ok() .content_type("application/octet-stream") .streaming(async_stream::stream! { let mut stream = FramedRead::new(tokioVideoFile.file, BytesCodec::new()); while let Some(chunk) = stream.next().await { yield chunk.map(|bytes| bytes.freeze()); } }) } else { HttpResponse::InternalServerError().body("Video file format is not handled.") } } Err(error) => HttpResponse::InternalServerError().body("C P T") } } #[get("/api/library")] pub async fn get_root_folder_content( video_service: web::Data> ) -> impl Responder { match video_service.list_root_folder() { Ok(library_items) => { let result: Vec = library_items.iter() .map(LibraryItemDto::new) .collect(); HttpResponse::Ok().json(result) } Err(_) => HttpResponse::InternalServerError().finish() } }