diff --git a/transcoder/src/identify.rs b/transcoder/src/identify.rs new file mode 100644 index 00000000..958da9b7 --- /dev/null +++ b/transcoder/src/identify.rs @@ -0,0 +1,10 @@ +use serde::Serialize; + +#[derive(Serialize)] +pub struct MediaInfo { + +} + +pub fn identify(path: String) -> Result { + todo!() +} diff --git a/transcoder/src/main.rs b/transcoder/src/main.rs index afac84f3..235e8fad 100644 --- a/transcoder/src/main.rs +++ b/transcoder/src/main.rs @@ -1,11 +1,19 @@ use std::str::FromStr; use actix_files::NamedFile; -use actix_web::{get, web, App, HttpRequest, HttpServer, Result}; +use actix_web::{ + get, + web::{self, Json}, + App, HttpRequest, HttpServer, Result, +}; use error::ApiError; -use crate::transcode::{Quality, Transcoder}; +use crate::{ + identify::{identify, MediaInfo}, + transcode::{Quality, Transcoder}, +}; mod error; +mod identify; mod paths; mod transcode; mod utils; @@ -16,7 +24,7 @@ fn get_client_id(req: HttpRequest) -> Result { .map(|x| x.to_str().unwrap().to_string()) } -#[get("/{resource}/direct/{slug}")] +#[get("/{resource}/{slug}/direct{extension}")] async fn get_direct(query: web::Path<(String, String)>) -> Result { let (resource, slug) = query.into_inner(); let path = paths::get_path(resource, slug).await.map_err(|e| { @@ -27,13 +35,13 @@ async fn get_direct(query: web::Path<(String, String)>) -> Result { Ok(NamedFile::open_async(path).await?) } -#[get("/{resource}/{quality}/{slug}/index.m3u8")] +#[get("/{resource}/{slug}/{quality}/index.m3u8")] async fn get_transcoded( req: HttpRequest, query: web::Path<(String, String, String)>, transcoder: web::Data, ) -> Result { - let (resource, quality, slug) = query.into_inner(); + let (resource, slug, quality) = query.into_inner(); let quality = Quality::from_str(quality.as_str()).map_err(|_| ApiError::BadRequest { error: "Invalid quality".to_string(), })?; @@ -52,13 +60,13 @@ async fn get_transcoded( }) } -#[get("/{resource}/{quality}/{slug}/segments-{chunk}.ts")] +#[get("/{resource}/{slug}/{quality}/segments-{chunk}.ts")] async fn get_chunk( req: HttpRequest, query: web::Path<(String, String, String, u32)>, transcoder: web::Data, ) -> Result { - let (resource, quality, slug, chunk) = query.into_inner(); + let (resource, slug, quality, chunk) = query.into_inner(); let quality = Quality::from_str(quality.as_str()).map_err(|_| ApiError::BadRequest { error: "Invalid quality".to_string(), })?; @@ -81,6 +89,21 @@ async fn get_chunk( }) } +#[get("/{resource}/{slug}/identify")] +async fn identify_resource( + query: web::Path<(String, String)>, +) -> Result, ApiError> { + let (resource, slug) = query.into_inner(); + let path = paths::get_path(resource, slug) + .await + .map_err(|_| ApiError::NotFound)?; + + identify(path).map(|info| Json(info)).map_err(|e| { + eprintln!("Unhandled error occured while transcoding: {}", e); + ApiError::InternalError + }) +} + #[actix_web::main] async fn main() -> std::io::Result<()> { let state = web::Data::new(Transcoder::new()); @@ -91,6 +114,7 @@ async fn main() -> std::io::Result<()> { .service(get_direct) .service(get_transcoded) .service(get_chunk) + .service(identify_resource) }) .bind(("0.0.0.0", 7666))? .run() diff --git a/transcoder/src/paths.rs b/transcoder/src/paths.rs index 5f5558b1..25853a39 100644 --- a/transcoder/src/paths.rs +++ b/transcoder/src/paths.rs @@ -7,9 +7,20 @@ struct Item { pub async fn get_path(_resource: String, slug: String) -> Result { let api_url = std::env::var("API_URL").unwrap_or("http://back:5000".to_string()); + let api_key = std::env::var("KYOO_APIKEYS") + .expect("Missing api keys.") + .split(',') + .next() + .unwrap() + .to_string(); + // TODO: Store the client somewhere gobal + let client = reqwest::Client::new(); // TODO: The api create dummy episodes for movies right now so we hard code the /episode/ - reqwest::get(format!("{api_url}/episode/{slug}")) + client + .get(format!("{api_url}/episode/{slug}")) + .header("X-API-KEY", api_key) + .send() .await? .error_for_status()? .json::()