Skip to content

Archive playback

The recorded archive is served over the same protocols as live: HLS and DASH from the station. There is no separate "archive" address — a recorded window is set by parameters on the ordinary address, while rewinding back has a path of its own.

Playback works for a stream with recording enabled. For a stream without recording the archive request is refused. Retention depth sets how far back playback goes: a request deeper than the start of the archive is served from the start of the archive, not as an empty answer.

Rewind

A playlist rewound N seconds back from now:

http://<station-address>/streaming/v/<stream>/rewind/<seconds>/index.m3u8

For example, rewind/3600/ is one hour back.

The playlist starts in the archive and continues with live: there are no duplicates and no skips at the seam, and the player does not notice the transition. Blocking reload of LL-HLS keeps working. Gaps in the recording are marked with the standard EXT-X-DISCONTINUITY.

The same exists for MPEG-TS HLS, under the ts/ segment:

http://<station-address>/streaming/v/<stream>/ts/rewind/<seconds>/index.m3u8

A window by absolute time

A recorded window is set by the from and to parameters — UTC in milliseconds:

http://<station-address>/streaming/v/<stream>/index.m3u8?from=<ms>&to=<ms>
http://<station-address>/streaming/v/<stream>/Manifest.mpd?from=<ms>&to=<ms>
  • Without from the address serves live; with from the archive begins, and the HLS playlist becomes closed — it describes exactly the recorded window and does not grow;
  • without to the right edge of the window is open forward.

In DASH, recording gaps become Periods, and the timeline is chosen with the timeline parameter:

  • compact — the default: periods follow one another without breaks, and the time in the manifest is continuous;
  • wallclock — gaps are preserved, and the position of the window in the manifest matches wall-clock time.

For example, a window on the wall-clock scale:

http://<station-address>/streaming/v/<stream>/Manifest.mpd?from=<ms>&to=<ms>&timeline=wallclock

Recorded windows

Which segments are recorded is served by a separate request. The archive edge and its lower boundary:

http://<station-address>/streaming/dvr-range/<stream>
{"from": 1789546139000, "to": 1789553339000}

Both values are UTC in milliseconds.

Recording windows, page by page:

http://<station-address>/streaming/dvr-ranges/<stream>?resolution=<ms>&limit=<count>&cursor=<cursor>
{
  "estimated_count": 2,
  "next": "MTc4OTU0NjEzOTAwMA",
  "ranges": [
    {"opened_at": 1789546139000, "closed_at": 1789549739000},
    {"opened_at": 1789550400000, "closed_at": 1789553339000}
  ]
}
  • opened_at and closed_at — the start and the end of one continuous recording window, UTC in milliseconds;
  • resolution — how precisely neighbouring windows are joined, in milliseconds. Zero means the precision of the recording itself;
  • limit — page size, 100 by default, 10000 at most;
  • cursor — the next value of the previous page. The cursor is opaque: its inner form is not part of the contract;
  • next is absent on the last page.

Windows can be filtered by time: opened_at_gte, opened_at_lte, closed_at_gte, all UTC in milliseconds. A value that looks like epoch seconds is refused with 422: multiplied by 1000 silently, it would return an empty answer for the year 1970 instead of an error.

Frame previews

  • A JPEG frame from the image track at a given moment:

text http://<station-address>/streaming/v/<stream>/image/<track>/<ms>.jpg

  • A short MP4 fragment from a keyframe:

text http://<station-address>/streaming/dvr-preview-mp4/<stream>/<ms>

Both addresses read the archive: the frame is assembled from the nearest fragment rather than served from a ready cache.

The player page

Checking the archive in a browser without building addresses by hand is what the player page is for:

http://<station-address>/streaming/embed/<stream>?dvr=true&from=<ms>&to=<ms>
  • dvr=true opens the archive timeline. Without the parameter the page shows live: for a stream without recording it falls back to the live player itself;
  • from and to set the timeline window, UTC in milliseconds.

These addresses check the signal, they do not deliver it to viewers: balancing, viewer authorisation and session accounting start where the headend ends. The player requirements are the same as for live.

What next