diff options
Diffstat (limited to 'transcoder/src')
-rw-r--r-- | transcoder/src/lib.rs | 1 | ||||
-rw-r--r-- | transcoder/src/thumbnail.rs | 35 |
2 files changed, 36 insertions, 0 deletions
diff --git a/transcoder/src/lib.rs b/transcoder/src/lib.rs index d540e57..63d2cb8 100644 --- a/transcoder/src/lib.rs +++ b/transcoder/src/lib.rs @@ -10,6 +10,7 @@ use tokio::sync::Semaphore; pub mod image; pub mod snippet; pub mod subtitles; +pub mod thumbnail; static LOCAL_IMAGE_TRANSCODING_TASKS: Semaphore = Semaphore::const_new(8); static LOCAL_VIDEO_TRANSCODING_TASKS: Semaphore = Semaphore::const_new(2); diff --git a/transcoder/src/thumbnail.rs b/transcoder/src/thumbnail.rs new file mode 100644 index 0000000..5baf888 --- /dev/null +++ b/transcoder/src/thumbnail.rs @@ -0,0 +1,35 @@ +use crate::LOCAL_IMAGE_TRANSCODING_TASKS; +use jellybase::cache::async_cache_file; +use jellycommon::AssetLocation; +use log::info; +use std::{path::Path, process::Stdio}; +use tokio::{io::copy, process::Command}; + +pub async fn create_thumbnail(path: &Path, time: f64) -> anyhow::Result<AssetLocation> { + Ok(async_cache_file( + &["thumb", path.to_str().unwrap(), &format!("{time}")], + move |mut output| async move { + let _permit = LOCAL_IMAGE_TRANSCODING_TASKS.acquire().await?; + info!("creating thumbnail of {path:?} at {time}s",); + + let mut proc = Command::new("ffmpeg") + .stdout(Stdio::piped()) + .args(&["-ss", &format!("{time}")]) + .args(&["-f", "matroska", "-i", path.to_str().unwrap()]) + .args(&["-frames:v", "1"]) + .args(&["-c:v", "qoi"]) + .args(&["-f", "image2"]) + .args(&["-update", "1"]) + .arg("pipe:1") + .spawn()?; + + let mut stdout = proc.stdout.take().unwrap(); + copy(&mut stdout, &mut output).await?; + + proc.wait().await.unwrap().exit_ok()?; + info!("done"); + Ok(()) + }, + ) + .await?) +} |