Repository navigation
media sdk overlay factory
OverlayFactory is the entry point for Media SDK overlays. Use it to initialize overlay support, get or create an Overlay stream for a camera, and remove an overlay stream when an integration needs to retire it.
You do not construct Overlay or Layer directly. OverlayFactory.Get returns an Overlay for a camera, and Overlay.CreateLayer returns a Layer inside that overlay. The Layer is where you draw text, lines, rectangles, ellipses, and images.
An overlay belongs to one camera and one overlay stream name. The stream name is the application-owned name that appears in the camera metadata stream list.
OverlayFactory.Get(camera, name) returns the same Overlay instance for the same camera-and-name pair within the process. Use a stable name per overlay purpose, such as AnalyticsOverlay or OperatorAnnotations, and reuse it across application runs.
An overlay contains one or more layers. Each layer has a LayerIdentifier GUID. The player uses this GUID to update that layer over time, so use a stable GUID for each drawing concept, such as object boxes, alarm regions, status text, or a logo. Layers cannot be listed later through the overlay API, so the application must own and preserve its layer ID scheme.
For dynamic content, use a bounded pool of deterministic layer IDs. For example, if an analytics integration tracks up to 50 objects, use a predictable set of 50 layer IDs, clear those IDs when the application starts, and reuse them while objects appear and disappear.
using Genetec.Sdk.Media.Overlay;
OverlayFactory.Initialize(engine);
Overlay overlay = OverlayFactory.Get(cameraGuid, "AnalyticsOverlay");The Engine must be connected to the Directory, and the Security Center license must include the Media SDK option. Calling Get before Initialize throws InvalidOperationException.
| Member | Description |
|---|---|
OverlayFactory.Initialize(IEngine engine) |
Initialize overlay support. Call once during application startup. |
OverlayFactory.Get(Guid cameraGuid, string overlayName) |
Get or create an Overlay for the camera and name. Overloads also accept a Camera, a list of camera GUIDs, or an integer logical ID. |
OverlayFactory.Remove(Guid cameraGuid, string overlayName, bool deleteFiles) |
Remove the overlay stream. Pass true to delete associated recorded overlay files. Pass false to remove the live stream registration while keeping archived overlay data available for playback. Use this for cleanup or upgrade workflows, not to clear routine drawings. |
Use Camera.IsOverlaySupported before creating overlays when your application selects cameras dynamically. Ghost and federated cameras do not support creating overlay streams.
After getting the overlay, initialize its drawing surface, and then create layers.
overlay.StateChange += OnOverlayStateChanged;
overlay.Initialize(
drawingSurfaceHeight: 1080,
drawingSurfaceWidth: 1920);
Layer layer = overlay.CreateLayer(
Guid.Parse("525dbe6e-5579-4b36-ac88-761a646a5410"),
"Vehicle count");| Member | Description |
|---|---|
Initialize(double drawingSurfaceHeight, double drawingSurfaceWidth) |
Set the logical drawing surface dimensions. Call before creating layers. The dimensions must be numbers greater than zero. |
DrawingSurfaceHeight, DrawingSurfaceWidth
|
The initialized surface size. These values are 0 until Initialize succeeds. |
CreateLayer(Guid layerIdentifier, string displayName) |
Create a layer with a stable GUID and display name. The overlay must be initialized first. |
IsReadyForUpdate |
true when the overlay recorder is started and can propagate layer updates. |
StateChange |
Raised when overlay update readiness changes. Use OverlayStatusEventArgs.CanPropagateUpdate to check the new state. |
Dispose() |
Release the overlay object and recorder resources. This does not remove the overlay stream and does not dispose layers created from the overlay. |
Call Initialize once per overlay. Calling it again with different dimensions is not supported. If the camera resolution or the application coordinate system changes, create a new overlay and layer setup rather than resizing the existing overlay.
The drawing surface is a logical canvas. Coordinates start at the top-left corner of that canvas:
-
x = 0,y = 0is the top-left corner. -
xincreases to the right. -
yincreases downward. - Drawing outside
0..DrawingSurfaceWidthand0..DrawingSurfaceHeightis clipped.
Use a drawing surface that matches the coordinate system you use to calculate overlay positions. For a typical video overlay, initialize the surface to the video frame size that your application targets, such as 1080, 1920 for 1920 by 1080 video.
Image positions are used as supplied. DrawImage takes an image and the destination rectangle on the overlay canvas; the destination rectangle is not independently scaled. If you initialize the overlay to a surface that does not match the video coordinate system, image overlays can appear at unexpected positions or sizes.
A Layer carries drawing commands. Drawing calls buffer content on the layer until an Update overload publishes the layer.
layer.Duration = TimeSpan.FromSeconds(5);
layer.DepthIndex = 10;
layer.DrawText(
"Vehicle detected",
"Calibri",
emSize: 32,
color: "#FFFF0000",
x: 50,
y: 50);
bool updated = layer.Update();| Member | Description |
|---|---|
LayerIdentifier |
The stable GUID that identifies this layer in the overlay stream. Reuse the same GUID to update or clear the same logical layer. |
DisplayName |
The layer display name supplied to CreateLayer. It is descriptive metadata, not the layer identity. |
IsReady |
true after the layer drawing surface and drawing context are ready. |
IsRecorderInitialized |
true when the layer has an initialized recorder. Returns false after the layer is disposed. |
Duration |
How long the published layer remains active. Milliseconds are ignored. A duration of TimeSpan.Zero is treated as 24 hours, not as infinite. For long-lived layers, refresh the duration before it elapses; use Clear() followed by Update() when the application must remove the layer at a precise time. |
DepthIndex |
Visual stacking value used by MediaPlayer. When layers overlap, higher values render in front of lower values. Use distinct values when order matters. |
IsDisplayedByDefault |
true by default. When set to false, the layer is not rendered by default by the player. |
DrawText(...) |
Draw text at a point. |
DrawLine(...) |
Draw a line between two points. |
DrawRectangle(...) |
Draw a rectangle with fill and outline values. |
DrawEllipse(...) |
Draw an ellipse with fill and outline values. |
DrawImage(...) |
Draw a BitmapImage at a destination rectangle. |
Clear() |
Clear the buffered drawing content. Call Update() after Clear() to publish the cleared layer. |
Dispose() |
Release layer resources. Disposing the parent overlay does not dispose the layer. |
When you pass WPF Brush or Pen objects to drawing methods, freeze them before calling the method. The string color overloads create their own brushes and pens.
String color overloads accept 8-digit hexadecimal ARGB color values in the form #AARRGGBB. This form is recommended because it includes the alpha value. Standard WPF color names, such as Red, are also accepted.
layer.DrawRectangle(
fillColor: "#80FF0000",
outlineColor: "#FFFF0000",
x: 100,
y: 100,
width: 300,
height: 120);In #AARRGGBB, AA is alpha, RR is red, GG is green, and BB is blue. For example, #FFFF0000 is opaque red, and #80FF0000 is semi-transparent red.
Empty or invalid color strings fail before the drawing command is queued. The failed draw call does not add content to the layer.
DrawImage accepts a non-null WPF BitmapImage and a destination rectangle:
layer.DrawImage(
bitmapImage,
xCoordinate: 40,
yCoordinate: 40,
width: 160,
height: 90);The image data is included in the layer update. The viewer does not load the original image file path. If the same BitmapImage instance is drawn more than once before an update, the update can reference that image at multiple locations.
No numeric maximum image width, height, or byte size is defined for DrawImage. Large images increase the overlay update payload and must be decoded and rendered by viewers. Prefer images that are already close to the displayed size, and avoid resending large images at high frequency.
Each Update call publishes the drawing commands currently buffered on the layer and then resets the drawing buffer for the next update. Redraw content before the next Update if it should remain visible with new timing or new geometry.
| Member | Description |
|---|---|
Update() |
Publish using the current UTC time. |
Update(DateTime frameTime) |
Publish with an explicit frame time. The time is converted to UTC before recording unless it is DateTime.MinValue. |
Update(DateTime frameTime, uint rtpTimestamp) |
Publish with both an explicit frame time and RTP timestamp. |
Update(uint rtpTimestamp) |
Publish with an RTP timestamp when that is the timing value your application has. |
Update returns true when the update is recorded. It returns false when the overlay is not ready for updates, the layer is disposed, or the update cannot be recorded. The first update can return false while the overlay starts up. Use Overlay.IsReadyForUpdate or Overlay.StateChange when the application needs to wait for update readiness.
Important
Update(DateTime) does not draw in the past. It does not edit an existing archive or insert an overlay into video that Security Center already recorded.
The supplied time becomes timing metadata for the update being sent through the current overlay stream. It does not backfill overlays, repair delayed analysis, or make the overlay appear on earlier video.
Use Update() for normal live annotations. Use the timestamp overloads only when the application already has the correct frame time or RTP timestamp for the overlay update it is sending.
Clear a layer by publishing an empty update for the same LayerIdentifier:
layer.Clear();
layer.Update();This is the right way to remove drawings during normal operation. Do not use OverlayFactory.Remove to clear routine content; that removes the overlay stream itself.
If a layer has a finite Duration, the player keeps the layer active until that duration expires. Since milliseconds are ignored, use Clear() followed by Update() when the application needs precise removal.
Overlay streams are camera metadata streams. A MediaPlayer discovers available overlay stream IDs while it plays video. Subscribe from the availability event instead of assuming the list is complete during initialization:
player.AvailableMetadataStreamChange += (_, _) =>
{
foreach (Guid streamId in player.AvailableMetadataStreams)
{
if (!player.MetadataStreamsSubscriptions.Contains(streamId))
{
player.SubscribeMetadataStream(streamId);
}
}
};| Member | Description |
|---|---|
AvailableMetadataStreams |
Overlay metadata stream IDs the player can subscribe to. |
MetadataStreamsSubscriptions |
Metadata stream IDs the player is currently subscribed to. |
AvailableMetadataStreamChange |
Raised when overlay metadata streams are discovered, added, or removed. |
SubscribeMetadataStream(Guid) |
Display the selected overlay metadata stream. |
UnsubscribeMetadataStream(Guid) |
Stop displaying the selected metadata stream. |
MediaPlayer.AutomaticallyStartOverlayStream |
Process-wide setting that makes players subscribe to overlay streams automatically as they are discovered. Set it explicitly for the behavior your application wants. |
To subscribe to one named overlay stream, match the stream name on the camera, then subscribe when the player reports that stream as available:
MetadataStreamInfo overlayStream = camera.MetadataStreams
.FirstOrDefault(stream => stream.Name == "AnalyticsOverlay" && !stream.IsGhost);
if (overlayStream != null &&
player.AvailableMetadataStreams.Contains(overlayStream.StreamId) &&
!player.MetadataStreamsSubscriptions.Contains(overlayStream.StreamId))
{
player.SubscribeMetadataStream(overlayStream.StreamId);
}The user must have the privilege to display video overlays for overlay subscription to succeed.
ShowSpecialOverlay(OverlayType) is unrelated to application overlay streams. It displays built-in player diagnostic overlays such as statistics and status.
No numeric maximum update frequency, layer count, or image size is defined for overlays. Each layer uses drawing resources, each update serializes the current layer content into a metadata update, and image updates include image data. Keep the layer set bounded, update only layers that changed, and dispose layers that are no longer used.
For recurring drawings, prefer stable layers with stable IDs. For temporary drawings, clear the layer and publish the clear update before disposing it. Dispose layers before disposing the parent overlay when shutting down an overlay workflow.
Use OverlayFactory.Remove only when the integration needs to remove the overlay stream itself, such as uninstall, migration, or cleanup. Pass deleteFiles: false when archived overlay data should remain available for playback. Pass deleteFiles: true only when the recorded overlay data should also be deleted.
- About MediaPlayer: MediaPlayer WPF control for live, recorded, and local-file playback.
- 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