Skip to content

fix: don't skip cross-monitor events in gapless playback when sorting by another field - #5312

Merged
connortechnology merged 1 commit into
ZoneMinder:masterfrom
connortechnology:fix-gapless-cross-monitor-skip
Oct 20, 2026
Merged

connortechnology merged 1 commit into
ZoneMinder:masterfrom
connortechnology:fix-gapless-cross-monitor-skip

Conversation

@connortechnology

Copy link
Copy Markdown
Member

Symptom

With Replay set to "Gapless events", playback skips over events recorded by monitors other than the first event's monitor. Reported on 1.38.7 against a database migrated from a multi-monitor production system; a fresh single-monitor test database did not show it.

Cause

getNearEvents() already selects the prev/next event with the full (sort value, Id) tuple, which orders events strictly in the chosen sort. It then also added AND E.StartDateTime >= / <= the current event's time. That extra predicate is only consistent when the sort field is StartDateTime. When the list is sorted by another field — MonitorName (grouping cameras) or Id — it drops events that are correctly next in that order but started earlier or later than the current one:

  • MonitorName sort: the next monitor's first event usually started before the current monitor's last event, so StartDateTime >= excludes it — the whole next monitor is skipped.
  • Id sort: a concurrently recorded event from another monitor can have a higher Id but an earlier StartDateTime, so it's skipped.

A fresh, single-timeline DB rarely exposes this because Id order tracks time order; a DB with several monitors recording in parallel (or one migrated from another system) makes the two diverge.

Fix

Drop the StartDateTime constraint and let the (sort value, Id) tuple be the whole ordering. It can't reintroduce the earlier playback loop (#4186 follow-up) because (sort value, Id) is a strict total order.

Verified php -l clean. The near-event query path is shared by Prev/Next and gapless playback for both video.js and zms events.

🤖 Generated with Claude Code

…y another field

getNearEvents() built the prev/next query from the full (sort value, Id) tuple,
which already orders events strictly in the chosen sort, but then also added
AND E.StartDateTime >= / <= the current event's time. That extra predicate is
only consistent when the sort field is StartDateTime. When events are sorted by
another field -- MonitorName to group cameras, or Id -- it dropped events that
are correctly next in that order but started earlier or later than the current
one: the next monitor's first event (which often started before the current
monitor's last), or a concurrently recorded event with a higher Id. Gapless
playback then skipped over the events of every monitor but the first.

A fresh, single-timeline database rarely shows this because Id order tracks
time order; a database with several monitors recording in parallel, or one
migrated from another system, makes the two diverge and exposes it.

Drop the StartDateTime constraint and let the tuple be the whole ordering. It
cannot reintroduce the earlier playback loop because (sort value, Id) is a
strict total order. refs ZoneMinder#4186

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@connortechnology
connortechnology merged commit 59c6fe3 into ZoneMinder:master Oct 20, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant