From 2676e755286d117b100d379fce84ec3da6d8ae98 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 29 Jan 2024 13:22:21 +0100 Subject: consistent name for {snippet,segment?,fragment} --- transcoder/src/fragment.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++ transcoder/src/lib.rs | 2 +- transcoder/src/snippet.rs | 102 --------------------------------------------- 3 files changed, 103 insertions(+), 103 deletions(-) create mode 100644 transcoder/src/fragment.rs delete mode 100644 transcoder/src/snippet.rs (limited to 'transcoder/src') diff --git a/transcoder/src/fragment.rs b/transcoder/src/fragment.rs new file mode 100644 index 0000000..90512c4 --- /dev/null +++ b/transcoder/src/fragment.rs @@ -0,0 +1,102 @@ +/* + 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) 2024 metamuffin +*/ + +use crate::LOCAL_VIDEO_TRANSCODING_TASKS; +use jellybase::cache::{async_cache_file, CachePath}; +use jellycommon::jhls::EncodingProfile; +use log::{debug, info}; +use std::process::Stdio; +use tokio::{ + io::copy, + process::{ChildStdin, Command}, +}; + +// TODO odd video resolutions can cause errors when transcoding to YUV42{0,2} +// TODO with an implementation that cant handle it (SVT-AV1 such an impl). + +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_VIDEO_TRANSCODING_TASKS.acquire().await?; + debug!("transcoding snippet with {enc:?}"); + + let mut args = Vec::new(); + match enc { + EncodingProfile::Video { + codec, + preset, + bitrate, + width, + } => { + if let Some(width) = width { + args.push("-vf".to_string()); + args.push(format!("scale={width}:-1")); + } + args.push("-c:v".to_string()); + args.push(codec.to_string()); + if let Some(preset) = preset { + args.push("-preset".to_string()); + args.push(format!("{preset}")); + } + args.push("-b:v".to_string()); + args.push(format!("{bitrate}")); + } + EncodingProfile::Audio { + codec, + bitrate, + sample_rate, + channels, + } => { + if let Some(channels) = channels { + args.push("-ac".to_string()); + args.push(format!("{channels}")) + } + if let Some(sample_rate) = sample_rate { + args.push("-ar".to_string()); + args.push(format!("{sample_rate}")) + } + args.push("-c:a".to_string()); + args.push(codec.to_string()); + args.push("-b:a".to_string()); + args.push(format!("{bitrate}")); + } + EncodingProfile::Subtitles { codec } => { + args.push("-c:s".to_string()); + args.push(codec.to_string()); + } + }; + 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 mut proc = Command::new("cat") + // .stdin(Stdio::piped()) + // .stdout(Stdio::piped()) + // .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?) +} diff --git a/transcoder/src/lib.rs b/transcoder/src/lib.rs index 35b5605..eb56229 100644 --- a/transcoder/src/lib.rs +++ b/transcoder/src/lib.rs @@ -8,7 +8,7 @@ use tokio::sync::Semaphore; pub mod image; -pub mod snippet; +pub mod fragment; pub mod subtitles; pub mod thumbnail; diff --git a/transcoder/src/snippet.rs b/transcoder/src/snippet.rs deleted file mode 100644 index 90512c4..0000000 --- a/transcoder/src/snippet.rs +++ /dev/null @@ -1,102 +0,0 @@ -/* - 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) 2024 metamuffin -*/ - -use crate::LOCAL_VIDEO_TRANSCODING_TASKS; -use jellybase::cache::{async_cache_file, CachePath}; -use jellycommon::jhls::EncodingProfile; -use log::{debug, info}; -use std::process::Stdio; -use tokio::{ - io::copy, - process::{ChildStdin, Command}, -}; - -// TODO odd video resolutions can cause errors when transcoding to YUV42{0,2} -// TODO with an implementation that cant handle it (SVT-AV1 such an impl). - -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_VIDEO_TRANSCODING_TASKS.acquire().await?; - debug!("transcoding snippet with {enc:?}"); - - let mut args = Vec::new(); - match enc { - EncodingProfile::Video { - codec, - preset, - bitrate, - width, - } => { - if let Some(width) = width { - args.push("-vf".to_string()); - args.push(format!("scale={width}:-1")); - } - args.push("-c:v".to_string()); - args.push(codec.to_string()); - if let Some(preset) = preset { - args.push("-preset".to_string()); - args.push(format!("{preset}")); - } - args.push("-b:v".to_string()); - args.push(format!("{bitrate}")); - } - EncodingProfile::Audio { - codec, - bitrate, - sample_rate, - channels, - } => { - if let Some(channels) = channels { - args.push("-ac".to_string()); - args.push(format!("{channels}")) - } - if let Some(sample_rate) = sample_rate { - args.push("-ar".to_string()); - args.push(format!("{sample_rate}")) - } - args.push("-c:a".to_string()); - args.push(codec.to_string()); - args.push("-b:a".to_string()); - args.push(format!("{bitrate}")); - } - EncodingProfile::Subtitles { codec } => { - args.push("-c:s".to_string()); - args.push(codec.to_string()); - } - }; - 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 mut proc = Command::new("cat") - // .stdin(Stdio::piped()) - // .stdout(Stdio::piped()) - // .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?) -} -- cgit v1.2.3-70-g09d2