Repository navigation
platform sdk 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.
- 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.
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.
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.
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.
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.
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);
}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:
BookmarkEventQueryretrieves 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 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 nextspanfor 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. UseTimeSpan.Zeroto 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.
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);- About video: The video hub.
- Enrolling a video unit: Standalone procedure.
- Archiver and auxiliary archiver roles: Archiver-side recording defaults, statistics, and certificates.
- Archive transfer: Backup, retrieval, restore, and trickling.
- PTZ coordinates manager: PTZ control through the Media SDK.
- Play video with Media SDK: Live and playback rendering.
- Export archived media: G64/G64x export.
- Camera blocking: Operator privacy controls.
- Overview
- Connecting to Security Center
- SDK certificates
- Referencing SDK assemblies
- ASP.NET hosting
- SDK compatibility
- Migrating to modern .NET
- Entities
- Entity cache
- Entity loading, cache, and query options
- Detecting entity changes
- Entity change event reference
- Transactions
- Security Center events
- Actions
- Security Desk
- Custom events
- Event-to-actions
- Managing macros
- ReportManager
- ReportManager query reference
- Access control raw events
- DownloadAllRelatedData and StrictResults
- Privileges
- Partitions
- Entity write restrictions
- About custom fields
- About video
- About cameras
- Enrolling a video unit
- Ingesting third-party video
- Archiver and auxiliary archiver roles
- Archive transfer
- About access control
- About cardholders and credentials
- About doors, areas, elevators, and access points
- About access rules and schedules
- About access control units and interface modules
- Enrolling an access control unit
- Door templates
- Visitors
- Mobile credentials
- About threat levels
- About alarms
- About incidents
- Maps
- Logging
- Overview
- Localization
- Certificates
- Lifecycle
- Threading
- State management
- Configuration
- Restricted configuration
- Events
- Queries
- Request manager
- Database
- Entity ownership
- Engine extensions
- Entity mappings
- Server management
- Custom privileges
- Custom entity types
- Resolving non-SDK assemblies
- Deploying plugins
- Modern .NET support
- Overview
- Localization
- Certificates
- Creating modules
- Tasks
- Pages
- Components
- Tile extensions
- Services
- Contextual actions
- Custom actions
- Options extensions
- Configuration pages
- Monitors
- Shared components
- Commands
- Extending events
- Map extensions
- Timeline providers
- Image extractors
- Credential encoders
- Credential readers
- Cardholder fields extractors
- Badge printers
- Content builders
- Dashboard widgets
- Incidents
- Logon providers
- Pinnable content builders
- Custom report pages
- Overview
- Getting started
- Media file formats
- MediaPlayer
- VideoSourceFilter
- MediaExporter
- MediaFile
- G64 converters
- FileCryptingManager
- PlaybackSequenceQuerier
- PlaybackStreamReader
- OverlayFactory
- PtzCoordinatesManager
- AudioTransmitter
- AudioRecorder
- AnalogMonitorController
- Camera blocking
- Overview
- Getting started
- Referencing entities
- Entity operations
- About access control in the Web SDK
- About video in the Web SDK
- Users and user groups
- Partitions
- Custom fields
- Custom card formats
- Actions
- Events and alarms
- Incidents
- Reports
- Tasks
- Macros
- Custom entity types
- System endpoints
- Performance guide
- Reference
- Endpoints
- Constants
- Enumerations
- Under the hood
- Troubleshooting