/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin */ use crate::LOCAL_TRANSCODING_TASKS; use jellybase::cache::async_cache_file; use jellycommon::{jhls::EncodingProfile, AssetLocation}; use log::info; use std::process::Stdio; use tokio::{ io::copy, process::{ChildStdin, Command}, }; pub async fn transcode( key: &str, enc: &EncodingProfile, input: impl FnOnce(ChildStdin), ) -> anyhow::Result { Ok(async_cache_file( &["snip-tc", key, &format!("{enc:?}")], move |mut output| async move { let _permit = LOCAL_TRANSCODING_TASKS.acquire().await?; info!("transcoding snippet {key}"); let args = match enc { EncodingProfile::Video { codec, preset, bitrate, width, } => [ "-vf".to_string(), format!("scale={width}:-1"), "-c:v".to_string(), codec.to_string(), "-preset".to_string(), format!("{preset}"), "-b:v".to_string(), format!("{bitrate}"), ] .to_vec(), EncodingProfile::Audio { codec, bitrate, sample_rate: _, } => [ // TODO resample? "-c:a".to_string(), codec.to_string(), "-b:a".to_string(), format!("{bitrate}"), ] .to_vec(), EncodingProfile::Subtitles { codec } => { ["-c:s".to_string(), codec.to_string()].to_vec() } }; info!("encoding with {:?}", args.join(" ")); let mut proc = Command::new("ffmpeg") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .args(&["-f", "matroska", "-i", "pipe:0"]) .args(args) .args(&["-f", "webm", "pipe:1"]) .spawn()?; let stdin = proc.stdin.take().unwrap(); let mut stdout = proc.stdout.take().unwrap(); input(stdin); copy(&mut stdout, &mut output).await?; proc.wait().await.unwrap().exit_ok()?; info!("done"); Ok(()) }, ) .await?) }