From a123a1997f3ab527ab83b44ca18bec94883f46d0 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 18 Apr 2025 23:33:29 +0200 Subject: use impl Hash for cache key instead of string --- transcoder/src/fragment.rs | 120 ++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 62 deletions(-) (limited to 'transcoder/src/fragment.rs') diff --git a/transcoder/src/fragment.rs b/transcoder/src/fragment.rs index 88a311e..3e07ad7 100644 --- a/transcoder/src/fragment.rs +++ b/transcoder/src/fragment.rs @@ -3,7 +3,6 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin */ - use crate::LOCAL_VIDEO_TRANSCODING_TASKS; use jellybase::{ cache::{async_cache_file, CachePath}, @@ -21,78 +20,75 @@ use tokio::{ // TODO with an implementation that cant handle it (SVT-AV1 is such an impl). pub async fn transcode( - key: &str, kind: TrackKind, format: &StreamFormatInfo, + input_key: &str, input: impl FnOnce(ChildStdin), ) -> anyhow::Result { - async_cache_file( - &["frag-tc", key, &format!("{format:?}")], - move |mut output| async move { - let _permit = LOCAL_VIDEO_TRANSCODING_TASKS.acquire().await?; - debug!("transcoding fragment with {format:?}"); + let template = match format.codec.as_str() { + "V_MPEG4/ISO/AVC" => CONF.encoders.avc.as_ref(), + "V_MPEGH/ISO/HEVC" => CONF.encoders.hevc.as_ref(), + "V_VP8" => CONF.encoders.vp8.as_ref(), + "V_VP9" => CONF.encoders.vp9.as_ref(), + "V_AV1" => CONF.encoders.av1.as_ref(), + _ => None, + } + .or(CONF.encoders.generic.as_ref()) + .cloned() + .unwrap_or("ffmpeg %i %f %e %o".to_owned()); - let template = match format.codec.as_str() { - "V_MPEG4/ISO/AVC" => CONF.encoders.avc.as_ref(), - "V_MPEGH/ISO/HEVC" => CONF.encoders.hevc.as_ref(), - "V_VP8" => CONF.encoders.vp8.as_ref(), - "V_VP9" => CONF.encoders.vp9.as_ref(), - "V_AV1" => CONF.encoders.av1.as_ref(), - _ => None, - } - .or(CONF.encoders.generic.as_ref()) - .cloned() - .unwrap_or("ffmpeg %i %f %e %o".to_owned()); + let filter = match kind { + TrackKind::Video => format!("-vf scale={}:-1", format.width.unwrap()), + TrackKind::Audio => format!(""), + TrackKind::Subtitle => String::new(), + }; + let typechar = match kind { + TrackKind::Video => "v", + TrackKind::Audio => "a", + TrackKind::Subtitle => "s", + }; + let fallback_encoder = match format.codec.as_str() { + "A_OPUS" => "libopus", + "V_VP8" => "libvpx", + "V_VP9" => "libvpx-vp9", + "V_AV1" => "libaom", // svtav1 is x86 only :( + "V_MPEG4/ISO/AVC" => "libx264", + "V_MPEGH/ISO/HEVC" => "libx265", + _ => "", + }; - let filter = match kind { - TrackKind::Video => format!("-vf scale={}:-1", format.width.unwrap()), - TrackKind::Audio => format!(""), - TrackKind::Subtitle => String::new(), - }; - let typechar = match kind { - TrackKind::Video => "v", - TrackKind::Audio => "a", - TrackKind::Subtitle => "s", - }; - let fallback_encoder = match format.codec.as_str() { - "A_OPUS" => "libopus", - "V_VP8" => "libvpx", - "V_VP9" => "libvpx-vp9", - "V_AV1" => "libaom", // svtav1 is x86 only :( - "V_MPEG4/ISO/AVC" => "libx264", - "V_MPEGH/ISO/HEVC" => "libx265", - _ => "", - }; + let args = template + .replace("%i", "-f matroska -i pipe:0 -copyts") + .replace("%o", "-f matroska pipe:1") + .replace("%f", &filter) + .replace("%e", "-c:%t %c -b:%t %r") + .replace("%t", typechar) + .replace("%c", fallback_encoder) + .replace("%r", &(format.bitrate as i64).to_string()) + .replace(" ", " "); - let args = template - .replace("%i", "-f matroska -i pipe:0 -copyts") - .replace("%o", "-f matroska pipe:1") - .replace("%f", &filter) - .replace("%e", "-c:%t %c -b:%t %r") - .replace("%t", typechar) - .replace("%c", fallback_encoder) - .replace("%r", &(format.bitrate as i64).to_string()) - .replace(" ", " "); + async_cache_file("frag-tc", (input_key, &args), async |mut output| { + let _permit = LOCAL_VIDEO_TRANSCODING_TASKS.acquire().await?; + debug!("transcoding fragment with {format:?}"); - info!("encoding with {:?}", args); + info!("encoding with {:?}", args); - let mut args = args.split(" "); - let mut proc = Command::new(args.next().unwrap()) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .args(args) - .spawn()?; + let mut args = args.split(" "); + let mut proc = Command::new(args.next().unwrap()) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .args(args) + .spawn()?; - let stdin = proc.stdin.take().unwrap(); - let mut stdout = proc.stdout.take().unwrap(); + let stdin = proc.stdin.take().unwrap(); + let mut stdout = proc.stdout.take().unwrap(); - input(stdin); - copy(&mut stdout, &mut output).await?; + input(stdin); + copy(&mut stdout, &mut output).await?; - proc.wait().await.unwrap().exit_ok()?; - info!("done"); - Ok(()) - }, - ) + proc.wait().await.unwrap().exit_ok()?; + info!("done"); + Ok(()) + }) .await } -- cgit v1.2.3-70-g09d2