Si vous envisagez de créer une plate-forme de contenu généré par l'utilisateur (UGC) avec Amazon Interactive Video Service (Amazon IVS), vous souhaiterez probablement intégrer une sorte de tableau de bord pour surveiller la santé des flux en direct de votre utilisateur. Comme toujours, la documentation fournit un excellent aperçu de la surveillance de la santé des flux.
Dans cet article, nous irons un peu plus loin et montrerons quelques exemples sur la façon de récupérer des sessions de flux et de récupérer des métriques de santé pour un flux en direct à partir d'Amazon CloudWatch. En prime, nous chercherons également à générer quelques graphiques utiles qui peuvent être ajoutés à votre tableau de bord UGC pour une surveillance de la santé en temps réel.
Les métriques de santé du flux Amazon IVS sont stockées dans Amazon CloudWatch. Pour récupérer ces métriques avec le kit AWS SDK pour JavaScript v3, nous pouvons utiliser la documentation de la méthode GetMetricDataCommand
du client Amazon CloudWatch ( @aws-sdk/client-cloudwatch
).
Cette méthode s'attend à ce que quelques propriétés filtrent les métriques sur une période et un canal Amazon IVS spécifiques, comme nous le verrons ci-dessous.
Remarque : cet article se concentrera sur la récupération des métriques de santé du flux avec le SDK Amazon CloudWatch, mais les métriques de santé vitales du flux peuvent également être observées via Amazon EventBridge afin que vous puissiez prendre toutes les mesures nécessaires lorsqu'un flux devient défectueux ou que les limites de service sont dépassées. Reportez-vous à la documentation pour plus d'informations.
Étant donné que nous avons besoin d'un StartTime
et EndTime
pour récupérer les métriques de santé, il est logique de récupérer une liste des sessions de flux récentes via le client Amazon IVS ( @aws-sdk/client-ivs
). Pour ce faire, nous pouvons utiliser ListStreamSessionsCommand
( docs ) et lui transmettre l' ARN
du canal qui nous intéresse.
import { IvsClient, ListStreamSessionsCommand } from "@aws-sdk/client-ivs"; const ivsClient = new IvsClient(); const listStreamSessionsInput = { channelArn: process.env.DEMO_CHANNEL_ARN, maxResults: 3, // default=100 }; const listStreamSessionsRequest = new ListStreamSessionsCommand(listStreamSessionsInput); const listStreamSessionsResponse = await ivsClient.send(listStreamSessionsRequest); console.log(listStreamSessionsResponse)
La réponse de ListStreamSessionsCommand
renverra un objet. La clé streamSessions
de cet objet contient un tableau de sessions de flux, triées par session la plus récente. Les sessions actives sont indiquées par l'absence de endTime
.
{ "$metadata": { "httpStatusCode": 200, "requestId": "[redacted]", "cfId": "[redacted]", "attempts": 1, "totalRetryDelay": 0 }, "nextToken": "AQI...[redacted]...A==", "streamSessions": [ { "endTime": undefined, "hasErrorEvent": false, "startTime": "2023-01-20T14:30:11.000Z", "streamId": "st-[redacted]" }, { "endTime": "2023-01-19T16:12:37.000Z", "hasErrorEvent": false, "startTime": "2023-01-19T16:12:29.000Z", "streamId": "st-[redacted]" }, { "endTime": "2023-01-19T16:12:25.000Z", "hasErrorEvent": false, "startTime": "2023-01-19T16:12:22.000Z", "streamId": "st-[redacted]" } ] }
À ce stade, nous avons pu utiliser ces horodatages pour récupérer nos métriques de flux. Cependant, il peut être utile de saisir un peu plus de détails, tels que la configuration d'ingestion audio et vidéo. Pour récupérer ces informations, nous pouvons utiliser GetStreamSessionCommand
( docs ). Cette méthode attend l' ARN
et un streamId
que nous avons déjà obtenu dans le résultat ci-dessus.
import { IvsClient, GetStreamSessionCommand } from "@aws-sdk/client-ivs"; import util from "node:util"; const ivsClient = new IvsClient(); const getStreamSessionInput = { channelArn: process.env.DEMO_CHANNEL_ARN, streamId: 'st-[redacted]' }; const getStreamSessionRequest = new GetStreamSessionCommand(getStreamSessionInput); const getStreamSessionResponse = await ivsClient.send(getStreamSessionRequest); console.log( util.inspect(getStreamSessionResponse, false, null, true) );
La méthode GetStreamSessionCommand
renvoie des informations sur la session (dans ce cas, un flux en direct actif). Notez que ingestConfiguration
contient des éléments pratiques tels que le codec, le débit binaire, la fréquence d'images, etc. L'objet truncatedEvents
contient tous les événements qui ont été déclenchés pour ce flux particulier.
{ "$metadata": { "httpStatusCode": 200, "requestId": "[redacted]", "cfId": "[redacted]", "attempts": 1, "totalRetryDelay": 0 }, "streamSession": { "channel": { "arn": "[redacted]", "authorized": false, "ingestEndpoint": "[redacted]", "latencyMode": "LOW", "name": "demo-channel", "playbackUrl": "[redacted]", "recordingConfigurationArn": "[redacted]", "type": "STANDARD" }, "ingestConfiguration": { "audio": { "channels": 2, "codec": "mp4a.40.2", "sampleRate": 48000, "targetBitrate": 128000 }, "video": { "avcLevel": "3.1", "avcProfile": "Baseline", "codec": "avc1.42C01F", "encoder": "", "targetBitrate": 8500000, "targetFramerate": 30, "videoHeight": 1080, "videoWidth": 1920 } }, "recordingConfiguration": { "arn": "[redacted]", "destinationConfiguration": { "s3": { "bucketName": "[redacted]" } }, "state": "ACTIVE" }, "startTime": "2023-01-20T14:30:11.000Z", "streamId": "st-[redacted]", "truncatedEvents": [ { "eventTime": "2023-01-20T14:30:19.000Z", "name": "Recording Start", "type": "IVS Recording State Change" }, { "eventTime": "2023-01-20T14:30:18.000Z", "name": "Stream Start", "type": "IVS Stream State Change" }, { "eventTime": "2023-01-20T14:30:11.000Z", "name": "Session Created", "type": "IVS Stream State Change" } ] } }
Si vous prévoyez d'intégrer des données de métrique de santé de flux dans votre application, vous utiliserez l'un des kits SDK AWS. Mais, si vous cherchez simplement à afficher les données de métrique de santé de manière moins fréquente, vous pouvez les afficher via la console AWS. Pour afficher les métriques de santé liées à Amazon IVS, sélectionnez Toutes les métriques , puis IVS via la console Amazon CloudWatch.
Nous pouvons parcourir les données métriques en choisissant une dimension.
Par exemple, pour afficher les métriques par canal, sélectionnez Par canal , puis choisissez la période souhaitée, le canal et la métrique.
Nous sommes prêts à utiliser le kit SDK Amazon CloudWatch pour extraire les données de métrique de santé d'un canal en fonction des heures de début et de fin du flux. GetMetricDataCommand
attend un objet GetMetricDataCommandInput
( docs ).
Comme mentionné ci-dessus, cet objet possède les propriétés StartTime
et EndTime
, ainsi qu'une propriété MetricDataQueries
qui doit contenir un tableau de requêtes en fonction des mesures de santé que nous souhaitons récupérer. Il y a quatre propriétés liées à la santé du canal Amazon IVS qui nous intéressent ici : IngestAudioBitrate
, IngestVideoBitrate
, IngestFramerate
et KeyframeInterval
. Nous allons construire un tableau pour chaque métrique, en utilisant AWS/IVS
comme Namespace
et en filtrant sur un canal spécifique en saisissant la partie de l'ARN du canal suivant /
.
import { CloudWatchClient, GetMetricDataCommand } from "@aws-sdk/client-cloudwatch"; const cloudWatchClient = new CloudWatchClient();
const getMetrics = async (arn, startTime, endTime) => { const streamHealthMetrics = [ "IngestAudioBitrate", "IngestVideoBitrate", "IngestFramerate", "KeyframeInterval" ]; const metricDataQueries = streamHealthMetrics.map((metric) => { return { Id: metric.toLowerCase(), MetricStat: { Metric: { MetricName: metric, Namespace: "AWS/IVS", Dimensions: [{ Name: "Channel", Value: arn.split("/")[1] }] }, Period: 5, Stat: "Average", } } }); const getMetricDataInput = { StartTime: startTime, EndTime: endTime, MetricDataQueries: metricDataQueries, MaxDatapoints: 100 }; const getMetricDataRequest = new GetMetricDataCommand(getMetricDataInput); const getMetricDataResponse = await cloudWatchClient.send(getMetricDataRequest); return getMetricDataResponse; }; // get metrics for a session const metrics = await getMetrics( process.env.DEMO_CHANNEL_ARN, new Date('2023-01-20T14:30:11.000Z'), new Date('2023-01-20T14:49:15.000Z') );
Le résultat de l'appel GetMetricDataCommand
ressemblera à la sortie suivante :
{ "$metadata": { "httpStatusCode": 200, "requestId": "[redacted]", "attempts": 1, "totalRetryDelay": 0 }, "MetricDataResults": [ { "Id": "ingestaudiobitrate", "Label": "IngestAudioBitrate", "Timestamps": [ "2023-01-20T14:49:10.000Z" ], "Values": [ 31049.333057821852 ], "StatusCode": "PartialData" }, { "Id": "ingestvideobitrate", "Label": "IngestVideoBitrate", "Timestamps": [ "2023-01-20T14:49:10.000Z" ], "Values": [ 3497988.4859657455 ], "StatusCode": "PartialData" }, { "Id": "ingestframerate", "Label": "IngestFramerate", "Timestamps": [ "2023-01-20T14:49:10.000Z" ], "Values": [ 29.143738984724312 ], "StatusCode": "PartialData" }, { "Id": "keyframeinterval", "Label": "KeyframeInterval", "Timestamps": [ "2023-01-20T14:49:10.000Z" ], "Values": [ 2.007629037 ], "StatusCode": "PartialData" } ], "NextToken": "[redacted]", "Messages": [] }
Il est important de noter que les métriques Amazon CloudWatch sont cumulées dans le temps, de sorte que la résolution granulaire diminue avec le temps.
Si nous devions exécuter la même requête avec une plage de temps plus longue (en fonction de la disponibilité des données comme mentionné ci-dessus), nous pouvons filtrer et regrouper les données en fonction d'une seule métrique et utiliser ce résultat pour afficher un joli graphique des valeurs. .
const videoBitrateMetrics = metrics .MetricDataResults .find((metric) => metric.Id === 'ingestvideobitrate'); const bitrateData = []; videoBitrateMetrics.Timestamps .sort((a, b) => new Date(a) > new Date(b) ? 1 : -1) .forEach((t, i) => { bitrateData.push({ timestamp: t, bitrate: videoBitrateMetrics.Values[i] / 1000, }) }); console.log(JSON.stringify(bitrateData));
Cela produit un tableau d'objets qui ressemble à ce qui suit :
[ { "timestamp": "2023-01-20T14:47:05.000Z", "bitrate": 3497.9884859657454 } ]
Nous pouvons utiliser ces données filtrées pour créer de belles visualisations pour nos tableaux de bord UGC. Quelques exemples rapides :
Une autre option super cool consiste à générer les graphiques directement via le SDK Amazon CloudWatch. Consultez la documentation pour plus de détails. Voici un exemple de génération d'un graphique pour la métrique IngestFramerate
via le kit SDK Amazon CloudWatch.
const getMetricImage = async (arn, startDate, endDate) => { const cloudWatchClient = new CloudWatchClient(); const getMetricWidgetImageInput = { MetricWidget: JSON.stringify({ metrics: [ [ "AWS/IVS", "IngestFramerate", "Channel", arn.split("/")[1] ] ], start: startDate, end: endDate, period: 5 }) }; const getMetricWidgetImageRequest = new GetMetricWidgetImageCommand(getMetricWidgetImageInput); const getMetricWidgetImageResponse = await cloudWatchClient.send(getMetricWidgetImageRequest); return getMetricWidgetImageResponse; }; const metricImage = await getMetricImage( process.env.DEMO_CHANNEL_ARN, new Date('2023-01-20T14:30:11.000Z'), new Date('2023-01-20T14:49:15.000Z') );
L'appel à GetMetricWidgetImageCommand
renvoie un objet JSON qui ressemble à ceci :
{ '$metadata': { httpStatusCode: 200, requestId: '[redacted]', extendedRequestId: undefined, cfId: undefined, attempts: 1, totalRetryDelay: 0 }, MetricWidgetImage: Uint8Array(36660) [ 137, 80, 78, ... 36560 more items ] }
Nous pouvons convertir le Uint8Array
en une chaîne base64 :
const buffer = Buffer.from(metricImage.MetricWidgetImage); console.log(buffer.toString('base64'));
Qui renvoie une chaîne base64 :
iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAIAAAD9V4nPA...
Cela peut être utilisé pour rendre une image :
Nous pouvons même combiner plusieurs métriques dans une seule image en passant des métriques supplémentaires à GetMetricWidgetImageCommand
.
Dans cet article, nous avons examiné comment récupérer des mesures de santé pour un flux en direct Amazon IVS et les afficher sous forme de graphiques. Restez à l'écoute pour un prochain article dans lequel nous approfondirons certaines des autres mesures disponibles via Amazon CloudWatch liées aux spectateurs de flux en direct.