From f7e3841426ed4661ede6ccfff9c306141735d465 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 26 Sep 2025 14:35:23 +0200 Subject: refactor remuxer trait; add webm support; add back transcoding --- transcoder/src/fragment.rs | 69 ++++++++++++++++++++++++++++++++-------------- transcoder/src/lib.rs | 2 +- 2 files changed, 50 insertions(+), 21 deletions(-) (limited to 'transcoder') diff --git a/transcoder/src/fragment.rs b/transcoder/src/fragment.rs index 4cd8b6f..c94b877 100644 --- a/transcoder/src/fragment.rs +++ b/transcoder/src/fragment.rs @@ -5,30 +5,36 @@ */ use crate::{Config, CONF, LOCAL_VIDEO_TRANSCODING_TASKS}; use anyhow::Result; -use jellycache::{async_cache_file, CachePath}; +use jellycache::cache_file; +use jellyremuxer::{demuxers::create_demuxer, muxers::write_fragment, ContainerFormat}; use jellystream_types::{StreamFormatInfo, TrackKind}; use log::info; use std::fmt::Write; -use std::process::Stdio; -use tokio::{ - io::copy, - process::{ChildStdin, Command}, -}; -use winter_matroska::TrackEntry as MatroskaTrackEntry; +use std::fs::File; +use std::io::{copy, Write as W2}; +use std::process::{Command, Stdio}; +use std::thread::spawn; +use winter_matroska::{Segment, TrackEntry as MatroskaTrackEntry}; // TODO odd video resolutions can cause errors when transcoding to YUV42{0,2} // TODO with an implementation that cant handle it (SVT-AV1 is such an impl). -pub async fn transcode( +pub fn transcode( kind: TrackKind, - orig_metadata: &MatroskaTrackEntry, - format: &StreamFormatInfo, input_key: &str, - input: impl FnOnce(ChildStdin), -) -> anyhow::Result { - let command = transcode_command(kind, orig_metadata, format, &*CONF).unwrap(); - async_cache_file("frag-tc", (input_key, &command), async |mut output| { - let _permit = LOCAL_VIDEO_TRANSCODING_TASKS.acquire().await?; + output_format: &StreamFormatInfo, + input: Segment, +) -> Result { + let command = transcode_command( + kind, + &input.tracks.as_ref().unwrap().entries[0], + output_format, + &*CONF, + ) + .unwrap(); + + let output = cache_file("frag-tc", (input_key, &command), |mut output| { + let _permit = LOCAL_VIDEO_TRANSCODING_TASKS.lock().unwrap(); info!("encoding with {command:?}"); let mut args = command.split(" "); let mut proc = Command::new(args.next().unwrap()) @@ -37,17 +43,40 @@ pub async fn transcode( .args(args) .spawn()?; - let stdin = proc.stdin.take().unwrap(); + let mut stdin = proc.stdin.take().unwrap(); let mut stdout = proc.stdout.take().unwrap(); - input(stdin); - copy(&mut stdout, &mut output).await?; + spawn(move || { + copy(&mut stdout, &mut output).unwrap(); + }); + + write_fragment(ContainerFormat::Matroska, &mut stdin, input)?; + stdin.flush()?; + drop(stdin); - proc.wait().await.unwrap().exit_ok()?; + proc.wait().unwrap().exit_ok()?; info!("done"); Ok(()) + })?; + + let mut demuxer = create_demuxer( + ContainerFormat::Matroska, + Box::new(File::open(output.abs())?), + ); + + let info = demuxer.info()?; + let tracks = demuxer.tracks()?; + let mut clusters = Vec::new(); + while let Some((_, cluster)) = demuxer.read_cluster()? { + clusters.push(cluster); + } + + Ok(Segment { + info, + tracks, + clusters, + ..Default::default() }) - .await } fn transcode_command( diff --git a/transcoder/src/lib.rs b/transcoder/src/lib.rs index 665f470..1eac15b 100644 --- a/transcoder/src/lib.rs +++ b/transcoder/src/lib.rs @@ -37,4 +37,4 @@ static CONF: LazyLock = LazyLock::new(|| { }); static LOCAL_IMAGE_TRANSCODING_TASKS: Semaphore = Semaphore::const_new(8); -static LOCAL_VIDEO_TRANSCODING_TASKS: Semaphore = Semaphore::const_new(2); +static LOCAL_VIDEO_TRANSCODING_TASKS: Mutex<()> = Mutex::new(()); -- cgit v1.2.3-70-g09d2