# NDI Sender Event Monitoring

To provide deeper control over NDI sources, the Advanced SDK supplements the standard **NDI Send Advertiser** and **NDI Send Listener** APIs with a more powerful toolset. These advanced APIs unlock comprehensive event subscription any registered sender. This extension empowers developers to not only be aware of the sender but also to listen to a sender's real-time event (per request or by default). Such capabilities are fundamental for creating sophisticated NDI ecosystems, allowing for intricate control and real-time monitoring of all NDI sending sources.&#x20;

Beyond the standard functions—`NDIlib_send_advertiser_create` and `NDIlib_send_listener_create`—available in the standard SDK, the **Advanced SDK** offers extended versions of this function calls:&#x20;

* NDIlib\_send\_advertiser\_create\_ex&#x20;
* NDIlib\_send\_listener\_create\_ex&#x20;

These extended functions accept configuration settings as JSON strings, providing greater flexibility for managing network configurations of both the sender advertiser and listener.&#x20;

## Subscribing to Sender Events

To subscribe to receive monitoring events from a specified sender, use the following function,&#x20;

`void NDIlib_send_listener_subscribe_events(NDIlib_send_listener_instance_t p_instance, const char* p_sender_uuid);`&#x20;

This function requires the following parameters:&#x20;

* p\_instance: The sender listener instance (`NDIlib_send_listener_instance_t`).&#x20;
* p\_uuid: The unique identifier of the sender.&#x20;

The sender’s UUID is part of the `NDIlib_sender_t structure`, which is generated by the SDK. You can retrieve the list of senders using the `NDIlib_send_listener_get_senders` function, which will provide the necessary UUID for each sender.

## Unsubscribing from Sender Events

To unsubscribe from receiving events from a specific sender, use the following function,&#x20;

`NDIlib_send_listener_unsubscribe_events(NDIlib_send_listener_instance_t p_instance, const char* p_sender_uuid);`&#x20;

This function requires the following parameters:&#x20;

* p\_instance: The sender listener instance (`NDIlib_send_listener_instance_t`).&#x20;
* p\_uuid: The unique identifier of the sender.&#x20;

**Example Code:**&#x20;

The following example demonstrates how to create a sender listener, retrieve the list of advertised senders, subscribe to events, and unsubscribe when finished:

{% code overflow="wrap" %}

```
// Create an instance of the sender listener. 
NDIlib_send_listener_instance_t pNDI_sender_listener = NDIlib_send_listener_create_ex(nullptr, p_ndi_config); 
if (!pNDI_sender_listener) { 
    // Handle error 
} 

// Get the list of advertised senders. 
uint32_t num_senders = 0; 
const NDIlib_sender_t* p_senders = NDIlib_send_listener_get_senders(pNDI_send_listener, &num_senders); 

// Display the found senders. 
printf("Network senders (%u found).\n", num_senders); 
for (uint32_t i = 0; i < num_senders; i++) { 
printf("%u. %s\n", i + 1, p_senders[i].p_name); 

// If the sender is not currently subscribed, subscribe to it. 
if (!p_sender[i].events_subscribed) { 
        NDIlib_send_listener_subscribe_events(pNDI_send_listener, p_senders[i].p_uuid); 
    } 

// Perform operations with the subscribed sender... 
… 
// Unsubscribe from the sender after processing. 
   NDIlib_send_listener_unsubscribe_events(pNDI_send_listener, p_senders[i].p_uuid); 
} 
```

{% endcode %}

## Sender Monitoring Events

The `NDIlib_send_listener_get_events` function allows you to fetch the list of monitoring events from the sender that you have previously subscribed to using the `NDIlib_send_listener_subscribe_events` function. It returns an array of `NDIlib_send_listener_event` structures containing the event details.&#x20;

{% code overflow="wrap" %}

```
const NDIlib_send_listener_event*
NDIlib_send_listener_get_events(NDIlib_send_listener_instance_t p_instance, uint32_t* p_num_events, uint32_t timeout_in_ms); 
```

{% endcode %}

**Parameters**:&#x20;

* **p\_instance** (NDIlib\_send\_listener\_instance\_t): The instance of the sender listener.&#x20;
* **p\_num\_events** (uint32\_t\*): A pointer to the variable that will receive the number of events returned by the function.&#x20;
* **timeout\_in\_ms** (uint32\_t): The timeout value in milliseconds, determining how long the function will wait for events. A value of 0 returns immediately with any current pending events, and -1 waits indefinitely until an event is received and .&#x20;

This function returns a pointer to an array of `NDIlib_send_listener_event` structures containing event details. If no events are received within the specified timeout period, the function returns NULL. The returned events should be freed using the `NDIlib_send_listener_free_events` function.&#x20;

**Example Code:**

```
uint32_t num_events; 
const NDIlib_send_listener_event* events = NDIlib_send_listener_get_events(p_instance, &num_events, 1000); 

if (events != NULL) { 
    for (uint32_t i = 0; i < num_events; ++i) { 
        printf("Event UUID: %s\n", events[i].p_uuid); 
        printf("Event Name: %s\n", events[i].p_name); 
        printf("Event Value: %s\n", events[i].p_value); 
    } 

// Free the events after processing 
NDIlib_send_listener_free_events(events); 
} else { 
    printf("No events received within the timeout period.\n"); 
} 
```

The following table lists the sender monitoring events currently supported in the first release. These events provide dynamic information about an NDI sender’s state, source, and media properties.

<table><thead><tr><th width="167.90911865234375">Event Name </th><th width="285.6363525390625">Description </th><th width="96.0908203125">Type </th><th>Example Event Values </th></tr></thead><tbody><tr><td>source-name </td><td>Name of the NDI source. </td><td>string </td><td>“Camera 2” </td></tr><tr><td>source-url </td><td>Comma-delimited list of valid URLs for the NDI sender. It would be a list due to having multiple network interfaces being available on the system. </td><td>string </td><td>“ndi://192.168.1.11/Camera_2” </td></tr><tr><td>connection-state </td><td><p>Indicator as to whether the NDI sender has any connected NDI receivers or not. Values can be one of the following: </p><ul><li>connected </li><li>disconnected </li></ul></td><td>string </td><td>“connected”, “disconnected” </td></tr><tr><td>connected-receivers </td><td>The number of connected NDI receivers to this NDI sender. </td><td>int </td><td>“42” </td></tr><tr><td>metadata-frames-sent </td><td>Number of metadata frames sent by the NDI sender. This would be an aggregate across each NDI receiver that is actively connected. </td><td>int64 </td><td>“1” </td></tr><tr><td>metadata-bytes-sent </td><td>Number of bytes sent for metadata frames. This would be an aggregate across each NDI receiver that is actively connected. </td><td>int64 </td><td>“2048” </td></tr><tr><td>audio-present </td><td>Has audio been sent through this NDI sender? </td><td>bool </td><td>true, false </td></tr><tr><td>audio-codec </td><td><p>The audio codec in use. Values can be one of the following: </p><ul><li>pcm </li><li>aac </li><li>opus </li></ul></td><td>string </td><td>“pcm”,”aac”,”opus” </td></tr><tr><td>audio-channels </td><td>The number of audio channels within the audio stream. </td><td>int </td><td>“8” </td></tr><tr><td>audio-sample-rate </td><td>The sample rate of the audio stream. </td><td>int </td><td>“44100”, “48000” </td></tr><tr><td>audio-frames-sent </td><td>Number of audio frames sent by the NDI sender. This would be an aggregate across each NDI receiver that is actively connected. </td><td>int64 </td><td>“1976” </td></tr><tr><td>audio-bytes-sent </td><td>Number of bytes sent for audio frames. This would be an aggregate across each NDI receiver that is actively connected. </td><td>int64 </td><td>“300001” </td></tr><tr><td>video-present </td><td>Has video been sent through this NDI sender? </td><td> bool </td><td>true, false </td></tr><tr><td>video-codec </td><td><p>The video codec in use. Values can be one of the following: </p><ul><li>shq0 </li><li>shq2 </li><li>shq7 </li><li>h264 </li><li>h265 </li></ul></td><td>string </td><td>“shq0” </td></tr><tr><td>video-resolution </td><td>The resolution of the video frames, in “WxH” format, where W is the width and H is the height. </td><td>string </td><td>“1920x1080”,“1280x720”, “3840x2160” </td></tr><tr><td>video-frame-rate </td><td>The frame rate of the video stream, in “N/D” format, where N is the numerator and D is the denominator. </td><td>string </td><td>“30/1”, “60/1”, “30000/1001” </td></tr><tr><td>video-frame-type </td><td><p>The type of fielding format in use by the video stream. Values can be one of the following: </p><ul><li>progressive </li><li>interlaced </li></ul></td><td>string </td><td>“progressive”, “interlaced” </td></tr><tr><td>video-has-alpha </td><td>Does the video stream contain an alpha channel? </td><td>bool </td><td>true, false </td></tr><tr><td>video-color-primaries </td><td><p>Color primaries of the video stream. Values can be one of the following: </p><ul><li>bt_601 </li><li>bt_709 </li><li>bt_2020 </li><li>bt_2100 </li></ul></td><td>string </td><td>“bt_601”, “bt_709”, “bt_2020”, “bt_2100” </td></tr><tr><td>video-transfer-function </td><td><p>Transfer function of the video stream. Values can be one of the following: </p><ul><li>bt_601 </li><li>bt_709 </li><li>bt_2020 </li><li>bt_2100_hlg </li><li>bt_2100_pq </li></ul></td><td>string </td><td>“bt_601”, “bt_709”, “bt_2020”, “bt_2100_hlg”, “bt_2100_pq” </td></tr><tr><td>video-matrix-coefficients </td><td><p>Matrix coefficients of the video stream. Values can be one of the following: </p><ul><li>bt_601 </li><li>bt_709 </li><li>bt_2020 </li><li>bt_2100 </li></ul></td><td>string </td><td>“bt_601”, “bt_709”, “bt_2020”, “bt_2100” </td></tr><tr><td>video-frames-sent </td><td>Number of video frames sent by the NDI sender. This would be an aggregate across each NDI receiver that is actively connected. </td><td>int64 </td><td>“600” </td></tr><tr><td>video-bytes-sent </td><td>Number of bytes sent for video frames. This would be an aggregate across each NDI receiver that is actively connected. </td><td>int64 </td><td>“450001” </td></tr><tr><td>tally-on-program</td><td>Is this NDI sender on program?</td><td>bool</td><td>true, false</td></tr><tr><td>tally-on-preview</td><td>Is this NDI sender on preview?</td><td>bool</td><td>true, false</td></tr><tr><td>sdk-version </td><td>Returns the NDI version for the sender. </td><td>string </td><td>6.3.0.0 </td></tr></tbody></table>

These monitoring events allow tracking of both transient and persistent properties of an NDI Sender. Additional properties will be supported in future SDK versions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ndi.video/all/developing-with-ndi/sdk/ndi-sender-discovery-and-monitor/ndi-sender-event-monitoring.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
