OpenRouter Support, Insight Chat and User injection #56
@@ -55,6 +55,16 @@ pub fn playlist_file_for(playlist_dir: &str, video_path: &Path) -> PathBuf {
|
||||
PathBuf::from(format!("{}/{}.m3u8", playlist_dir, filename))
|
||||
}
|
||||
|
||||
/// Sentinel path written next to a would-be playlist when ffmpeg cannot
|
||||
/// transcode the source (e.g. truncated mp4 with no moov atom). Its presence
|
||||
/// causes future scans to skip the file instead of re-running ffmpeg every
|
||||
/// pass. Delete the `.unsupported` file to force a retry.
|
||||
pub fn playlist_unsupported_sentinel(playlist_file: &Path) -> PathBuf {
|
||||
let mut s = playlist_file.as_os_str().to_owned();
|
||||
s.push(".unsupported");
|
||||
PathBuf::from(s)
|
||||
}
|
||||
|
||||
pub async fn create_playlist(video_path: &str, playlist_file: &str) -> Result<Child> {
|
||||
if Path::new(playlist_file).exists() {
|
||||
debug!("Playlist already exists: {}", playlist_file);
|
||||
@@ -319,7 +329,10 @@ impl Handler<ScanDirectoryMessage> for VideoPlaylistManager {
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| e.file_type().is_file())
|
||||
.filter(is_video)
|
||||
.filter(|e| !playlist_file_for(&playlist_dir_str, e.path()).exists())
|
||||
.filter(|e| {
|
||||
let playlist = playlist_file_for(&playlist_dir_str, e.path());
|
||||
!playlist.exists() && !playlist_unsupported_sentinel(&playlist).exists()
|
||||
})
|
||||
.collect::<Vec<DirEntry>>();
|
||||
|
||||
let scan_dir_name = msg.directory.clone();
|
||||
@@ -393,7 +406,8 @@ impl Handler<QueueVideosMessage> for VideoPlaylistManager {
|
||||
let playlist_generator = self.playlist_generator.clone();
|
||||
|
||||
for video_path in msg.video_paths {
|
||||
if playlist_file_for(&playlist_dir_str, &video_path).exists() {
|
||||
let playlist = playlist_file_for(&playlist_dir_str, &video_path);
|
||||
if playlist.exists() || playlist_unsupported_sentinel(&playlist).exists() {
|
||||
continue;
|
||||
}
|
||||
let path_str = video_path.to_string_lossy().to_string();
|
||||
@@ -683,6 +697,20 @@ impl Handler<GeneratePlaylistMessage> for PlaylistGenerator {
|
||||
};
|
||||
error!("ffmpeg failed for {}: {}", video_file, detail);
|
||||
cleanup_partial_hls(&playlist_tmp, playlist_path.as_str(), video_stem).await;
|
||||
let sentinel = playlist_unsupported_sentinel(Path::new(&playlist_file));
|
||||
if let Err(se) = tokio::fs::write(&sentinel, b"").await {
|
||||
warn!(
|
||||
"Failed to write playlist sentinel {}: {}",
|
||||
sentinel.display(),
|
||||
se
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
"Wrote playlist sentinel {} so future scans skip {}",
|
||||
sentinel.display(),
|
||||
video_file
|
||||
);
|
||||
}
|
||||
span.set_status(Status::error(detail.clone()));
|
||||
Err(std::io::Error::other(detail))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user