Edit

Configure the media connector

In Azure IoT Operations, the media connector enables access to media from media sources such as cameras.

An asset in Azure IoT Operations is a logical entity that you create to represent a physical asset or device. An Azure IoT Operations asset can have custom properties, data points, streams, and events that describe its behavior and characteristics. An asset is associated with one or more devices. Azure IoT Operations stores asset definitions in the Azure Device Registry.

A device in Azure IoT Operations is a logical entity that defines the connections to physical assets or devices. Without a device, data can't flow from a physical device or asset to the MQTT broker. When you configure a device and asset, a connection is established to the physical asset or device and data point values, events, and streams arrive in Azure IoT Operations instance. A device has one or more inbound endpoints. Azure IoT Operations stores device definitions in the Azure Device Registry.

The following table summarizes the features the media connector supports:

Feature Supported Notes
Username/password authentication Yes For RTSPS endpoints
X.509 user certificates No
Anonymous access Yes For testing purposes
Southbound certificate trust list Yes For media source TLS certificate validation
OpenTelemetry integration Yes
Northbound username/password authentication Yes For RTSPS endpoints
Northbound anonymous access Yes For RTSP and RTSPS endpoints
Northbound certificate trust list Yes For RTSPS endpoint TLS certificate validation
Snapshot to MQTT Yes Publish image snapshots to MQTT topics
Clip to file system Yes Save video clips to local storage
Snapshot to file system Yes Save image snapshots to local storage
Stream to RTSP/RTSPS Yes Proxy live video streams to an RTSP or RTSPS endpoint

For each configured stream, the connector for media:

  1. Opens a connection to the stream from the media source.
  2. Generates clips, captures snapshots, or proxies the stream as specified in the stream configuration.
  3. Sends the media to the specified destination.

This article explains how to use the media connector to perform tasks such as:

  • Define the devices that connect media sources to your Azure IoT Operations instance.
  • Add assets, and define their streams for capturing media from the media source.
  • Send an image snapshot to the MQTT broker.
  • Save a video clip to Azure storage.

Prerequisites

  • The Azure CLI installed on your development machine. Check Available Azure CLI extensions for the minimum required version to use the azure-iot-ops extension. Use az --version to check your version and az upgrade to update if necessary. For more information, see Install the Azure CLI.

  • The Azure IoT Operations extension for the Azure CLI. Use the following command to add the extension or update it to the latest version:

    az extension add --upgrade --name azure-iot-ops
    

To sign in to the operations experience web UI, you need a Microsoft Entra ID account with at least contributor permissions for the resource group that contains your Kubernetes - Azure Arc instance. You can't sign in with a Microsoft account (MSA). For more information, see Troubleshoot access to the operations experience web UI.

A camera connected to your network and accessible from your Azure IoT Operations cluster. The camera must support the Real Time Streaming Protocol for video streaming. You also need the camera's username and password to authenticate with it.

Media source types

The media connector can connect to various sources, including:

Media source Example URLs Notes
IP camera rtsp://192.168.178.45:554/stream1 RTSP endpoint to stream video. An IP camera might also expose a standard ONVIF control interface.
Media server rtsp://192.168.178.45:554/stream1 RTSP endpoint to stream video. A media server might also expose other endpoints.

Stream configuration

The streamconfigurations of an asset describe how to process the stream received from an inbound endpoint of type Microsoft.Media.

Task types

The media connector supports the following streamconfiguration task types:

Task type Description
snapshot-to-mqtt Captures a snapshot from a media source and publishes it to an MQTT topic.
snapshot-to-fs Saves a snapshot from a media source to the container file system.
clip-to-fs Saves a video clip from a media source to the container file system.
stream-to-rtsp Proxies a live video stream from a media source to RTSP endpoints.
stream-to-rtsps Proxies a live video stream from a media source to RTSPS endpoints.

Each task type supports different configuration properties in the streamconfiguration:

Property Type Allowed values Default snapshot-to-mqtt snapshot-to-fs clip-to-fs stream-to-rtsp stream-to-rtsps
autostart boolean true, false true yes yes yes yes yes
format string png, bmp, jpg, jpeg, tif, tiff jpeg yes no no no no
format string png, bmp, jpg, jpeg, tif, tiff png no yes no no no
snapshotsPerSecond number 0-60.0 1 yes yes no no no
format string avi, mp4, mkv, mjpeg, mpg, mpeg mkv no no yes no no
duration integer 1-3600 60 no no yes no no
mediaServerUsernameRef string N/A "" no no no yes yes
mediaServerPasswordRef string N/A "" no no no yes yes
mediaServerCertificateRef string N/A "" no no no no yes

Northbound destinations

The output destination for the media connector depends on the streamconfiguration task type. Configure the destination in the asset's streamconfiguration:

  • snapshot-to-mqtt: Use a destination of type mqtt to specify the MQTT topic.
  • snapshot-to-fs and clip-to-fs: Use a destination of type storage. Set the path field to a fully qualified path inside the local container file system. To enable external access to the saved snapshots or clips, point this path to a mounted volume.
  • stream-to-rtsp and stream-to-rtsps: Set the path field to the endpoint address of the northbound media server that you want to proxy the source stream into.

Northbound RTSPS endpoint validation and user authentication

The connector supports username and password authentication when it connects to the southbound media source.

Follow the steps in Manage secrets for your Azure IoT Operations deployment to add secrets for username and password in Azure Key Vault, project them into Kubernetes cluster, and reference them from your Device inbound endpoint device configuration.

It also supports username and password authentication when it connects to a northbound media server for streamconfiguration task type stream-to-rtsps.

Follow the steps in Manage secrets for your Azure IoT Operations deployment to add secrets for username and password in Azure Key Vault and project them into Kubernetes cluster. Then follow the steps in Reference runtime secrets to reference the secrets in the connector template instance. The value of secretAlias is the value set in the streamconfiguration, the value of secretRef is the name of the secret CR created, and the value of secretKey is the key inside the secret identifying the entry which holds the value.

Note

Ensure you always use stream-to-rtsps when using authentication for the northbound media server to prevent sending credentials as clear text over the wire.

Media connector supports certificate validation of the southbound media source and the northbound media server certificate when TLS is used for the connection. Media connector does not support mutual TLS to connect.

The southbound media source endpoint is configured in the address field of the device inbound endpoint. The trust bundle to use for certificate validation must be configured by using the connector template instance. Follow the steps in Reference trust settings to reference the secret containing the trust bundle in the connector template instance.

The northbound media server endpoint is configured by using the destination of the streamconfiguration with task type stream-to-rtsp or stream-to-rtsps. For stream-to-rtsps the trust bundle to use for certificate validation must be configured by using the mediaServerCertificateRef in the stream configuration. Follow the process as described previously for username and password to define the secret which contains the trust bundle.

Manage certificates for external communications shows how to add secrets for TLS certificates in Azure Key Vault, project them into Kubernetes cluster.

Username and password authentication

The media connector supports username and password authentication for both:

  • Southbound connections to the media source.
  • Northbound connections to a media server, when the streamconfiguration task type is stream-to-rtsps.

To configure authentication:

  1. Add the username and password as secrets in Azure Key Vault and project them into the Kubernetes cluster. To learn more, see Manage secrets for your Azure IoT Operations deployment.

  2. Reference the secrets:

    • Southbound: From the Device inbound endpoint device configuration.

    • Northbound: From the runtimeConfiguration.managedConfigurationSettings.secrets section of the connector template instance. To learn more, see Create a connector template instance in Build and deploy Akri connectors. Use these values:

      Field Value
      secretAlias The alias set in the streamconfiguration.
      secretRef The name of the secret CR you created.
      secretKey The key inside the secret that holds the value.

Important

Always use stream-to-rtsps (not stream-to-rtsp) to authenticate to a northbound media server. Otherwise, credentials are sent in clear text.

TLS certificate validation

When you use TLS, the media connector validates the certificates of both the southbound media source and the northbound media server. Mutual TLS isn't supported.

To configure the trust bundle:

  • Southbound media source: The endpoint is set in the address field of the device inbound endpoint. Configure the trust bundle in the connector template instance, in the runtimeConfiguration.managedConfigurationSettings.trustSettings.trustListSecretRef field. To learn more, see Reference trust settings.

  • Northbound media server: The endpoint is set in the destination of a stream-to-rtsp or stream-to-rtsps streamconfiguration. For stream-to-rtsps, configure the trust bundle in the mediaServerCertificateRef field of the stream configuration. Use the same secret-creation process as for username and password.

To add TLS certificates as secrets in Azure Key Vault and project them into the Kubernetes cluster, see Manage certificates for external communications.

Example uses

Example uses of the media connector include:

  • Capture snapshots from a video stream and publish them to an MQTT topic. A subscriber to the MQTT topic can use the captured images for further processing or analysis.

  • Save snapshots or video clips to a local file system on your cluster. Use Azure Container Storage enabled by Azure Arc to provide a reliable and fault-tolerant solution for uploading the captured video to the cloud for storage or processing. To learn how to create a suitable persistent volume claim, see Cloud Ingest Edge Volumes configuration.

    Important

    You must install Azure Container Storage enabled by Azure Arc before you use it with the media connector template.

  • Proxy a live video stream from a camera to an RTSP/RTSPS endpoint that an operator provides. The operator can configure a media server, which does expose such an endpoint and transcode/transform the stream based on the operators requirements. This media server is not part of the media connector.

Media connector template instance

Before an OT user can create a device that uses the media connector, an IT administrator must add a media connector template instance to your Azure IoT Operations instance. If you save snapshots or video clips to storage, the IT administrator must also attach a persistent volume claim to the template. To learn more, see Create and manage connector template instances and Configure a persistent volume claim for the media connector.

Configure a certificate trust list for the connector

Each connector has its own trust list: the set of certificates the connector uses to validate the TLS certificate that a southbound endpoint presents when the connector establishes a secure connection to it. Add a certificate to the trust list when the southbound endpoint uses a TLS certificate that's signed by a private or enterprise certificate authority (CA), or a self-signed certificate that the connector doesn't already trust. Client certificates that the connector presents to the southbound endpoint for mutual TLS are configured separately as part of the device's user authentication.

Note

For the connector for OPC UA, the trust list also handles OPC UA application-instance certificates. To learn more, see Understand the OPC UA certificates infrastructure.

You can add a certificate to a connector's trust list in two ways:

  • Operations experience. In the operations experience web UI, you can either upload a certificate file directly or pick an existing secret from Azure Key Vault. The operations experience adds the certificate to Azure Key Vault as a secret (if needed), creates the synced secret resource on the cluster, and wires it into the connector's trust list for you. To learn more, see Manage certificates for external communications.

  • Azure CLI. The Azure CLI flow assumes the certificate is already stored as a secret in Azure Key Vault. You use az iot ops secretsync secret set to create a synced secret on the cluster that references the Key Vault secret, and then az iot ops connector template update to add a reference to the synced secret in the connector template's trust list. To learn more, see Add and use certificates. To learn how to add a certificate to Azure Key Vault, see Add certificates as secrets to Azure Key Vault.

The operations experience and the Azure CLI flows partially overlap. The operations experience can both upload a new certificate to Azure Key Vault and sync it to the cluster in one experience. The Azure CLI flow assumes the certificate is already in Azure Key Vault and only handles the sync and trust-list wiring.

Create a device with a media endpoint

To configure the media connector, first create a device that defines the connection to the media source. The device includes the URL of the media source and any authentication credentials you need to access the media source:

  1. In the operations experience web UI, select Devices in the left navigation pane. Then select Create new.

  2. Enter a name for your device, such as media-connector. To add the endpoint for the media connector, select New on the Microsoft.Media tile.

  3. Add the details of the endpoint for the media connector, including any authentication credentials:

    Screenshot that shows how to add a media connector endpoint.

    Select Apply to save the endpoint.

  4. On the Device details page, select Next to continue.

  5. On the Add custom property page, you can add any other properties you want to associate with the device. For example, you might add a property to indicate the manufacturer of the camera. Then select Next to continue.

  6. On the Summary page, review the details of the device and select Create to create the asset.

  7. After the device is created, you can view it in the Devices list:

    Screenshot that shows the list of devices.

Configure a device to use a username and password

The previous example uses the Anonymous authentication mode. This mode doesn't require a username or password.

To use the Username password authentication mode, complete the following steps:

In the operations experience, when you add the inbound endpoint and choose the Username password authentication mode, select Add reference to add the secret references for the username and password. The operations experience offers two options:

  • Create a new secret: uploads the value to Azure Key Vault and synchronizes it to the cluster as a synced secret.
  • Add from Azure Key Vault: synchronizes an existing Key Vault secret to the cluster.

The operations experience saves both the username and password references in a single synced secret resource on the cluster, and you give that synced secret a name.

To learn more, see Add and use secrets.

Create an asset to publish an image snapshot

To define an asset that publishes an image snapshot from the media source to the MQTT broker:

  1. In the operations experience web UI, select Assets in the left navigation pane. Then select Create asset.

  2. Select the inbound endpoint for the media connector that you created in the previous section.

  3. Enter a name for your asset, such as my-media-source.

  4. Add any custom properties you want to associate with the asset. For example, you might add a property to indicate the manufacturer of the camera. Select Next to continue.

  5. On the Streams page, select Add stream to add a stream for the asset.

  6. Add a name for the stream, such as mysnapshots. Set MQTT as the destination and add a name for the MQTT topic to publish to such as azure-iot-operations/data/snapshots. Select snapshot-to-mqtt as the task type.

    Screenshot that shows how to add a snapshot stream that publishes to an MQTT topic.

    Select Add to save the stream.

  7. On the Streams page, select Next to continue.

  8. On the Review page, review the details of the asset and select Create to create the asset.

Verify the published messages

To verify that the connector is publishing messages, use an MQTT client to subscribe to the topic you configured the asset to publish to. If the device and asset are configured correctly, you receive messages containing JPEG image snapshots when you subscribe to this topic.

The following steps show you how to run the mosquitto_sub tool in the cluster. To learn more about this tool and alternative approaches, see MQTT tools:

Verify data is flowing to the MQTT broker by using the mosquitto_sub tool. In this example, you run the mosquitto_sub tool inside your Kubernetes cluster:

  1. Run the following command to deploy a pod that includes the mosquitto_pub and mosquitto_sub tools that are useful for interacting with the MQTT broker in the cluster:

    kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/mqtt-client.yaml
    

    The following snippet shows the YAML file that you applied:

    # Important: do not use in production environments
    # Create a service account
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: mqtt-client
      namespace: azure-iot-operations
    ---
    # Creates a pod with mosquitto-clients and mqttui utilities in your cluster
    apiVersion: v1
    kind: Pod
    metadata:
      name: mqtt-client
      # The namespace must match the IoT MQ BrokerListener's namespace
      # Otherwise use the long hostname: aio-broker.azure-iot-operations.svc.cluster.local
      namespace: azure-iot-operations
    spec:
      # Use the "mqtt-client" service account which comes with default deployment
      # Otherwise create it with `kubectl create serviceaccount mqtt-client -n azure-iot-operations`
      serviceAccountName: mqtt-client
      containers:
        # Install mosquitto and mqttui utilities on Alpine linux
      - image: alpine
        name: mqtt-client
        command: ["sh", "-c"]
        args: ["apk add mosquitto-clients mqttui && sleep infinity"]
        resources:
          limits:
            cpu: 500m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - name: broker-sat
          mountPath: /var/run/secrets/tokens
        - name: trust-bundle
          mountPath: /var/run/certs
      volumes:
      - name: broker-sat
        projected:
          sources:
          - serviceAccountToken:
              path: broker-sat
              audience: aio-internal # Must match audience in BrokerAuthentication
              expirationSeconds: 86400
      - name: trust-bundle
        configMap:
          name: azure-iot-operations-aio-ca-trust-bundle # Default root CA cert
    

    Caution

    This configuration isn't secure. Don't use this configuration in a production environment.

  2. When the mqtt-client pod is running, run the following command to create a shell environment in the pod you created:

    kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh
    
  3. At the Bash shell in the mqtt-client pod, run the following command to connect to the MQTT broker using the mosquitto_sub tool and use a wildcard to subscribe to the data/# topics:

    mosquitto_sub --host aio-broker --port 18883 --topic "azure-iot-operations/data/#" -v --debug --cafile /var/run/certs/ca.crt -D CONNECT authentication-method 'K8S-SAT' -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat)
    

    This command continues to run and displays messages as they arrive on any data/# topics until you press Ctrl+C to stop it. To exit the shell environment, type exit.

To save the payload of a single message, use a command like the following example:

mosquitto_sub --host aio-broker --port 18883 --topic "azure-iot-operations/data/snapshots/#" -C 1 -F %p --cafile /var/run/certs/ca.crt -D CONNECT authentication-method 'K8S-SAT' -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat) > image1.jpeg

The following screenshot shows an example topic name that receives the published snapshots:

A screenshot that shows the published data in a topic called `azure-iot-operations/data/my-camera/mysnapshots`.

Add a stream to save a video clip

In this section, you add a stream to the asset that saves video clips from the media source to the file system. This section assumes that you configured Azure Container Storage enabled by Azure Arc with a subvolume called ingestSubDir and mounted the persistent volume claim to the connector template instance at /data. To learn more, see Configure a persistent volume claim for the media connector.

Azure CLI

To use the Azure CLI, run the following command to add a new stream called clipstream to the asset:

az iot ops ns asset media stream add --asset my-media-source-cli --instance {your instance name}  -g {your resource group name} --name clipstream --task-type clip-to-fs --format mkv --duration 30 --dest path=/data/ingestSubDir/clips --disable-autostart false

Bicep

To use a Bicep template:

Deploy the following Bicep template. The template redeploys the my-media-source-bicep asset with both the original snapshot stream and the new clip stream, because Bicep declares the full asset resource. Replace the placeholders <AIO_NAMESPACE_NAME> and <CUSTOM_LOCATION_NAME> with your Azure IoT Operations namespace name and custom location name respectively:

param adrNamespaceName string = '<AIO_NAMESPACE_NAME>'
param customLocationName string = '<CUSTOM_LOCATION_NAME>'

resource adrNamespace 'Microsoft.DeviceRegistry/namespaces@2026-04-01' existing = {
  name: adrNamespaceName
}

resource customLocation 'Microsoft.ExtendedLocation/customLocations@2021-08-31-preview' existing = {
  name: customLocationName
}

resource asset 'Microsoft.DeviceRegistry/namespaces/assets@2026-04-01' = {
  name: 'my-media-source-bicep'
  parent: adrNamespace
  location: resourceGroup().location
  extendedLocation: {
    type: 'CustomLocation'
    name: customLocation.id
  }
  properties: {
    displayName: 'my-media-source-bicep'
    description: 'An example media asset'
    enabled: true

    deviceRef: {
      deviceName: 'media-connector-bicep'
      endpointName: 'media-connector-bicep-0'
    }
    streams: [
      {
        name: 'mysnapshots-bicep'
        streamConfiguration: '{"taskType": "snapshot-to-mqtt","autostart":true, "format": "jpeg","snapshotsPerSecond": 0.25}'
        destinations: [
          {
            target: 'Mqtt'
            configuration: {
                topic: 'azure-iot-operations/data/snapshots'
                qos: 'Qos1'
                retain: 'Never'
                ttl: 60
              }
          }
        ]
      }
      {
        name: 'clipstream'
        streamConfiguration: '{"taskType": "clip-to-fs","autostart":true, "format": "mkv","duration": 30}'
        destinations: [
          {
            target: 'Storage'
            configuration: {
                path: '/data/ingestSubDir/clips'
              }
          }
        ]
      }
    ]
  }
}

Verify the saved messages

The following steps assume that you configured a persistent volume claim (PVC) to save the clips to your Azure Blob storage account with these settings:

Setting Value
Storage container pvc
Edge sub volume path ingestSubDir
Connector template mount path /data
Stream path in operations experience /data/ingestSubDir/clips

Important

The mount path must start with the '/' character.

After the connector captures the clips, it uploads them to the /clips folder in your storage container:

Screenshot that shows the captured streams in Blob storage.