Azure IoT Operations では、メディア コネクタ (プレビュー) を使用して、エッジ接続カメラなどのメディア ソースからメディアにアクセスできます。 この記事では、メディア コネクタを使用して次のようなタスクを実行する方法について説明します。
- MQTT ブローカーに画像スナップショットを送信する。
- ビデオ ストリームをローカル ファイル システムに保存する。
メディア コネクタ:
資産エンドポイントを使用してメディア ソースにアクセスします。 資産エンドポイントにより、カメラなどのメディア ソースへの接続が定義されます。 資産エンドポイントの構成には、メディア ソースの URL、メディア ソースの種類、およびメディア ソースへのアクセスに必要な認証情報が含まれます。
アセットを使用して、カメラなどのメディア ソースを表します。 資産により、カメラなどのメディア ソースの機能とプロパティが定義されます。
前提条件
Azure IoT Operations のデプロイされたインスタンス。 まだインスタンスがない場合は、「 クイック スタート: K3s を使用して GitHub Codespaces で Azure IoT 操作を実行する」を参照してください。
ネットワークに接続され、Azure IoT Operations クラスターからアクセスできるカメラ。 このカメラは、ビデオ ストリーミング用のリアルタイム ストリーミング プロトコルをサポートする必要があります。 また、カメラを認証するには、そのユーザー名とパスワードも必要です。
メディア コネクタを展開する
プレビュー バージョンのコネクタをデプロイするには、Azure IoT Operations インスタンスをデプロイするときにコネクタを有効にするか、インスタンスをデプロイした後で有効にすることができます。
Azure IoT Operations インスタンスをデプロイするときにプレビュー コネクタを有効にするには:
[Azure IoT Operations 基本のインストール] ページの >] セクションで ONVIF コネクタとメディア コネクタ (プレビュー) を選択します。
Azure IoT Operations インスタンスをデプロイした後でプレビュー コネクタを有効にするには:
Azure portal で Azure IoT Operations インスタンスに移動します。
プレビュー コネクタを有効にします。
重要
プレビュー機能を有効にしない場合は、メディアまたは ONVIF コネクタを使用しようとすると、 aio-supervisor-...
ポッド ログに次のエラー メッセージが表示されます: No connector configuration present for AssetEndpointProfile: <AssetEndpointProfileName>
。
メディア サーバーをデプロイする
メディア コネクタを使用してライブ ビデオをストリーミングする場合は、独自のメディア サーバーをインストールする必要があります。 メディア コネクタで使用するサンプル メディア サーバーを展開するには、次のコマンドを実行します。
kubectl create namespace media-server
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/refs/heads/main/samples/media-server/media-server-deployment.yaml
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/refs/heads/main/samples/media-server/media-server-service.yaml
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/refs/heads/main/samples/media-server/media-server-service-public.yaml
重要
このメディア サーバーは、テストと開発の目的にのみ適しています。 運用環境では、独自のメディア サーバーを提供する必要があります。
このメディア サーバーのクラスター IP アドレスを検出するには、次のコマンドを実行します。
kubectl get service media-server-public --namespace media-server
CLUSTER-IP 値をメモしておきます。後でメディア サーバーにアクセスするために使用します。
資産エンドポイントの構成
メディア コネクタを構成するには、まず、メディア ソースへの接続を定義する資産エンドポイントを作成します。 資産エンドポイントには、メディア ソースの URL、メディア ソースの種類、およびメディア ソースにアクセスするために必要な資格情報が含まれます。
カメラで認証が必要な場合は、カメラのユーザー名とパスワードを格納するシークレットを Kubernetes クラスターに作成します。 メディア コネクタは、このシークレットを使用してカメラで認証します。
次の内容を含む contoso-secrets.yaml という名前の YAML ファイルを作成します。 プレースホルダーを、base64 でエンコードされたカメラのユーザー名とパスワードに置き換えます。
apiVersion: v1 kind: Secret metadata: name: contoso-secrets type: Opaque data: username: "<YOUR CAMERA USERNAME BASE64 ENCODED>" password: "<YOUR CAMERA PASSWORD BASE64 ENCODED>"
ヒント
Bash プロンプトで base64 のユーザー名とパスワードをエンコードするには、次のコマンドを使用します:
echo -n "<STRING TO ENCODE>" | base64
。既定の Azure IoT Operations 名前空間のクラスターにシークレットを追加するには、次のコマンドを実行します。
kubectl apply -f contoso-secrets.yaml -n azure-iot-operations
Bicep ファイルを使用して資産エンドポイントを作成するには:
以下の環境変数を設定します。
SUBSCRIPTION_ID="<YOUR SUBSCRIPTION ID>" RESOURCE_GROUP="<YOUR AZURE IOT OPERATIONS RESOURCE GROUP>" TARGET_ADDRESS="<YOUR CAMERA RTSP ADDRESS>" AEP_NAME="contoso-rtsp-aep" SECRET_NAME="contoso-secrets"
次のスクリプトを実行します。
# Download the Bicep file wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/media-connector-bicep/aep-media-connector.bicep -O aep-media-connector.bicep # Find the name of your custom ___location CUSTOM_LOCATION_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].extendedLocation.name" -o tsv) # Use the Bicep file to deploy the asset endpoint az deployment group create --subscription $SUBSCRIPTION_ID --resource-group $RESOURCE_GROUP --template-file aep-media-connector.bicep --parameters targetAddress=$TARGET_ADDRESS customLocationName=$CUSTOM_LOCATION_NAME aepName=$AEP_NAME secretName=$SECRET_NAME
次のスニペットは、資産エンドポイントの作成に使用した bicep ファイルを示しています。
metadata description = 'Asset endpoint profile for media connector'
@description('The RTSP endpoint for the media stream.')
param targetAddress string
@description('The name of the custom ___location you are using.')
param customLocationName string
@description('Specifies the name of the asset endpoint resource to create.')
param aepName string
@description('The name of the Kubernetes secret you are using to store the camera credentials.')
param secretName string
/*****************************************************************************/
/* Asset endpoint profile */
/*****************************************************************************/
resource assetEndpoint 'Microsoft.DeviceRegistry/assetEndpointProfiles@2024-11-01' = {
name: aepName
___location: resourceGroup().___location
extendedLocation: {
type: 'CustomLocation'
name: customLocationName
}
properties: {
targetAddress: targetAddress
endpointProfileType: 'Microsoft.Media'
#disable-next-line no-hardcoded-env-urls //Schema required during public preview
additionalConfiguration: '{"@schema":"https://aiobrokers.blob.core.windows.net/aio-media-connector/1.0.0.json"}'
authentication: {
method: 'UsernamePassword'
usernamePasswordCredentials: {
passwordSecretName: '${secretName}/password'
usernameSecretName: '${secretName}/username'
}
}
}
}
前の例では、ユーザー名とパスワードを使用してカメラで認証するように資産エンドポイントを構成します。 Bicep ファイルでは、作成した資産エンドポイントの認証セクションは次の例のようになります。
authentication: {
method: 'UsernamePassword'
usernamePasswordCredentials: {
passwordSecretName: '${secretName}/password'
usernameSecretName: '${secretName}/username'
}
カメラにユーザー名とパスワードが必要ない場合は、次の例に示すように匿名認証を構成します。
authentication: {
method: 'Anonymous'
}
資産の構成
資産を構成する際、datasets.DataPoints
パラメーターは、メディア コネクタがその資産に対して実行するアクションを指定します。 カメラ資産は、次のタスクの種類をサポートしています。
タスクの種類 | 説明 |
---|---|
snapshot-to-mqtt |
カメラからスナップショットをキャプチャし、MQTT トピックに発行します。 |
snapshot-to-fs |
カメラからスナップショットをキャプチャし、ローカル ファイル システムに保存します。 |
clip-to-fs |
カメラからビデオ クリップをキャプチャし、ローカル ファイル システムに保存します。 |
stream-to-rtsp |
カメラからメディア サーバーにライブ ビデオ ストリームを送信します。 |
次の設定を使用すると、個々のタスクを構成できます。
-
autostart
: 資産の開始時にタスクが自動的に開始されるかどうか。 -
realtime
: タスクがリアルタイムで実行されるかどうか。 -
loop
: タスクが継続的に実行されるかどうか。 -
format
: メディア ファイルの形式。 -
fps
: メディア ファイルの 1 秒あたりのフレーム数。 -
audioEnabled
: メディア ファイルに対してオーディオが有効かどうか。 -
duration
: メディア ファイルの期間。
次の例は、タスクの種類ごとに資産をデプロイする方法を示しています。
ヒント
メディア ポッドは、メディア コネクタを使用する資産をデプロイするまで Kubernetes に作成されません。 資産をデプロイする前に kubectl get pods
コマンドを実行しようとすると、メディア ポッドは表示されません。
スナップショットを MQTT へ
カメラからスナップショットをキャプチャし、MQTT トピックに発行する資産を構成するには:
以下の環境変数を設定します。
SUBSCRIPTION_ID="<YOUR SUBSCRIPTION ID>" RESOURCE_GROUP="<YOUR AZURE IOT OPERATIONS RESOURCE GROUP>" AEP_NAME="contoso-rtsp-aep"
次のスクリプトを実行します。
# Download the Bicep file wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/media-connector-bicep/asset-snapshot-to-mqtt.bicep -O asset-snapshot-to-mqtt.bicep # Find the name of your custom ___location CUSTOM_LOCATION_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].extendedLocation.name" -o tsv) # Use the Bicep file to deploy the asset az deployment group create --subscription $SUBSCRIPTION_ID --resource-group $RESOURCE_GROUP --template-file asset-snapshot-to-mqtt.bicep --parameters customLocationName=$CUSTOM_LOCATION_NAME aepName=$AEP_NAME
次のスニペットは、資産の作成に使用した bicep ファイルを示しています。
metadata description = 'Media asset that publishes snapshots to MQTT.'
@description('The name of the custom ___location you are using.')
param customLocationName string
@description('Specifies the name of the asset endpoint resource to use.')
param aepName string
@description('The name of the asset you are creating.')
param assetName string = 'asset-snapshot-to-mqtt'
/*****************************************************************************/
/* Asset */
/*****************************************************************************/
resource asset 'Microsoft.DeviceRegistry/assets@2024-11-01' = {
name: assetName
___location: resourceGroup().___location
extendedLocation: {
type: 'CustomLocation'
name: customLocationName
}
properties: {
assetEndpointProfileRef: aepName
datasets: [
{
name: 'dataset1'
dataPoints: [
{
name: 'snapshot-to-mqtt'
dataSource: 'snapshot-to-mqtt'
dataPointConfiguration: '{"taskType":"snapshot-to-mqtt","autostart":true,"realtime":true,"loop":true,"format":"jpeg","fps":1}'
}
]
}
]
}
}
スナップショットが MQTT ブローカーに発行されていることを確認するには、 mosquitto_sub ツールを使用します。 この例では、Kubernetes クラスター内のポッド内で mosquitto_sub ツールを実行します。
次のコマンドを実行して、クラスター内の MQTT ブローカーとの対話に役立つ mosquitto_pub ツールと mosquitto_sub ツールを含むポッドをデプロイします。
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/quickstarts/mqtt-client.yaml
注意事項
この構成はセキュリティで保護されていません。 運用環境では、この構成を使わないでください。
mqtt-client ポッドが実行されている場合は、次のコマンドを実行して、作成したポッドにシェル環境を作成します。
kubectl exec --stdin --tty mqtt-client -n azure-iot-operations -- sh
mqtt-client ポッドの Bash シェルで、次のコマンドを実行し、 トピックをサブスクライブした
azure-iot-operations/data
ツールを使用して MQTT ブローカーに接続します。mosquitto_sub --host aio-broker --port 18883 --topic "azure-iot-operations/data/#" -V 5 -F '%p' -C 1 --cafile /var/run/certs/ca.crt -D CONNECT authentication-method 'K8S-SAT' -D CONNECT authentication-data $(cat /var/run/secrets/tokens/broker-sat) > image.jpeg
このコマンドは、1 つのメッセージから生のペイロードをキャプチャし、ポッドのファイリング システムで image.jpeg というファイルに保存します。 ポッドのシェル環境を終了するには、「
exit
」と入力します。ポッドからローカル コンピューターにイメージ ファイルをコピーするには、次のコマンドを実行します:
kubectl cp azure-iot-operations/mqtt-client:image.jpeg image.jpeg
資産のテストが完了したら、次のコマンドを実行してそれを削除できます。
az iot ops asset delete -n asset-snapshot-to-mqtt -g $RESOURCE_GROUP
スナップショットをファイル システムへ
カメラからスナップショットをキャプチャしてファイルとして保存するアセットを構成するには:
以下の環境変数を設定します。
SUBSCRIPTION_ID="<YOUR SUBSCRIPTION ID>" RESOURCE_GROUP="<YOUR AZURE IOT OPERATIONS RESOURCE GROUP>" AEP_NAME="contoso-rtsp-aep"
次のスクリプトを実行します。
# Download the Bicep file wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/media-connector-bicep/asset-snapshot-to-fs.bicep -O asset-snapshot-to-fs.bicep # Find the name of your custom ___location CUSTOM_LOCATION_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].extendedLocation.name" -o tsv) # Use the Bicep file to deploy the asset az deployment group create --subscription $SUBSCRIPTION_ID --resource-group $RESOURCE_GROUP --template-file asset-snapshot-to-fs.bicep --parameters customLocationName=$CUSTOM_LOCATION_NAME aepName=$AEP_NAME
次のスニペットは、資産の作成に使用した bicep ファイルを示しています。
metadata description = 'Media asset that saves snapshots to the file system.'
@description('The name of the custom ___location you are using.')
param customLocationName string
@description('Specifies the name of the asset endpoint resource to use.')
param aepName string
@description('The name of the asset you are creating.')
param assetName string = 'asset-snapshot-to-fs'
/*****************************************************************************/
/* Asset */
/*****************************************************************************/
resource asset 'Microsoft.DeviceRegistry/assets@2024-11-01' = {
name: assetName
___location: resourceGroup().___location
extendedLocation: {
type: 'CustomLocation'
name: customLocationName
}
properties: {
assetEndpointProfileRef: aepName
datasets: [
{
name: 'dataset1'
dataPoints: [
{
name: 'snapshot-to-fs'
dataSource: 'snapshot-to-fs'
dataPointConfiguration: '{"taskType":"snapshot-to-fs","autostart":true,"realtime":true,"loop":true,"format":"jpeg","fps":1}'
}
]
}
]
}
}
ファイルは、opc-media-1-...
ポッドのファイル システム内に保存されます。 このポッドのフル ネームを確認するには、次のコマンドを実行します。 次のコマンドでは、既定の Azure IoT Operations 名前空間を使用します。
kubectl get pods -n azure-iot-operations
ファイルを表示するには、ポッドで ls
コマンドを実行します。 次のコマンドの中でポッドのフル ネームを使用します。
kubectl exec aio-opc-media-1-... -n azure-iot-operations -- ls /tmp/azure-iot-operations/data/asset-snapshot-to-fs/snapshots/
資産のテストが完了したら、次のコマンドを実行してそれを削除できます。
az iot ops asset delete -n asset-snapshot-to-fs -g $RESOURCE_GROUP
クリップをファイル システムへ
カメラからクリップをキャプチャしてファイルとして保存するアセットを構成するには:
以下の環境変数を設定します。
SUBSCRIPTION_ID="<YOUR SUBSCRIPTION ID>" RESOURCE_GROUP="<YOUR AZURE IOT OPERATIONS RESOURCE GROUP>" AEP_NAME="contoso-rtsp-aep"
次のスクリプトを実行します。
# Download the Bicep file wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/media-connector-bicep/asset-clip-to-fs.bicep -O asset-clip-to-fs.bicep # Find the name of your custom ___location CUSTOM_LOCATION_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].extendedLocation.name" -o tsv) # Use the Bicep file to deploy the asset az deployment group create --subscription $SUBSCRIPTION_ID --resource-group $RESOURCE_GROUP --template-file asset-clip-to-fs.bicep --parameters customLocationName=$CUSTOM_LOCATION_NAME aepName=$AEP_NAME
次のスニペットは、資産の作成に使用した bicep ファイルを示しています。
metadata description = 'Media asset that saves clips to the file system.'
@description('The name of the custom ___location you are using.')
param customLocationName string
@description('Specifies the name of the asset endpoint resource to use.')
param aepName string
@description('The name of the asset you are creating.')
param assetName string = 'asset-clip-to-fs'
/*****************************************************************************/
/* Asset */
/*****************************************************************************/
resource asset 'Microsoft.DeviceRegistry/assets@2024-11-01' = {
name: assetName
___location: resourceGroup().___location
extendedLocation: {
type: 'CustomLocation'
name: customLocationName
}
properties: {
assetEndpointProfileRef: aepName
datasets: [
{
name: 'dataset1'
dataPoints: [
{
name: 'clip-to-fs'
dataSource: 'clip-to-fs'
dataPointConfiguration: '{"taskType":"clip-to-fs","autostart":true,"realtime":true,"loop":true,"format":"avi","duration":3}'
}
]
}
]
}
}
ファイルは、opc-media-1-...
ポッドのファイル システム内に保存されます。 このポッドのフル ネームを確認するには、次のコマンドを実行します。 次のコマンドでは、既定の Azure IoT Operations 名前空間を使用します。
kubectl get pods -n azure-iot-operations
ファイルを表示するには、ポッドで ls
コマンドを実行します。 次のコマンドの中でポッドのフル ネームを使用します。
kubectl exec aio-opc-media-1-... -n azure-iot-operations -- ls /tmp/azure-iot-operations/data/asset-clip-to-fs/clips/
資産のテストが完了したら、次のコマンドを実行してそれを削除できます。
az iot ops asset delete -n asset-clip-to-fs -g $RESOURCE_GROUP
ストリームを RTSP へ
カメラからメディア サーバーにビデオ ストリームを転送するアセットを構成するには:
前の手順でメディア サーバーを展開したときに、メディア サーバーの IP アドレスを書き留めた。
以下の環境変数を設定します。
SUBSCRIPTION_ID="<YOUR SUBSCRIPTION ID>" RESOURCE_GROUP="<YOUR AZURE IOT OPERATIONS RESOURCE GROUP>" MEDIA_SERVER_ADDRESS="<YOUR MEDIA SERVER IP ADDRESS>" AEP_NAME="contoso-rtsp-aep"
次のスクリプトを実行します。
# Download the Bicep file wget https://raw.githubusercontent.com/Azure-Samples/explore-iot-operations/main/samples/media-connector-bicep/asset-stream-to-rtsp.bicep -O asset-stream-to-rtsp.bicep # Find the name of your custom ___location CUSTOM_LOCATION_NAME=$(az iot ops list -g $RESOURCE_GROUP --query "[0].extendedLocation.name" -o tsv) # Use the Bicep file to deploy the asset az deployment group create --subscription $SUBSCRIPTION_ID --resource-group $RESOURCE_GROUP --template-file asset-stream-to-rtsp.bicep --parameters customLocationName=$CUSTOM_LOCATION_NAME aepName=$AEP_NAME mediaServerAddress=$MEDIA_SERVER_ADDRESS
次のスニペットは、資産の作成に使用した bicep ファイルを示しています。
metadata description = 'Media asset that streams RTSP to a media server.'
@description('The name of the custom ___location you are using.')
param customLocationName string
@description('Specifies the name of the asset endpoint resource to use.')
param aepName string
@description('The name of the asset you are creating.')
param assetName string = 'asset-stream-to-rtsp'
@description('The IP address of your media server.')
param mediaServerAddress string
/*****************************************************************************/
/* Asset */
/*****************************************************************************/
resource asset 'Microsoft.DeviceRegistry/assets@2024-11-01' = {
name: assetName
___location: resourceGroup().___location
extendedLocation: {
type: 'CustomLocation'
name: customLocationName
}
properties: {
assetEndpointProfileRef: aepName
datasets: [
{
name: 'dataset1'
dataPoints: [
{
name: 'stream-to-rtsp'
dataSource: 'stream-to-rtsp'
dataPointConfiguration: '{"taskType":"stream-to-rtsp","autostart":true,"realtime":true,"loop":true,"media_server_address":"${mediaServerAddress}"}'
}
]
}
]
}
}
メディア ストリームを表示するには、次のような URL を使用します: http://<YOUR KUBERNETES CLUSTER IP ADDRESS>:8888/azure-iot-operations/data/asset-stream-to-rtsp
。
ヒント
Codespaces 内で Azure IoT Operations を実行している場合は、次のコマンドを実行して、メディア サーバーをローカル コンピューターにポート転送します: kubectl port-forward service/media-server-public 8888:8888 -n media-server
。
ヒント
仮想マシンで Azure IoT 操作を実行している場合は、ファイアウォールで受信アクセス用にポート 8888 が開いていることを確認します。
メディア サーバーは、資産からの接続とストリームの作成をログに記録します。
2025/02/20 15:31:10 INF [RTSP] [conn <INTERNAL IP ADDRESS OF ASSET>:41384] opened
2025/02/20 15:31:10 INF [RTSP] [session 180ce9ad] created by <INTERNAL IP ADDRESS OF ASSET>:41384
2025/02/20 15:31:10 INF [RTSP] [session 180ce9ad] is publishing to path 'azure-iot-operations/data/asset-stream-to-rtsp', 2 tracks (H264, LPCM)
2025/02/20 15:31:18 INF [HLS] [muxer azure-iot-operations/data/asset-stream-to-rtsp] created (requested by <IP ADDRESS OF EXTERNAL CLIENT>:16831)
2025/02/20 15:31:18 WAR [HLS] [muxer azure-iot-operations/data/asset-stream-to-rtsp] skipping track 2 (LPCM)
2025/02/20 15:31:18 INF [HLS] [muxer azure-iot-operations/data/asset-stream-to-rtsp] is converting into HLS, 1 track (H264)
資産のテストが完了したら、次のコマンドを実行してそれを削除できます。
az iot ops asset delete -n asset-stream-to-rtsp -g $RESOURCE_GROUP