feature/hls-content-hash #95

Merged
cameron merged 10 commits from feature/hls-content-hash into master 2026-05-15 20:09:49 +00:00
4 changed files with 31 additions and 41 deletions
Showing only changes of commit 8c91bf554b - Show all commits

View File

@@ -80,8 +80,7 @@ pub async fn generate_video(
return HttpResponse::BadRequest().finish(); return HttpResponse::BadRequest().finish();
}; };
let preferred_library = let preferred_library = libraries::resolve_library_param(&app_state, body.library.as_deref())
libraries::resolve_library_param(&app_state, body.library.as_deref())
.ok() .ok()
.flatten() .flatten()
.unwrap_or_else(|| app_state.primary_library()); .unwrap_or_else(|| app_state.primary_library());
@@ -122,7 +121,11 @@ pub async fn generate_video(
// already-ingested videos. // already-ingested videos.
let hash_from_db: Option<String> = { let hash_from_db: Option<String> = {
let mut dao = exif_dao.lock().expect("Unable to lock ExifDao"); let mut dao = exif_dao.lock().expect("Unable to lock ExifDao");
match dao.get_exif_batch(&context, Some(resolved_library_id), &[rel_path.clone()]) { match dao.get_exif_batch(
&context,
Some(resolved_library_id),
std::slice::from_ref(&rel_path),
) {
Ok(rows) => rows.into_iter().next().and_then(|r| r.content_hash), Ok(rows) => rows.into_iter().next().and_then(|r| r.content_hash),
Err(e) => { Err(e) => {
warn!( warn!(

View File

@@ -256,9 +256,8 @@ pub async fn hls_stats_handler(
// Synchronous file IO + DB query — run on a blocking pool so the // Synchronous file IO + DB query — run on a blocking pool so the
// actix worker thread stays free for other requests. // actix worker thread stays free for other requests.
let stats = match web::block(move || compute_and_publish(&libraries, &exif_dao, &video_dir)) let stats =
.await match web::block(move || compute_and_publish(&libraries, &exif_dao, &video_dir)).await {
{
Ok(s) => s, Ok(s) => s,
Err(e) => { Err(e) => {
warn!("/hls/stats: blocking task failed: {:?}", e); warn!("/hls/stats: blocking task failed: {:?}", e);

View File

@@ -38,10 +38,7 @@ pub struct RetireStats {
impl RetireStats { impl RetireStats {
pub fn total_deleted(&self) -> usize { pub fn total_deleted(&self) -> usize {
self.deleted_playlists self.deleted_playlists + self.deleted_segments + self.deleted_sentinels + self.deleted_tmp
+ self.deleted_segments
+ self.deleted_sentinels
+ self.deleted_tmp
} }
} }

View File

@@ -79,9 +79,10 @@ pub fn cleanup_orphaned_playlists(
info!(" Cleanup interval: {} seconds", cleanup_interval_secs); info!(" Cleanup interval: {} seconds", cleanup_interval_secs);
info!(" HLS directory: {}", video_path.display()); info!(" HLS directory: {}", video_path.display());
let exif_dao: Arc<Mutex<Box<dyn ExifDao>>> = Arc::new(Mutex::new( let exif_dao: Arc<Mutex<Box<dyn ExifDao>>> = Arc::new(Mutex::new(Box::new(
Box::new(SqliteExifDao::new()) as Box<dyn ExifDao> SqliteExifDao::new(),
)); )
as Box<dyn ExifDao>));
loop { loop {
std::thread::sleep(Duration::from_secs(cleanup_interval_secs)); std::thread::sleep(Duration::from_secs(cleanup_interval_secs));
@@ -163,11 +164,7 @@ pub fn cleanup_orphaned_playlists(
for shard_entry in read_root.flatten() { for shard_entry in read_root.flatten() {
let shard_path = shard_entry.path(); let shard_path = shard_entry.path();
if !shard_entry if !shard_entry.file_type().map(|t| t.is_dir()).unwrap_or(false) {
.file_type()
.map(|t| t.is_dir())
.unwrap_or(false)
{
continue; continue;
} }
let shard_name = match shard_path.file_name().and_then(|n| n.to_str()) { let shard_name = match shard_path.file_name().and_then(|n| n.to_str()) {
@@ -194,16 +191,14 @@ pub fn cleanup_orphaned_playlists(
let mut shard_emptied = true; let mut shard_emptied = true;
for hash_entry in read_shard.flatten() { for hash_entry in read_shard.flatten() {
let hash_path = hash_entry.path(); let hash_path = hash_entry.path();
if !hash_entry if !hash_entry.file_type().map(|t| t.is_dir()).unwrap_or(false) {
.file_type()
.map(|t| t.is_dir())
.unwrap_or(false)
{
shard_emptied = false; shard_emptied = false;
continue; continue;
} }
let Some(hash_name) = let Some(hash_name) = hash_path
hash_path.file_name().and_then(|n| n.to_str()).map(|n| n.to_owned()) .file_name()
.and_then(|n| n.to_str())
.map(|n| n.to_owned())
else { else {
shard_emptied = false; shard_emptied = false;
continue; continue;
@@ -586,13 +581,9 @@ pub fn watch_files(
// quick scans because the cost is non-trivial on big // quick scans because the cost is non-trivial on big
// libraries and the data only meaningfully changes on // libraries and the data only meaningfully changes on
// full passes. // full passes.
let video_dir_str = let video_dir_str = dotenv::var("VIDEO_PATH").expect("VIDEO_PATH must be set");
dotenv::var("VIDEO_PATH").expect("VIDEO_PATH must be set"); let stats =
let stats = hls_stats::compute_and_publish( hls_stats::compute_and_publish(&libs, &exif_dao, Path::new(&video_dir_str));
&libs,
&exif_dao,
Path::new(&video_dir_str),
);
hls_stats::log_summary(&stats); hls_stats::log_summary(&stats);
last_full_scan = now; last_full_scan = now;