Skip to main content

Public Interface

The recorder SDK exposes two public layers:

  • A native C++ DLL interface in TSRecorder/ITSRecorder.h
  • A managed .NET-facing wrapper in TSRecorderWr/ITSRecorderWr.h

This page documents the API surface that is actually implemented by the recorder code, including the lifecycle, configuration types, callbacks, and the segment filename convention.

Interface Layers

Native Recorder Interface

The native entry point is the exported factory function:

ITSRecorder* recorder = CreateTSRecorder("Recorder-1");

The created object implements ITSRecorder and is configured with plain C++ types:

  • NetSourceProps
  • FileTargetProps
  • NetRecasterProps

Managed Wrapper Interface

The managed interface is TSRecorderWr::ITSRecorderWr. The concrete implementation used by .NET callers is TSRecorderWr::CTSRecorderWr.

using TSRecorderWr;

var recorder = new CTSRecorderWr(0, "Recorder-1");

The wrapper maps directly to the native recorder API and adds activation plus a small set of convenience properties.

Recorder Lifecycle

Use the recorder in this order:

  1. Create the recorder instance.
  2. Register recorder and error callbacks.
  3. Configure the source and target properties.
  4. Call Init(...).
  5. Optionally call SetRecaster(...) before Start().
  6. Call Start().
  7. Observe events and query statistics while recording.
  8. Call Stop().
  9. Call Close() before releasing the object.

Native Example

ITSRecorder* recorder = CreateTSRecorder("Recorder-1");
recorder->SetEventListener(OnRecorderEvent, OnRecorderError, context);

NetSourceProps source;
source.IP = "227.1.1.1";
source.Port = 1234;

FileTargetProps target;
target.Dir = "C:/Recordings";
target.BaseName = "capture.ts";
target.SegmentationType = SegmentationType_Seconds;
target.SegmentDuration = 10000;

if (recorder->Init(source, target))
{
recorder->Start();
}

// ...

recorder->Stop();
recorder->Close();

Native C++ Types

NetSourceProps

FieldTypeMeaning
NicstringNetwork interface identifier. Defaults to localhost.
IPstringSource IP address or multicast address.
PortintUDP port.
TimeoutintIdle timeout in milliseconds. When it expires, the recorder raises WaitingForData.
MaxDetectionTimeintMaximum PID detection time in milliseconds for GOP-aligned mode.
UrlstringOptional full input URL. The implementation also inspects it for /shmem=... shared-memory input.

NetRecasterProps

FieldTypeMeaning
NicstringOutgoing network interface used for recasting.
IPstringRecast destination IP address.
PortintRecast destination UDP port.
Ttlunsigned intMulticast TTL.
UrlstringOptional full recast URL.

FileTargetProps

FieldTypeMeaning
BaseNamestringOutput filename template. The recorder uses its stem and extension when generating the actual segment filenames.
DirstringOutput directory. It is created during Init(...) if it does not exist.
SegmentationTypeFileSegmentationTypeSegmentationType_None, SegmentationType_KBytes, or SegmentationType_Seconds.
SegmentDurationunsigned intSegment duration in milliseconds when splitting by time.
SegmentLength__int64Segment size in bytes when splitting by size. Must be non-zero for size-based segmentation.
StartIndexunsigned intInitial segment index used in generated filenames and event parameters.
GopAlignedSegmentationboolWhen true, segment cuts are delayed to H.264 GOP boundaries.
OldSegmentDeletionModeOldSegmentDeleteModeNone, delete by count, or delete by quota.
LastSegmentsToKeepunsigned intRetention count used with OldSegmentDelete_OnCount.
DiskSpaceQuotaunsigned longRetention quota used with OldSegmentDelete_OnQuota. The native code treats this as megabytes.
MinFlushIntervalintMinimum flush interval in milliseconds. -1 disables explicit flushing.
MinWriteSizeunsigned intBuffered write threshold in bytes.

Enumerations

The public header also exports these enums:

  • Recorder_Event
  • Error_Type
  • ITSRecorderState::TSRecorderState
  • FileSegmentationType
  • OldSegmentDeleteMode

See the separate Recorder Events page for the event list.

Native C++ Methods

MethodDescription
Init(const NetSourceProps&, const FileTargetProps&)Stores configuration, validates segmentation settings, creates the target directory when needed, and raises Initialized on success.
SetRecaster(const NetRecasterProps&)Enables optional UDP recasting before or during recording setup.
Start()Starts the UDP client and processing thread. Returns false if called in the wrong state.
Stop()Stops input, finalizes the current segment, and raises Stopped.
Close()Releases the recorder resources. Call this before deleting the object.
SetEventListener(...)Registers the recorder and error callbacks plus a caller-provided context pointer.
GetCurrentSegmentPath()Returns the full path of the current output file.
GetTotalReceivedSize()Returns the total received byte count for the current session.
GetTotalRecordedSize()Returns the total recorded byte count for the current session.
GetCurrentSegmentReceivedSize()Returns bytes received for the current segment.
GetCurrentSegmentRecordedSize()Returns bytes written for the current segment.
GetCurrentSegmentIndex()Returns the current segment index.
GetRecordingBitrate()Returns the average bitrate since the previous bitrate query.
GetProgress()Returns segment progress as a percentage. In segmented mode it is based on the current duration or size threshold and capped at 100.

Callback Contracts

Native Callbacks

typedef void (__stdcall *TSRECORDER_EVENT_CALLBACK)(
Recorder_Event ev,
LPCSTR description,
__int64 param,
void* context);

typedef void (__stdcall *TSRECORDER_ERROR_CALLBACK)(
Error_Type e,
LPCSTR description,
void* context);

The description and param values are event-specific. For the segment lifecycle events, the implementation uses the following values:

  • SegmentStarted: description is the full segment path, param is the segment index
  • SegmentCompleted: description is the full segment path, param is the segment index
  • WaitingForData: param is the configured timeout in milliseconds
  • DetectionCompleted: param carries the detected video PID when one is found

Managed Delegates

public delegate void NotifyRecorderEvent(
Recorder_Event ev,
string info,
long param,
object context);

public delegate void NotifyError(
Error_Type e,
string err,
object context);

The wrapper passes the recorder Id object as the managed context argument.

Managed Wrapper Surface

The managed wrapper mirrors the native recording functions and adds activation support.

Main Members of ITSRecorderWr

MemberDescription
Activate(appName, licPath, key)Activates the licensed feature set.
GetNodeInfo()Returns host information used for licensing and support.
Init(NetSourcePropsWr, FileTargetPropsWr)Managed equivalent of the native Init(...).
SetRecaster(NetRecasterPropsWr)Managed equivalent of the native SetRecaster(...).
Start(), Stop(), Close()Recorder lifecycle methods.
GetTotalReceivedSize(), GetTotalRecordedSize()Session totals.
GetCurrentSegmentReceivedSize(), GetCurrentSegmentRecordedSize()Current-segment totals.
GetCurrentSegmentIndex()Current segment index.
GetCurrentSegmentPath()Current segment full path.
GetRecordingBitrate()Bitrate since the previous query.
GetProgress()Progress percentage for the current segment.
RecorderEventRecorder event notification.
ErrorEventError notification.
Id, NameCaller-supplied identity values from CTSRecorderWr.
RecorderStateWrapper-side state that is updated from core events.
SessionDurationElapsed time since the session start.
LastErrorLast error text observed by the wrapper.
SourceProps, TargetPropsLast source and target objects passed to Init(...).

Wrapper Property Types

NetSourcePropsWr, NetRecasterPropsWr, and FileTargetPropsWr map directly to the native structures, with two notable differences:

  • FileTargetPropsWr.SegmentDuration is a TimeSpan
  • FileTargetPropsWr.DiskSpaceQuota is documented and passed as megabytes

Managed Wrapper Notes

  • CTSRecorderWr is constructed as CTSRecorderWr(Object^ id, String^ name).
  • The wrapper rejects Init(...) if the source IP is missing.
  • The wrapper rejects SetRecaster(...) if the recast IP is missing.
  • The current implementation stores only one handler for RecorderEvent and one handler for ErrorEvent.

Recorder Segment Naming Convention

The recorder has two naming layers:

  • The native recorder generates the actual transport-stream file paths.
  • The HLS wrapper reuses those .ts files and adds playlist-specific naming rules.

Native TS Segment Files

The native recorder does not write directly to BaseName.

Instead, it splits BaseName into a stem and an extension, then generates the actual filename in the following format:

<stem>_<index>_<YYYY>_<MM>_<DD>_<HH>_<MM>_<SS><extension>

Example:

BaseName: capture.ts
StartIndex: 42
Generated file: capture_42_2026_03_25_14_07_11.ts

Native naming rules:

  • The timestamp uses local system time.
  • The timestamp has one-second resolution.
  • The numeric index starts from StartIndex.
  • The segment index is incremented after each completed segment.
  • If BaseName has no extension, the generated files are also extensionless.
  • Even when segmentation is disabled, the recorder still creates the output path through the same naming function, so the single output file also receives the index and timestamp suffix.

HLS Media Segments And Playlists

When you initialize HLS recording with InitHls(srcUrl, trgtManifest, ...), the wrapper derives segment names from the target manifest path:

  • The video playlist path is exactly trgtManifest.
  • The native segment BaseName becomes Path.ChangeExtension(trgtManifest, ".ts").
  • Because of that, the underlying HLS media files still use the native filename pattern.

Example:

Target manifest: C:/Recordings/live.m3u8
Derived BaseName: C:/Recordings/live.ts
First segment file: C:/Recordings/live_0_2026_03_25_14_07_11.ts

The HLS manifest stores only the file name portion of each segment path, not the full absolute path. In the example above, the playlist entry is:

live_0_2026_03_25_14_07_11.ts

If CreateMasterManifest is enabled, the wrapper creates the master playlist as:

Master-<video-manifest-stem>.m3u8

Example:

Target manifest: live.m3u8
Master manifest: Master-live.m3u8

HLS Discontinuity Split Names

If SplitSegmentOnHlsDiscontinuity is enabled and the wrapper detects a PTS discontinuity inside one recorded .ts file, it physically cuts that file into sub-segments.

The first sub-segment is named:

<generated-segment-stem>-1.ts

Additional sub-segments continue the same suffix sequence:

<generated-segment-stem>-2.ts
<generated-segment-stem>-3.ts

Example:

Original recorded segment: live_0_2026_03_25_14_07_11.ts
Split sub-segments:
live_0_2026_03_25_14_07_11-1.ts
live_0_2026_03_25_14_07_11-2.ts

After the split files are created, the original unsplit file is scheduled for deletion and the manifest is updated to reference the split files.

Internal Temporary Files

During finalized-manifest generation and duration collection, the wrapper may create a temporary copy of the currently open segment using this pattern:

<generated-segment-stem>_last.ts

Example:

live_12_2026_03_25_14_20_00_last.ts

This _last file is an internal helper for analysis and finalization. It is not the steady-state segment naming convention used for normal recording output.

Retention And Naming Interaction

  • OldSegmentDelete_OnCount tracks only segments created during the current session.
  • OldSegmentDelete_OnQuota scans the target directory for existing files that share the same extension as BaseName, sorts them by last write time, and deletes the oldest ones first.
  • Because quota deletion is extension-based, using a dedicated directory for each recorder output is the safest way to avoid unrelated files being treated as recorder segments.

Practical Guidance

  • Always provide BaseName with the extension you want on the final files.
  • Use a dedicated output directory when retention-by-quota is enabled.
  • Treat GetRecordingBitrate() as a delta measurement, not a lifetime average.
  • Call Close() even after Stop() so that internal resources are released deterministically.