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/GetRecordingSearchResultswith known time ranges and metadata without waiting for real recordings to accumulate. - Replay Testing: Verify
GetReplayUrireturns 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
<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):
<?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:
<!-- 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:
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
- Save the
onvif.cfgfile. - Place the media files referenced by
<media_source>in the server's working directory (e.g.,test.mp4). - Launch the ONVIF Server executable. It will parse the configuration and populate the RecordingList.
- Check the logs for successful recording configuration loading. Look for entries indicating the recordings and their tracks were registered.
- Test with an ONVIF client:
- Call
GetRecordings— verify that each configured<recording>appears with its auto-generated token, name, and description. - Call
FindRecordings/GetRecordingSearchResultswith a time range that overlaps the configured<start_time>to<end_time>— the recording should be returned. - Call
GetReplayUri— verify the returned URI contains the correctearliest,latest, andfile=parameters.
- Call
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 trailingZ. 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.