mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-23 15:30:34 -04:00
Add identify route
This commit is contained in:
parent
5cdcff0cd0
commit
f80289aef1
10
transcoder/src/identify.rs
Normal file
10
transcoder/src/identify.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct MediaInfo {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn identify(path: String) -> Result<MediaInfo, std::io::Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
@ -1,11 +1,19 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use actix_files::NamedFile;
|
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 error::ApiError;
|
||||||
|
|
||||||
use crate::transcode::{Quality, Transcoder};
|
use crate::{
|
||||||
|
identify::{identify, MediaInfo},
|
||||||
|
transcode::{Quality, Transcoder},
|
||||||
|
};
|
||||||
mod error;
|
mod error;
|
||||||
|
mod identify;
|
||||||
mod paths;
|
mod paths;
|
||||||
mod transcode;
|
mod transcode;
|
||||||
mod utils;
|
mod utils;
|
||||||
@ -16,7 +24,7 @@ fn get_client_id(req: HttpRequest) -> Result<String, ApiError> {
|
|||||||
.map(|x| x.to_str().unwrap().to_string())
|
.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<NamedFile> {
|
async fn get_direct(query: web::Path<(String, String)>) -> Result<NamedFile> {
|
||||||
let (resource, slug) = query.into_inner();
|
let (resource, slug) = query.into_inner();
|
||||||
let path = paths::get_path(resource, slug).await.map_err(|e| {
|
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<NamedFile> {
|
|||||||
Ok(NamedFile::open_async(path).await?)
|
Ok(NamedFile::open_async(path).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/{resource}/{quality}/{slug}/index.m3u8")]
|
#[get("/{resource}/{slug}/{quality}/index.m3u8")]
|
||||||
async fn get_transcoded(
|
async fn get_transcoded(
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
query: web::Path<(String, String, String)>,
|
query: web::Path<(String, String, String)>,
|
||||||
transcoder: web::Data<Transcoder>,
|
transcoder: web::Data<Transcoder>,
|
||||||
) -> Result<String, ApiError> {
|
) -> Result<String, ApiError> {
|
||||||
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 {
|
let quality = Quality::from_str(quality.as_str()).map_err(|_| ApiError::BadRequest {
|
||||||
error: "Invalid quality".to_string(),
|
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(
|
async fn get_chunk(
|
||||||
req: HttpRequest,
|
req: HttpRequest,
|
||||||
query: web::Path<(String, String, String, u32)>,
|
query: web::Path<(String, String, String, u32)>,
|
||||||
transcoder: web::Data<Transcoder>,
|
transcoder: web::Data<Transcoder>,
|
||||||
) -> Result<NamedFile, ApiError> {
|
) -> Result<NamedFile, ApiError> {
|
||||||
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 {
|
let quality = Quality::from_str(quality.as_str()).map_err(|_| ApiError::BadRequest {
|
||||||
error: "Invalid quality".to_string(),
|
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<Json<MediaInfo>, 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]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
let state = web::Data::new(Transcoder::new());
|
let state = web::Data::new(Transcoder::new());
|
||||||
@ -91,6 +114,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.service(get_direct)
|
.service(get_direct)
|
||||||
.service(get_transcoded)
|
.service(get_transcoded)
|
||||||
.service(get_chunk)
|
.service(get_chunk)
|
||||||
|
.service(identify_resource)
|
||||||
})
|
})
|
||||||
.bind(("0.0.0.0", 7666))?
|
.bind(("0.0.0.0", 7666))?
|
||||||
.run()
|
.run()
|
||||||
|
@ -7,9 +7,20 @@ struct Item {
|
|||||||
|
|
||||||
pub async fn get_path(_resource: String, slug: String) -> Result<String, reqwest::Error> {
|
pub async fn get_path(_resource: String, slug: String) -> Result<String, reqwest::Error> {
|
||||||
let api_url = std::env::var("API_URL").unwrap_or("http://back:5000".to_string());
|
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/
|
// 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?
|
.await?
|
||||||
.error_for_status()?
|
.error_for_status()?
|
||||||
.json::<Item>()
|
.json::<Item>()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user