Repository navigation
media sdk export archived media
MediaExporter retrieves recorded video from Security Center and writes it to a G64 or G64x package on disk. One exporter handles one or more cameras, one or more time ranges per camera, an optional set of archive sources, a watermark, a playback mode, and the choice of file format.
MediaExporter requires a Platform SDK Engine that is logged on to a Directory before you call Initialize. The Security Center license must include the Media SDK option.
MediaExporter writes export files to the destination folder you pass to Initialize. One exporter instance runs one export at a time. To run concurrent exports, create a separate MediaExporter for each.
ExportAsync returns an ExportEndedResult that carries the final status, the exported file paths, and any exception details. Subscribe to ExportStarted, StatisticsReceived, and ExportEnded only when the UI needs live progress; otherwise the result is enough. Treat ExportResults as one final status value, not as flags.
Create the exporter, initialize it against an engine and destination folder, then call ExportAsync:
using Genetec.Sdk.Media;
using Genetec.Sdk.Media.Export;
using MediaExporter exporter = new MediaExporter();
exporter.StatisticsReceived += OnExportStatisticsReceived;
bool initialized = exporter.Initialize(
engine,
destinationFolder,
clientSubnet: Guid.Empty,
exportOriginalStream: false);
if (!initialized)
{
throw new InvalidOperationException(
"The exporter was not initialized.");
}
exporter.SetExportFileFormat(MediaExportFileFormat.G64X);
var range = new DateTimeRange(startTimeUtc, endTimeUtc);
var cameraExport = new CameraExportConfig(
cameraGuid,
new[] { range });
ExportEndedResult result = await exporter.ExportAsync(
cameraExport,
PlaybackMode.AllAtOnce,
"EntranceExport",
includeWatermark: true);
if (result.Results == ExportResults.Successful)
{
foreach (string exportedFile in result.ExportFileList)
{
RegisterExportedFile(exportedFile);
}
}Initialize returns false when the exporter is already running an export on the same instance. Invalid arguments such as a missing destination folder or an unconnected engine can throw. Check the return value before calling ExportAsync.
exportOriginalStream controls how the exporter handles privacy protection. When true, the exporter exports the original stream without applying privacy protection. When false (the default), the exported stream respects the camera's privacy-protection configuration.
Use Guid.Empty for clientSubnet when the default media route is correct. Pass a specific subnet GUID when the SDK application must resolve media through a particular network route, such as when the application runs on a different network than the default route. A wrong route selector can prevent Security Center from resolving a usable stream or server address and can lead to media-routing failures such as UnableToSatisfy, SpecifiedServerUnavailable, or ErrorNoSessionDescriptor.
| Parameter | Type | Description |
|---|---|---|
engine |
IEngine | Connected Platform SDK engine logged on to a Directory. |
destinationFolder |
string | Folder where the exporter writes output files. |
clientSubnet |
Guid | Media route selector. Pass Guid.Empty for the default route, or a specific subnet GUID when the application must resolve media through that route. |
exportOriginalStream |
bool | When true, export the original stream without applying privacy protection. |
Initialize returns bool: true on success, false when an export is already in progress on this instance.
Validation performed by Initialize:
-
sdkEnginemust not be null. -
destinationFoldermust already exist. -
sdkEnginemust be a Platform SDKEngine. - The engine must be connected.
- The Security Center license must include the Media SDK option.
| Format | When to use it | Constraints |
|---|---|---|
MediaExportFileFormat.G64X |
Default. Multi-camera, multi-range, password-protectable, re-exportable. | Each range can be up to four days. |
MediaExportFileFormat.G64 |
Legacy format. | One camera, one time range. The range can be up to one day. |
Set the format with SetExportFileFormat(MediaExportFileFormat) after Initialize. Default is G64X. Use G64 only when a downstream system specifically requires it.
Choose G64X to retain recorded overlay streams. When overlay data exists for the selected interval and the user has the display video overlays privilege, the package includes the overlay metadata separately from the video. Legacy G64 export omits those streams and does not burn their drawings into the video pixels. See Recorded overlay content for what the metadata contains.
CameraExportConfig describes what to export for one camera: the camera GUID, one or more UTC DateTimeRange values, and optional archive source GUIDs.
var morning = new DateTimeRange(morningStartUtc, morningEndUtc);
var afternoon = new DateTimeRange(afternoonStartUtc, afternoonEndUtc);
var exportConfig = new CameraExportConfig(
cameraGuid,
new[] { morning, afternoon },
archiveSourceGuids);CameraExportConfig validates that the camera GUID is not empty, that dateTimeRanges and archiveSources are not null, and that at least one range is present.
Use UTC DateTimeRange values. Ranges for the same camera must not overlap, and each range's end time must be greater than its start time. If the user picks several clips in a UI, validate and merge the selection before constructing CameraExportConfig instances.
Pass archive source GUIDs only when the application must target a specific Archiver or Auxiliary Archiver source. Most integrations omit them and let Security Center select an available source.
The archiveSources argument in CameraExportConfig expects Archiver role GUIDs or Auxiliary Archiver role GUIDs. Pass the role GUID, not an agent GUID; the supplied GUID is validated against the Role entity, and the exporter selects the correct agents from the role itself.
To discover which source contains video for a camera and time range, run a VideoFileQuery for that camera and range and inspect the ArchiveSourceGuid column:
var query = (VideoFileQuery)engine.ReportManager.CreateReportQuery(
ReportType.VideoFile);
query.Cameras.Add(cameraGuid);
query.TimeRange.SetTimeRange(startTimeUtc, DateTime.MaxValue);
query.SecondStartTime = endTimeUtc;
QueryCompletedEventArgs results = query.Query();
var fileSourceGuids = results.Data.Rows
.Cast<DataRow>()
.Select(row => (Guid)row[VideoFileQuery.ArchiveSourceGuidColumnName])
.Distinct()
.ToList();For an Archiver source, VideoFileQuery.ArchiveSourceGuidColumnName corresponds to an Archiver archive source, also known as an agent. Map that agent back to the owning Archiver role before passing a GUID to CameraExportConfig: enumerate the Archiver roles and select the one whose ArchiveSources collection contains the agent GUID. For an Auxiliary Archiver source, the source GUID is the Auxiliary Archiver role GUID.
ExportAsync has an overload that accepts a list of CameraExportConfig for multi-camera exports:
ExportEndedResult multiResult = await exporter.ExportAsync(
cameraExportConfigs,
PlaybackMode.AllAtOnce,
"IncidentExport",
includeWatermark: true,
canReExport: true,
textOverlay: "Incident 2026-04-25");| Parameter | Description |
|---|---|
playbackMode |
AllAtOnce plays all selected ranges in a multi-tile layout. Sequential plays sequences one after the other. |
exportName |
Base name for the exported package. The exporter may produce more than one file using this base name. |
includeWatermark |
Includes watermark data in the export when the source video contains watermarking information. It does not create a visible text overlay. |
canReExport |
Controls whether supported viewers allow the exported video to be exported again. |
textOverlay |
Text stored with the exported package and displayed by supported players as an export watermark or text overlay. Whitespace-only values are ignored. |
Pass a base name without an extension for exportName. For G64x export sets, the exporter appends .g64x. If exportName is null, empty, or whitespace, the exporter uses SdkExporter.
Before starting a multi-camera export:
- Log on with an
Enginethat has Media SDK access. - Verify the destination folder exists and is writable by the application process.
- Use
MediaExportFileFormat.G64X. - Use UTC ranges.
- Validate that each camera has at least one range.
- Merge or reject overlapping ranges for the same camera.
- Keep each range at four days or less.
- Use empty archive sources unless the user selected a specific Archiver or Auxiliary Archiver.
- Pass Archiver role GUIDs or Auxiliary Archiver role GUIDs when filtering by archive source.
- Use
PlaybackMode.AllAtOncefor multi-tile playback, orPlaybackMode.Sequentialfor one sequence after another. - Use a file-system safe base name without an extension.
- Check
ExportEndedResult.Resultsand useExportEndedResult.ExportFileListinstead of constructing output paths.
ExportAsync performs additional validation after Initialize succeeds.
| Check | Failure behavior |
|---|---|
cameraExportConfigs is null or empty |
Throws an argument exception. |
| The exporter was not initialized | Returns ExportResults.Cancelled; if an Initialize call was started but did not complete, the export call fails instead. |
| Another export is already running on the same instance | Returns ExportResults.Cancelled with an exception explaining that another export is in progress. |
exportOriginalStream is true for a privacy-protected camera and the user lacks the remove privacy protection privilege |
Returns ExportResults.InsufficientPrivilege. |
| A camera GUID is empty or does not resolve to a camera | Throws an argument exception. |
| An archive source GUID does not resolve to a role | Throws an argument exception. |
| A range has an end time equal to or earlier than its start time | Throws an argument exception. |
| Ranges overlap for the same camera | Throws an argument exception. |
| A G64 range is longer than one day | Throws ArgumentOutOfRangeException. |
| A G64x range is longer than four days | Throws ArgumentOutOfRangeException. |
| G64 is used with more than one camera or more than one range | Throws InvalidOperationException. |
| The output path cannot be written during export | Returns ErrorNoWriteAccess, NotEnoughSpace, NoPathAvailable, ErrorFileAllocation, or another file-related result. |
Archive viewing limitations are applied during export. If the logged-on user cannot view part of a requested time range, the exporter adjusts the start time to the earliest time the user can view. For a G64 export, a range that is entirely outside the archive viewing limit fails the export with InsufficientPrivilege. For a G64x export, each range that is entirely outside the limit is excluded from the export, and the remaining ranges are exported.
The destination folder comes from Initialize. The exportName argument passed to ExportAsync is a base name, not a full path. Use a name without an extension.
Existing files are not overwritten. When the chosen output path already exists, the exporter adds a numeric suffix such as _1, _2, and so on.
One export can produce more than one file. The exact files depend on the format, the selected ranges, the media types included in the archive, and how the source archive is split. Always read ExportEndedResult.ExportFileList after completion. For live UI, use ExportStartedEventArgs.CompleteExportFilePath to display the file that just started.
File extensions used by export include:
| Extension | Meaning |
|---|---|
.g64x |
G64x package. Used for export sets and for G64x output. |
.g64 |
Video archive file. |
.g64a |
Audio archive file. |
.g64m |
Metadata archive file. |
The current capability flag is ExportProgressReporting. When this flag is present, StatisticsReceived carries percentage, bit rate, frame rate, and transferred-bytes values the UI can display. When the flag is absent, drive UI from ExportEndedResult instead.
ExporterCapabilities is meaningful only after ExportAsync has been invoked at least once. Reading it before then throws InvalidOperationException, and reading it after Dispose returns None. Read it from inside an ExportStarted handler or after the first ExportAsync call returns.
exporter.ExportStarted += (sender, e) =>
{
bool canReportProgress = exporter.ExporterCapabilities
.HasFlag(ExporterCapabilities.ExportProgressReporting);
};| Event | Args | Description |
|---|---|---|
ExportStarted |
ExportStartedEventArgs |
Raised when the export begins. Carries the export file path. |
StatisticsReceived |
ExportStatisticsEventArgs |
Periodic progress: percentage (0-100), bit rate, frame rate, transferred bytes. Only raised when ExportProgressReporting is supported. |
ExportEnded |
ExportEndedEventArgs |
Raised when the export finishes. Equivalent to the awaited ExportEndedResult returned by ExportAsync. |
For new code, await ExportAsync and read ExportEndedResult directly. Use ExportEnded for event-driven integrations that do not await ExportAsync.
| Property | Type | Description |
|---|---|---|
Results |
ExportResults |
Final status, such as Successful, Cancelled, InsufficientPrivilege, or ErrorOccured. |
ExportFileList |
IEnumerable<string> |
Paths of files the export wrote. One export can produce more than one file. |
ExceptionDetails |
Exception |
Exception raised during the export, when the export fails with an exception. |
ErrorMessage |
string |
Human-readable error description when the export fails. |
Inspect Results first. When it is Successful or PartiallySuccessful, use ExportFileList as the set of files produced by the exporter. For any other result, do not treat listed paths as complete output. When you cancel with deleteExportFiles: true, partial files are deleted and the list can be empty; when you cancel with deleteExportFiles: false, listed files can be partial.
Use ExportEndedResult.Results to decide what to do next.
| Result | Meaning | Developer action |
|---|---|---|
Undefined |
No final result was set. | Treat as failure, log ErrorMessage, and do not use partial files. |
Successful |
The export completed. | Use every path in ExportFileList. |
Cancelled |
The export was cancelled, or the exporter returned cancellation because it could not start the requested operation. | Do not treat partial files as complete. If the user did not cancel, inspect ExceptionDetails. |
NoVideoAvailable |
No video matched the camera, time range, and source selection. | Let the user pick another time range or remove the archive source filter. |
SpecifiedServerUnavailable |
The exporter could not reach the required server. | Check Archiver, Media Router, redirector, or server availability, then retry. |
ConnectionLost |
The exporter lost its connection during export. | Retry after the media route is stable. |
EntityNotFound |
A camera or playback source no longer resolves. | Refresh entities and rebuild the export request. |
MissingConfiguration |
Required export configuration was missing or invalid. | Verify Initialize, format selection, destination path, and export parameters. |
ErrorOccured |
A generic export error occurred. | Show or log ErrorMessage and ExceptionDetails. |
MaximumUnitPlaybackConnection |
The unit reached its maximum playback connection count. | Reduce concurrent playback or export sessions, then retry. |
PlaybackCapacityReached |
Playback capacity was reached while retrieving archive sequences. | Reduce concurrent exports or playback sessions, then retry. |
NotEnoughSpace |
The destination does not have enough free space. | Free disk space or choose another destination. |
NoPathAvailable |
No valid output path was available. | Choose a valid destination folder and retry. |
PartiallySuccessful |
At least one sequence was exported and at least one sequence was skipped. | Keep ExportFileList, warn the user, and show ErrorMessage when present. |
ErrorFileCreation |
The exporter could not create an output file. | Check the destination folder, file name, locks, and permissions. |
ErrorFileAllocation |
The exporter could not allocate an output path or file. | Check destination availability, free space, and file-system errors. |
ErrorPathTooLong |
The generated path exceeded the supported path length. | Shorten the destination path, camera names, or export base name. |
ErrorNoWriteAccess |
The process cannot write to the destination. | Choose a writable folder or change file-system permissions. |
ErrorNoSessionDescriptor |
The exporter could not get a media session descriptor. | Check media routing, Archiver availability, and network connectivity. |
ErrorGettingSequenceList |
The exporter could not retrieve the archive sequence list. | Retry after checking Archiver and Media Router health. |
ErrorRTSPSession |
An RTSP session error occurred. | Check media route, certificates, and network stability. |
ErrorPlaybackSourceDeleted |
A playback source was deleted during export. | Refresh archive sources and retry. |
ErrorExportUnhandledException |
An unhandled export exception occurred. | Log ExceptionDetails and treat the export as failed. |
ErrorLegacyExportAllSequenceEncrypted |
A legacy G64 export skipped every encrypted sequence. | Use G64x when possible, or export a range that can be exported by the current user. |
ErrorRTSPSecureSession |
The media route required a secure RTSP session that could not be established. | Check secure communication and certificate configuration. |
ErrorUnauthorized |
The media request was unauthorized. | Verify the user session and export privileges. |
InsufficientPrivilege |
The user lacks a required privilege, or the archive viewing limitation excludes the requested range. | Check export video, playback, remove privacy protection, and archive viewing limitation settings. |
UnableToSatisfy |
No media route can satisfy the request, or a server address cannot be resolved. | Check Media Router, redirector, public/private address, and clientSubnet configuration. |
ExportStarted |
The export has started. | Do not treat this as completion. Wait for ExportEndedResult. |
ErrorExportAllSequenceEncrypted |
Every sequence was skipped because encrypted video could not be exported for the requested operation. | Check encryption-related privileges or choose an export format and range that can be exported. |
MissingFiles |
Required source archive files are missing. | Try another archive source, another time range, or investigate source storage. |
ManagedApplianceUnreachable |
A managed appliance required for the export is unreachable. | Restore appliance connectivity, then retry. |
The exporter checks privileges in several places:
-
Initializeverifies Media SDK access. - Export startup enforces the export video privilege.
- Federated cameras require export video privilege for the camera.
-
exportOriginalStream: truerequires the remove privacy protection privilege when the camera is privacy protected. - Archive viewing limitations can trim the requested start time or fail the export with
InsufficientPrivilege. - Audio is included only when the user has the use audio privilege.
- Overlay and ONVIF analytics streams are included only when the user has the display video overlays privilege.
When the result is InsufficientPrivilege, ErrorUnauthorized, ErrorExportAllSequenceEncrypted, or ErrorLegacyExportAllSequenceEncrypted, do not retry blindly. Check the logged-on user's privileges, archive viewing limitation, selected format, and whether the source video is encrypted or privacy protected.
exporter.CancelExport(deleteExportFiles: true);Pass true to delete partial output. Pass false to keep partial files for review or diagnostics.
After cancellation, ExportAsync completes with ExportEndedResult.Results == ExportResults.Cancelled. Do not reuse the same exporter instance for a follow-up export until the cancelled one has completed.
MediaExporter implements IDisposable. Wrap the exporter in using so resources are released even if ExportAsync throws.
- About media file formats: Choosing between G64x, G64, and MP4 output.
- About MediaFile: Inspecting an existing G64, G64x, or MP4 file on disk.
- About PlaybackStreamReader: Reading raw recorded video, audio, or metadata frames as data.
- About G64 converters: Converting G64 and G64x packages to ASF or MP4.
- 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