How to Configure Recordings in the ONVIF Server Configuration File

A practical guide to populating the ONVIF Server's RecordingList using the <recording> element in onvif.cfg. Define custom recordings with tracks, time ranges, and media sources — enabling NVR compatibility testing, recording search validation, and replay without physical recording hardware.

Why Configure Recordings?

In a real deployment, a recording device accumulates hours or days of video before it becomes useful for testing search and replay. The ONVIF Server lets you pre-populate the RecordingList from the configuration file, so recordings appear as if they were captured at specific past times — immediately enabling:

  • NVR Compatibility Testing: Validate that your NVR or VMS correctly enumerates recordings, searches by time range, and replays historical video.
  • Recording Search Validation: Test FindRecordings / GetRecordingSearchResults with known time ranges and metadata without waiting for real recordings to accumulate.
  • Replay Testing: Verify GetReplayUri returns a correct replay URL pointing to the associated media file.
  • Repeatable Regression Testing: Use the same recording definitions across test runs to ensure consistent validation of your client software.

The <recording> element defines a custom media recording entry that populates a RecordingList node in the server's configuration. Each node creates a new recording with an auto-generated token, specifying metadata, tracks, time range, and the associated media file.

The <recording> Element

The <recording> element is placed inside the <config> element in onvif.cfg. Multiple <recording> nodes may be configured, each producing a separate recording in the RecordingList.

Syntax

onvif.cfg — Recording Element
<recording>
    <name>Front Entrance Camera</name>
    <description>Continuous recording from front entrance IP camera</description>
    <track>
        <type>Video</type>
        <description>Main video track</description>
    </track>
    <track>
        <type>Audio</type>
        <description>Audio track</description>
    </track>
    <start_time>2026-07-09T08:00:00Z</start_time>
    <end_time>2026-07-09T10:00:00Z</end_time>
    <media_source>test.mp4</media_source>
</recording>

Sub-Element Reference

Element Required Description
<name> Optional Human-readable recording name. Mapped to Recording.Configuration.Source.Name.
<description> Optional Descriptive text for the recording. Mapped to Recording.Configuration.Source.Description.
<track> Optional (0..N) A track within the recording. Each <track> creates a TrackList node appended to Recording.Tracks.
<track>/<type> Required for each track Track type string: "Video", "Audio", or "Metadata".
<track>/<description> Optional Description of this specific track. Stored in Track.Configuration.Description.
<start_time> Optional Earliest recording time as ISO 8601 UTC datetime (e.g., 2026-07-09T08:00:00Z). Parsed into RecordingList.EarliestRecording.
<end_time> Optional Latest recording time as ISO 8601 UTC datetime. Parsed into RecordingList.LatestRecording.
<media_source> Optional The media file path or filename (e.g., test.mp4). Appended as a file=xxx parameter to the replay URI returned by GetReplayUri. Stored in RecordingList.media_source.

Step 1: Add a Recording to the Configuration

Open onvif.cfg in a text editor and add one or more <recording> elements inside the <config> element. Below is a complete onvif.cfg with a recording that has three tracks (Video, Audio, and Metadata):

onvif.cfg — Recording Configuration
<?xml version="1.0" encoding="utf-8"?>
<config>
    <server_ip></server_ip>
    <http_enable>1</http_enable>
    <http_port>8000</http_port>
    <https_enable>1</https_enable>
    <https_port>8443</https_port>
    <need_auth>1</need_auth>
    <log_enable>1</log_enable>
    <log_level>1</log_level>
    <log_mode>loop</log_mode>

    <user>
        <username>admin</username>
        <password>admin</password>
        <userlevel>Administrator</userlevel>
    </user>

    <!-- Recording entry -->
    <recording>
        <name>recording1</name>
        <description>Recording from profile</description>
        <track>
            <type>Video</type>
            <description>Video track</description>
        </track>
        <track>
            <type>Audio</type>
            <description>Audio track</description>
        </track>
        <track>
            <type>Metadata</type>
            <description>Metadata track</description>
        </track>
        <start_time>2026-07-09T08:00:00Z</start_time>
        <end_time>2026-07-09T10:00:00Z</end_time>
        <media_source>test.mp4</media_source>
    </recording>

    <scope>onvif://www.onvif.org/name/IP-Camera</scope>
    <event>
        <renew_interval>60</renew_interval>
    </event>
</config>

Step 2: Configure Multiple Recordings

To simulate a multi-channel NVR, configure multiple <recording> nodes. Each recording gets an auto-generated token and is exposed independently to ONVIF clients. You can give each recording a distinct name, track layout, time range, and media file:

onvif.cfg — Multiple Recordings
<!-- Recording 1: Front Entrance (2 hours, video+audio) -->
<recording>
    <name>Front Entrance</name>
    <description>Continuous recording, front entrance camera</description>
    <track>
        <type>Video</type>
    </track>
    <track>
        <type>Audio</type>
    </track>
    <start_time>2026-07-09T08:00:00Z</start_time>
    <end_time>2026-07-09T10:00:00Z</end_time>
    <media_source>front-entrance.mp4</media_source>
</recording>

<!-- Recording 2: Parking Lot (short event-triggered clip) -->
<recording>
    <name>Parking Lot</name>
    <description>Motion-triggered clip, parking lot camera</description>
    <track>
        <type>Video</type>
    </track>
    <start_time>2026-07-09T14:23:45Z</start_time>
    <end_time>2026-07-09T14:24:55Z</end_time>
    <media_source>parking-motion.mp4</media_source>
</recording>

<!-- Recording 3: Server Room (video + metadata track) -->
<recording>
    <name>Server Room</name>
    <description>Continuous recording with analytics metadata</description>
    <track>
        <type>Video</type>
    </track>
    <track>
        <type>Metadata</type>
        <description>Analytics metadata track</description>
    </track>
    <start_time>2026-07-09T00:00:00Z</start_time>
    <end_time>2026-07-10T00:00:00Z</end_time>
    <media_source>server-room.mp4</media_source>
</recording>

Step 3: Understand the Replay URI

When <media_source> is specified and the recording is requested via GetReplayUri, the resulting URL will include a file= query parameter pointing to the associated media file:

Example Replay URI
rtsp://192.168.1.100:554/replay?earliest=1752055200&latest=1752062400&file=test.mp4&t=unicast&p=udp

Replay URI parameters:

Parameter Description
earliest Unix timestamp (seconds) of the earliest recording time, derived from <start_time>.
latest Unix timestamp (seconds) of the latest recording time, derived from <end_time>.
file The media file path or filename from <media_source>. When present, the replay server plays this file instead of a live source.
t Transport type. unicast indicates a point-to-point replay stream.
p Transport protocol. udp for UDP transport (may also appear as tcp).

Step 4: Launch and Verify

  1. Save the onvif.cfg file.
  2. Place the media files referenced by <media_source> in the server's working directory (e.g., test.mp4).
  3. Launch the ONVIF Server executable. It will parse the configuration and populate the RecordingList.
  4. Check the logs for successful recording configuration loading. Look for entries indicating the recordings and their tracks were registered.
  5. Test with an ONVIF client:
    1. Call GetRecordings — verify that each configured <recording> appears with its auto-generated token, name, and description.
    2. Call FindRecordings / GetRecordingSearchResults with a time range that overlaps the configured <start_time> to <end_time> — the recording should be returned.
    3. Call GetReplayUri — verify the returned URI contains the correct earliest, latest, and file= parameters.

Troubleshooting

Issue Possible Cause Resolution
GetRecordings returns no recordings No <recording> element in the config, or the config failed to parse. Verify the <recording> element is inside <config>. Check the server log for XML parse errors. Confirm the Profile G build is used (recording services require Profile G).
Recording search returns zero results Search time range does not overlap the configured <start_time>/<end_time>, or timestamps are in the wrong timezone. Verify the search window overlaps the recording's time range. Ensure timestamps are in UTC (ISO 8601 with a trailing Z). Note: FindRecordings uses UTC regardless of the client's local timezone.
Replay URI missing the file= parameter <media_source> is empty or missing. Add a <media_source> element with the media file path or filename. Ensure the file exists in the server's working directory.
Replay stream fails to play The media file cannot be decoded, or the codec/resolution does not match the client's expectations. Verify the media file is a valid, playable video (test with VLC or ffplay). Check that the file's codec is supported (H.264/H.265/MPEG-4 video, G.711/AAC audio).
Recording timestamps appear wrong Timestamps were provided in local time instead of UTC. ONVIF recording timestamps are always UTC. Append Z to the datetime and convert local time to UTC before configuring <start_time> and <end_time>.

Best Practices

  • Use the Profile G Build: Recording configuration, search, and replay services are only exposed by the Profile G compatible version of the ONVIF Server. Verify you are using the correct build before configuring recordings.
  • Use UTC Timestamps Consistently: Always express <start_time> and <end_time> in UTC with a trailing Z. This avoids timezone mismatch between the server, the client, and recording search queries.
  • Place Media Files in the Working Directory: Reference media files by filename and keep them in the server's working directory, or use paths relative to it. This prevents replay failures caused by unresolvable file paths.
  • Test Edge-Case Time Ranges: Configure recordings that span midnight, DST transitions, and month boundaries. These edge cases are where NVR recording search logic most frequently fails.
  • Match Media Codec to the Profile: Ensure the media file's codec and resolution match what the ONVIF client expects. Use H.264 video and G.711/AAC audio for maximum compatibility.
  • Start with One Recording: Begin with a single <recording> and verify enumeration, search, and replay end-to-end before adding many recordings for large-scale testing.