Skip to main content

Continuous recording review

FishTube represents continuous recording as a virtual timeline of small, independently verifiable cloud objects. The Edge device may keep its existing short local inference segments, while the cloud upload scheduler groups completed source segments into two-minute chunks. Each chunk records:

  • recordingSessionId: one uninterrupted camera recording session;
  • sequenceNumber: monotonic order inside that session;
  • discontinuitySequence: a counter that changes after a camera or recorder interruption;
  • sourceSegmentIds: the local source segments represented by the cloud object;
  • durationMs: the measured object duration.
  • recordingOrigin=continuous and segmentRole=review_archive: explicit classification that keeps the chunk separate from operator-uploaded manual originals.

Raw-video synchronization is opt-in on Edge. Deploying API or infrastructure changes does not enable the upload flag or increase vessel traffic by itself.

After S3 and FishTube acknowledge a scheduled chunk, Edge deletes the derived file only from the configured volume's archives directory. It retains the durable upload receipt for idempotency and keeps source captures under the normal retention policy. A source capture is not eligible for retention cleanup until its media upload and AI inference have completed, unless inference was explicitly disabled and marked skipped. A restart can safely resume this cleanup.

Video and AI results are intentionally uploaded separately. The video is useful immediately and must not be blocked by inference latency, a model failure, or an AI retry. Edge later uploads zero or more immutable events followed by one analysis-completion marker for the source segment and revision. FishTube joins those records to the already available recording.

Review a date range​

Call GET /observer/review-timeline with vesselId, cameraId, startAt, and endAt. A range must be positive and no longer than 30 days. The response contains ordered playable chunks, explicit gaps, canonical aiEvents, per-chunk AI coverage, a page analysis watermark, and an opaque nextCursor.

The Web application plays chunks sequentially and requests another cursor page when required. It also shows one absolute range overview with loaded media, known gaps, canonical AI events, and the current playhead. Selecting an unloaded point requests a bounded page beginning there, rather than downloading every signed object in a 30-day range. It does not concatenate one day—or thirty days—into a new S3 object. This avoids long-running media jobs, duplicate storage, and a delay before observers can begin work.

The two-minute boundary is a storage and retry boundary, not an observer workflow boundary. The primary player preloads the next chunk, carries the play/pause state and 1×, 2×, or 4× speed across the transition, and keeps the main progress control anchored to the selected Trip range. A missing interval or a recorder shutdown remains visible as a gap and playback advances to the next available chunk. Next AI event and Next unreviewed video continue across timeline cursor pages.

The review screen keeps pending recordings playable. Each loaded chunk reports pending, partial, or completed, together with completed and total source-segment counts. The range bar uses a distinct pending or partial treatment, and the status banner reports the current analysis lag. Observers can start manual marking before AI catches up; the event lane fills in as results are accepted.

A source capture can temporarily appear through an uploaded event clip. After its completed cloud chunk declares the source id, FishTube suppresses the covered source row and shows the evidence once on the chunk.

Manual originals remain available through their direct review-session identifiers, but the bounded continuous timeline excludes recordingOrigin=manual_upload. AI event clips and thumbnails are separate evidence media attached through source segment identifiers; they are not additional full recordings.

Observer marks still target one segmentId and timestampSeconds. FishTube also stores the derived absolute observedAt, so a mark remains stable on the source timeline even though playback uses a virtual playlist.

Complete human review​

An observer can either add or correct an event mark, or explicitly acknowledge a chunk as reviewed with no event. PUT /observer/review-sessions/:segmentId/review stores the latter decision without creating a synthetic catch event. The timeline exposes unreviewed, reviewed_no_event, and reviewed_with_events states.

The review workspace shows AI-analyzed, AI-pending, human-reviewed, and human-unreviewed coverage in minutes for the complete Trip range. POST /observer/trip-reviews/complete succeeds only after every continuous review archive in the selected range has a human mark or explicit review acknowledgement. This makes an all-clear Trip auditable without changing the event count.

Manual uploads are supplemental evidence. They remain directly reviewable but do not contribute to continuous-recording completeness or the default Trip report. Adding a manual original to a Trip requires a separate explicit inclusion workflow; filename or upload time never implies inclusion.

Events at a chunk boundary​

Every accepted AI evidence row remains immutable. Related boundary fragments share a canonicalEventId. The canonical row is active; duplicate evidence is superseded and points to the root through supersededBy.

The timeline and notifications expose one representative per canonical event. Analysis eventCount continues to verify the number of immutable rows produced by an Edge analysis revision; it is not an official catch count. Human review remains the boundary for official marks and reports.