Files
lumi-re/backend/exposition/src/video/handler.rs
T

63 lines
2.3 KiB
Rust

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<Arc<VideoService>>,
video_id: web::Path<Uuid>
) -> 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::<TokioVideoFile>() {
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<Arc<VideoService>>
) -> impl Responder {
match video_service.list_root_folder() {
Ok(library_items) => {
let result: Vec<LibraryItemDto> = library_items.iter()
.map(LibraryItemDto::new)
.collect();
HttpResponse::Ok().json(result)
}
Err(_) => HttpResponse::InternalServerError().finish()
}
}