From 2a273a3ed95223080b7e41386490176220216677 Mon Sep 17 00:00:00 2001 From: Cameron Cordes Date: Thu, 7 May 2026 16:41:24 -0400 Subject: [PATCH] thumbnails: stop video failures from re-logging every watcher tick MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit generate_video_thumbnail used .output().expect(...), which only catches spawn failure — non-zero ffmpeg exits were silently discarded. With no thumbnail and no .unsupported sentinel left behind, the watcher re-detected the file as missing every quick-scan tick and re-logged "New file detected (missing thumbnail)" forever. Mirror the image branch: return io::Result, check status.success(), and write the sentinel from create_thumbnails on failure. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/main.rs | 11 ++++++++++- src/video/actors.rs | 18 +++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 68f8f61..a3070b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1687,7 +1687,16 @@ fn create_thumbnails(libs: &[libraries::Library], excluded_dirs: &[String]) { ]); debug!("Generating video thumbnail: {:?}", thumb_path); - generate_video_thumbnail(src, &thumb_path); + if let Err(e) = generate_video_thumbnail(src, &thumb_path) { + let sentinel = unsupported_thumbnail_sentinel(&thumb_path); + error!( + "Unable to thumbnail video {:?}: {}. Writing sentinel {:?}", + src, e, sentinel + ); + if let Err(se) = std::fs::write(&sentinel, b"") { + warn!("Failed to write sentinel {:?}: {}", sentinel, se); + } + } video_span.end(); } else if is_image(&entry) { match generate_image_thumbnail(src, &thumb_path) { diff --git a/src/video/actors.rs b/src/video/actors.rs index c7300ef..7722a5d 100644 --- a/src/video/actors.rs +++ b/src/video/actors.rs @@ -107,19 +107,27 @@ pub async fn create_playlist(video_path: &str, playlist_file: &str) -> Result std::io::Result<()> { + let output = Command::new("ffmpeg") .arg("-ss") .arg("3") .arg("-i") - .arg(path.to_str().unwrap()) + .arg(path) .arg("-vframes") .arg("1") .arg("-f") .arg("image2") .arg(destination) - .output() - .expect("Failure to create video frame"); + .output()?; + + if !output.status.success() { + return Err(std::io::Error::other(format!( + "ffmpeg failed ({}): {}", + output.status, + String::from_utf8_lossy(&output.stderr).trim() + ))); + } + Ok(()) } /// Use ffmpeg to extract a 200px-wide thumbnail from formats the `image` crate