Skip to content

LiveKit recorder: Start..Stop is shorter than the file when the recorder moves the media start #2

Open

Description

@prlanzarin

With the media timestamps from bbb-webrtc-recorder (bigbluebutton/bbb-webrtc-recorder#51), the LiveKit recorder manager writes a recording's Start from recordingMediaStarted and its Stop from mediaEnd in recordingStopped. When the recorder moves the media start back after it reported it, the written Start..Stop is shorter than the file, and record-and-playback cuts the file's tail by that move.

What happens

The recorder reports a file's media start once it settles, or once it is 4.5 s old. A few cases can still move the start back after that, by at most 1 s. The recorder lists them in livekit.go:80-88: a frame whose first packet is over 500 ms late, the builtin VP8 samplebuilder, an Opus frame held behind a loss, and a frame the jitter buffer's timer releases.

recordingStopped then carries the moved start, and its mediaEnd counts from it (README.md:234-236).

Say the start was reported at S and moved back by d, and the file holds D of media. The SFU has already written the Start at S, and it writes the Stop at (S - d) + D. The event span is D - d. Record-and-playback places the file's first frame at the Start, so the last d of the file falls after the Stop.

Possible fix

Keep the recorder's mediaStartUTC behind the Start that was written. At the stop, push the recorder's end forward by how far the start moved, before mapping it into the event clocks:

const startMove = Number.isFinite(recordingInfo.mediaStartUTC)
  && Number.isFinite(mediaTimes.mediaStartUTC)
  ? Math.max(0, recordingInfo.mediaStartUTC - mediaTimes.mediaStartUTC)
  : 0;
const stopTimestamps = mapRecorderTimestamps({
  utc: mediaTimes.mediaEndUTC + startMove,
  hr: mediaTimes.mediaEndHR + startMove,
}) || sfuTimestamps();

mediaStartUTC is set wherever the Start is written from the recorder's times. For a recording found by getRecordings after an SFU restart, it is the reported start that getRecordings returns. A start that did not move gives a move of 0, so the Stop stays mediaEnd.

Tests: a recorder that reports S, then stops with mediaStart = S - 600 ms and mediaEnd = S - 600 ms + D, gets its Stop at S + D. The same check applies to a resynced recording.

The recorder could instead stop moving the start once it reported it, or count mediaEnd from the reported start. That needs a recorder release, and the SFU would still have to handle recorders that move it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions