From 47d3af70c73f5570f6769d17a2073f657da07ffc Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 15 May 2026 23:54:32 -0400 Subject: [PATCH] fix: keep DefaultVideo='index.m3u8' for events with an HLS manifest refs #4757 Event::~Event() rewrote DefaultVideo to the renamed mp4 filename on every close, which made event.php's HLS detection (str_ends_with DefaultVideo, '.m3u8') return false for every closed event. The HLS player only kicked in for in-progress events or when MP4HLS was manually picked from the codec dropdown. Detect index.m3u8 in the same dirent walk that already computes video_size, and write 'index.m3u8' to DefaultVideo when it's present. mp4-only events keep using the renamed mp4 as before. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/zm_event.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 4bb68eb78..cc50f1b35 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -258,18 +258,27 @@ Event::~Event() { if (frame_data.size()) WriteDbFrames(); uint64_t video_size = 0; + bool has_m3u8 = false; DIR *video_dir; if ((video_dir = opendir(path.c_str())) != NULL) { struct dirent *dir_entry; while ((dir_entry = readdir(video_dir)) != NULL) { struct stat vf_stat; if (stat((path + "/" + dir_entry->d_name).c_str(), &vf_stat) == 0 && - S_ISREG(vf_stat.st_mode)) + S_ISREG(vf_stat.st_mode)) { video_size += vf_stat.st_size; + if (!strcmp(dir_entry->d_name, "index.m3u8")) has_m3u8 = true; + } } closedir(video_dir); } + // Prefer index.m3u8 as DefaultVideo when an HLS manifest was written, so + // event.php picks the HLS player on closed events too — otherwise the player + // selection logic falls back to direct mp4 playback for everything except a + // manual MP4HLS codec choice. + std::string default_video = has_m3u8 ? "index.m3u8" : video_file; + // Use async dbQueue instead of synchronous zmDbDoUpdate to avoid blocking // the close_event_thread (which blocks the analysis thread on the next closeEvent). // Conditionally update Name only if it hasn't been changed by the user during recording. @@ -286,7 +295,7 @@ Event::~Event() { frames, alarm_frames, tot_score, static_cast(alarm_frames ? (tot_score / alarm_frames) : 0), max_score, max_score_frame_id, - video_file.c_str(), // defaults to "" + default_video.c_str(), video_size, id); dbQueue.push(std::move(sql));