diff --git a/transcoder/Dockerfile b/transcoder/Dockerfile index eba3c847..39bbf803 100644 --- a/transcoder/Dockerfile +++ b/transcoder/Dockerfile @@ -11,7 +11,7 @@ COPY src src RUN cargo install --path . FROM alpine -RUN apk add --no-cache ffmpeg +RUN apk add --no-cache ffmpeg mediainfo COPY --from=builder /usr/local/cargo/bin/transcoder ./transcoder EXPOSE 7666 diff --git a/transcoder/Dockerfile.dev b/transcoder/Dockerfile.dev index 1d77ee35..c08026a0 100644 --- a/transcoder/Dockerfile.dev +++ b/transcoder/Dockerfile.dev @@ -1,5 +1,5 @@ FROM rust:alpine -RUN apk add --no-cache musl-dev ffmpeg +RUN apk add --no-cache musl-dev ffmpeg mediainfo RUN cargo install cargo-watch WORKDIR /app diff --git a/transcoder/src/identify.rs b/transcoder/src/identify.rs index 54e03cd6..dc83f3e3 100644 --- a/transcoder/src/identify.rs +++ b/transcoder/src/identify.rs @@ -1,5 +1,6 @@ +use json::JsonValue; use serde::Serialize; -use std::str; +use std::str::{self, FromStr}; use tokio::process::Command; use utoipa::ToSchema; @@ -65,20 +66,26 @@ pub async fn identify(path: String) -> Result { .arg("--Language=raw") .arg(path) .output() - .await?; + .await + .expect("Error running the mediainfo command"); assert!(mediainfo.status.success()); let output = json::parse(str::from_utf8(mediainfo.stdout.as_slice()).unwrap()).unwrap(); - let general = output["media"]["tracks"] + let general = output["media"]["track"] .members() .find(|x| x["@type"] == "General") .unwrap(); + fn parse(v: &JsonValue) -> Option { + v.as_str().and_then(|x| x.parse::().ok()) + } + + // TODO: Every number is wrapped by "" in mediainfo json's mode so the number parsing is wrong. Ok(MediaInfo { - length: general["Duration"].as_f32().unwrap(), + length: parse::(&general["Duration"]).unwrap(), container: general["Format"].as_str().unwrap().to_string(), video: { - let v = output["media"]["tracks"] + let v = output["media"]["track"] .members() .find(|x| x["@type"] == "Video") .expect("File without video found. This is not supported"); @@ -86,17 +93,17 @@ pub async fn identify(path: String) -> Result { // This codec is not in the right format (does not include bitdepth...). codec: v["Format"].as_str().unwrap().to_string(), language: v["Language"].as_str().map(|x| x.to_string()), - quality: Quality::from_height(v["Height"].as_u32().unwrap()), - width: v["Width"].as_u32().unwrap(), - height: v["Height"].as_u32().unwrap(), - bitrate: v["BitRate"].as_u32().unwrap(), + quality: Quality::from_height(parse::(&v["Height"]).unwrap()), + width: parse::(&v["Width"]).unwrap(), + height: parse::(&v["Height"]).unwrap(), + bitrate: parse::(&v["BitRate"]).unwrap(), } }, - audios: output["media"]["tracks"] + audios: output["media"]["track"] .members() .filter(|x| x["@type"] == "Audio") .map(|a| Track { - index: a["StreamOrder"].as_u32().unwrap(), + index: parse::(&a["StreamOrder"]).unwrap(), title: a["Title"].as_str().map(|x| x.to_string()), language: a["Language"].as_str().map(|x| x.to_string()), // TODO: format is invalid. Channels count missing... @@ -105,11 +112,11 @@ pub async fn identify(path: String) -> Result { forced: a["Forced"] == "No", }) .collect(), - subtitles: output["media"]["tracks"] + subtitles: output["media"]["track"] .members() .filter(|x| x["@type"] == "Text") .map(|a| Track { - index: a["StreamOrder"].as_u32().unwrap(), + index: parse::(&a["StreamOrder"]).unwrap(), title: a["Title"].as_str().map(|x| x.to_string()), language: a["Language"].as_str().map(|x| x.to_string()), // TODO: format is invalid. Channels count missing... @@ -119,7 +126,7 @@ pub async fn identify(path: String) -> Result { }) .collect(), fonts: vec![], - chapters: output["media"]["tracks"] + chapters: output["media"]["track"] .members() .find(|x| x["@type"] == "Menu") .map(|x| { diff --git a/transcoder/src/main.rs b/transcoder/src/main.rs index 769a83d5..42f05aa6 100644 --- a/transcoder/src/main.rs +++ b/transcoder/src/main.rs @@ -94,7 +94,7 @@ async fn identify_resource( .map_err(|_| ApiError::NotFound)?; identify(path).await.map(|info| Json(info)).map_err(|e| { - eprintln!("Unhandled error occured while transcoding: {}", e); + eprintln!("Unhandled error occured while identifing the resource: {}", e); ApiError::InternalError }) } diff --git a/transcoder/src/transcode.rs b/transcoder/src/transcode.rs index 730d3331..634a7f63 100644 --- a/transcoder/src/transcode.rs +++ b/transcoder/src/transcode.rs @@ -98,7 +98,7 @@ impl Quality { pub fn from_height(height: u32) -> Self { Self::iter() - .find(|x| x.height() <= height) + .find(|x| x.height() >= height) .unwrap_or(&Quality::P240) .clone() }