Skip to content

platform sdk cameras

Andre Lafleur edited this page Oct 8, 2026 · 18 revisions

About cameras

A Camera is the SDK's logical channel for video. It represents one feed produced by a piece of video hardware. Each camera is hosted on a parent VideoUnit (the device: IP camera, encoder, or video server) and is recorded by an ArchiverRole or AuxiliaryArchiverRole. Operators view the camera's live and playback streams in Security Desk; SDK applications configure the camera, manage its recording behavior, work with its archives, and observe its status.

A unit can host one or many cameras; a camera always has exactly one parent video unit. VideoUnit identification (Manufacturer, Model, SerialNumber, MacAddress, FirmwareVersion, HardwareVersion) is read-only. The writable members are the network and credentials side, plus TimeZone and GeographicalLocation.

Common tasks

  • Enrolling a video unit: add a new unit to a running archiver.
  • Read or update camera coordinates: see Geographical location.
  • Configure recording: see "Recording inheritance and scheduled modes" below.
  • Trigger a manual recording: see "Manual recording" below.
  • Protect a window of recorded video: see "Video protection" below.
  • Add a bookmark on a camera's timeline: see "Bookmarks" below.
  • Observe a unit going offline: see "Status and health" below.

Geographical location

Use Camera.GeographicalLocation to read the latitude and longitude values configured for a camera. The property returns a GeographicalLocation object whose Latitude and Longitude properties use double values.

GeographicalLocation location = camera.GeographicalLocation;
double latitude = location.Latitude;
double longitude = location.Longitude;

For a local camera, the logged-on user must have view access to the associated VideoUnit, which Camera.Unit identifies. Reading Camera.GeographicalLocation fails if the user cannot retrieve that video unit.

For a federated camera, the property returns coordinates synchronized from the remote Security Center system. The SDK application can read these coordinates even if it cannot retrieve the camera's video unit.

To update the coordinates of a local camera, assign a new GeographicalLocation object:

camera.GeographicalLocation = new GeographicalLocation(latitude: 45.5017, longitude: -73.5673);

The logged-on user must have write access to both the camera and its associated video unit. Federated cameras provide read-only access to Camera.GeographicalLocation.

Updating network settings atomically

For network changes, prefer VideoUnit.UpdateNetworkSettings(IPAddress, IPAddress, IPAddress) over setting properties one at a time. The single call validates the IP, subnet mask, and gateway together. Writing the address properties one at a time also validates, but each write is checked against the values still stored for the other two, so a valid target combination that changes more than one value can be rejected or only partially applied. IsNetworkSettingsCombinationValid(...) enables the integration to check before committing. An invalid combination is rejected rather than applied. A successful call also turns off DHCP and switches the unit to a static configuration, and requires the connected user to have write access to the unit.

Recording inheritance and scheduled modes

A camera records while an active schedule selects a recording mode other than Off. The mode and schedule are defined by Camera.RecordingConfiguration (an ICameraRecordingConfiguration). UseCustomRecordingSettings controls inheritance: when false, the camera inherits the configuration from its parent ArchiverRole; when true, the camera's local configuration is used. This is how installations carry archiver-wide defaults onto most cameras and override on a few.

A ScheduledRecordingMode pairs a Schedule with a RecordingMode (Off, Continuous, OnMotionOrManual, Manual). Build one through the static factory ScheduledRecordingMode.CreateFrom(Schedule, RecordingMode). Static singletons ContinuousRecording, ManualRecording, OffRecording, and OnMotionOrManualRecording are exposed as the always-schedule shortcut.

ICameraRecordingConfiguration recording = camera.RecordingConfiguration;

ScheduledRecordingMode mode = ScheduledRecordingMode.CreateFrom(
    schedule,
    RecordingMode.Continuous);

recording.SetScheduledRecordingModes(mode);

SetScheduledRecordingModes replaces the entire list. AddScheduledRecordingModes appends. RemoveScheduledRecordingModes drops entries.

Manual recording

Camera.StartRecording(TimeSpan recordingLength, bool locked) triggers a manual recording. The lock flag keeps the recording active for the full duration even if the trigger condition stops. Camera.StopRecording() ends it.

camera.StartRecording(
    recordingLength: TimeSpan.FromMinutes(2),
    locked: true);

camera.StopRecording();

A three-argument StartRecording(TimeSpan, bool, Guid) overload directs the recording at a specific archiver when the camera has multiple archiver targets; StopRecording(Guid targetedRole) is the matching stop.

When the integration only holds a Guid (no Camera instance), Engine.ActionManager.StartRecording(Guid camera, TimeSpan recordingLength, bool locked) and StopRecording(Guid camera) give the same result through the action manager.

Stream usage and per-stream configuration

A camera typically exposes multiple VideoStream entities. Each stream can be assigned a usage (Live, Remote, HighQuality, LowQuality, or Archiving), and applications retrieve a stream by that usage instead of guessing. Camera.SetStreamUsage(StreamingType streamType, Guid videoStreamId) assigns the selected usage to the video stream identified by videoStreamId. Enumerate the camera's streams with Camera.Streams, a read-only collection of stream Guids, and read their current assignments with Camera.StreamUsages, where each entry exposes its Usage and Stream. Pass the chosen stream's Guid as the second argument to SetStreamUsage.

foreach (VideoStreamUsage usage in camera.StreamUsages)
{
    VideoStream stream = engine.GetEntity<VideoStream>(usage.Stream);
    Console.WriteLine($"{usage.Usage}: {stream.Name}");
}

camera.SetStreamUsage(StreamingType.HighQuality, hqStreamGuid);

Per-stream setters (SetBitRate, SetMaximumAllowedBitRate, SetFrameRate, SetResolution, SetKeyFrameInterval, and so on) all take the schedule the change applies to as the first argument, so a camera carries different stream settings on different schedules.

Discover valid inputs first. VideoStream.VideoCompressionCapabilities reports the supported bit-rate range, frame-rate range, and supported resolutions for the device. Pick a StreamSupportedResolution from VideoCompressionCapabilities.SupportedResolutions rather than constructing one. StreamConnectionType is a [Flags] enum; SupportedConnectionTypes is a bitmask of every value the device supports.

foreach (Guid streamGuid in camera.Streams)
{
    VideoStream stream = engine.GetEntity<VideoStream>(streamGuid);

    // Cap the always-on schedule at 4 Mbps.
    stream.SetMaximumAllowedBitRate(alwaysOnSchedule, 4_000_000);
}

Bookmarks

A bookmark is a moment on a camera's timeline tagged for later reference. The SDK exposes bookmarks through three APIs:

  • Events raised on the camera: CameraBookmarkEvent, CameraLiveBookmarkAddedEvent, CameraPlaybackBookmarkAddedEvent.
  • Queries through the report manager: BookmarkEventQuery retrieves bookmarks by camera and time range.
  • Actions for event-to-action wiring: AddBookmarkAction, EditBookmarkAction, DeleteBookmarkAction.

For direct add, edit, and delete on the connected user's session, Engine.ActionManager exposes AddCameraBookmark(Guid, DateTime, string), EditCameraBookmark(Guid, DateTime, string), and DeleteCameraBookmark(Guid, DateTime).

engine.ActionManager.AddCameraBookmark(
    cameraGuid,
    DateTime.UtcNow,
    "Suspect entered the lobby");

For the BookmarkEventQuery filter properties, see Platform SDK report manager query reference.

Video protection

Video protection prevents a window of recorded video from being deleted by automatic cleanup. Use it to preserve evidence beyond the configured retention period. AddVideoProtection requires a duration longer than one day; StartVideoProtection requires at least one day. A shorter duration is rejected and no protection is applied. To protect a window indefinitely with AddVideoProtection, pass TimeSpan.MaxValue as the duration.

For a known past window:

DateTime start = new DateTime(2025, 1, 15, 9, 0, 0, DateTimeKind.Utc);
DateTime end = new DateTime(2025, 1, 15, 10, 0, 0, DateTimeKind.Utc);

camera.AddVideoProtection(start, end, duration: TimeSpan.FromDays(30));

For video archived after the call:

  • Camera.StartVideoProtection(TimeSpan span, TimeSpan duration) protects video archived during the next span for the protection duration. Protection starts immediately. The method does not start recording, so it protects only video recorded during that period.
  • Camera.StopVideoProtection(TimeSpan delay) stops applying protection after the delay. Use TimeSpan.Zero to stop immediately. It does not remove protection from archived video.

To protect or remove protection from an already archived time range, use AddVideoProtection or RemoveVideoProtection. By default, calling RemoveVideoProtection leaves video protected for another 24 hours. Video with less than 24 hours of protection remaining keeps its original expiration time.

For protecting a window across multiple cameras at once, Engine.ActionManager.AddVideoProtection(IEnumerable<Guid>, DateTime, DateTime, TimeSpan) and the matching RemoveVideoProtection overload operate on a list of cameras.

Status and health

Both Camera and VideoUnit inherit IsOnline and RunningState from Entity. Both raise IsOnlineChanged when their connectivity transitions; the event arg carries no payload, so read unit.IsOnline (or camera.IsOnline) directly inside the handler:

unit.IsOnlineChanged += (sender, e) =>
{
    Console.WriteLine($"Unit online state changed: {unit.IsOnline}");
};

Camera.SupportsLiveStreaming is a capability of the camera. It does not indicate whether the unit is online or the stream is currently configured. Check camera.IsOnline and the camera's stream configuration separately before requesting live video. For camera health from the archiver's side, such as recording problems or disk and encoder load, use ArchiverRole.ArchiverStatisticsCollection. Each encoder's ArchiverEncoderStatistics.Description contains a RecordingProblem value before an archive query shows the same issue. See Archiver and auxiliary archiver roles for the available statistics members.

For unit-level recovery, Engine.ActionManager.ReconnectVideoUnit(Guid) and RebootVideoUnit(Guid) are the operator-side actions.

Engine.ActionManager.ChangeUnitPassword(Guid unit, SecureString newPassword) changes the unit's password to a value you supply. ChangeUnitPassword(Guid unit) and ChangeUnitPasswordBatch(IEnumerable<Guid> units) request auto-generated password changes. Pass a video unit or access control unit GUID, not a camera GUID.

The overload that accepts a SecureString validates the target and reports failures by throwing SdkException. The auto-generated password overloads submit changes only for video units and access control units that the logged-on user has permission to update. They ignore other nonempty GUIDs and return without sending an action when no supported unit remains. These overloads do not report the eventual per-unit result synchronously. Password changes require the UpdatePasswordVideoUnits or UpdatePasswordAccessControlUnits privilege and the Unit Assistant role.

using System.Net;

engine.ActionManager.ChangeUnitPassword(
    videoUnitGuid,
    new NetworkCredential("", "NewUnitPassword1!").SecurePassword);

See also

Platform SDK

Plugin SDK

Workspace SDK

Media SDK

Macro SDK

Web SDK

Synergis RIO

Media Gateway

Genetec Web Player

Clone this wiki locally