如果您计划使用 Amazon Interactive Video Service (Amazon IVS) 构建用户生成的内容 (UGC) 平台,那么您可能希望集成某种仪表板来监控用户直播流的健康状况。一如既往,该文档提供了监控流健康状况的重要概述。
在这篇文章中,我们将更深入地展示一些示例,说明如何检索流会话,以及如何从 Amazon CloudWatch 检索实时流的运行状况指标。作为额外的奖励,我们还将着眼于生成一些有用的图表,这些图表可以添加到您的 UGC 仪表板以进行实时健康监控。
Amazon IVS 流运行状况指标存储在 Amazon CloudWatch 中。要使用 AWS SDK for JavaScript v3 检索这些指标,我们可以使用 Amazon CloudWatch 客户端 ( @aws-sdk/client-cloudwatch
) 中的GetMetricDataCommand
方法文档。
此方法需要一些属性来筛选特定时间段和 Amazon IVS 通道的指标,如下所示。
注意:本文将重点介绍使用 Amazon CloudWatch SDK 检索流健康指标,但也可以通过 Amazon EventBridge 观察重要的流健康指标,这样您就可以在流变得不健康或违反服务限制时采取任何必要的措施。有关详细信息,请参阅文档。
由于我们需要StartTime
和EndTime
来检索健康指标,因此通过 Amazon IVS 客户端 ( @aws-sdk/client-ivs
) 检索最近的流会话列表是有意义的。为此,我们可以使用ListStreamSessionsCommand
( docs ) 并将我们感兴趣的频道的ARN
传递给它。
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)
来自ListStreamSessionsCommand
的响应将返回一个对象。该对象中的streamSessions
键包含一个流会话数组,按最近的会话排序。活动会话由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]" } ] }
此时,我们可以使用这些时间戳来检索我们的流指标。但是,获取更多细节(例如音频和视频摄取配置)可能会有用。要检索此信息,我们可以使用GetStreamSessionCommand
( docs )。此方法需要ARN
和我们已在上述结果中获得的streamId
。
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) );
GetStreamSessionCommand
方法返回有关会话的信息(在本例中为活动直播流)。请注意, ingestConfiguration
包含一些方便的项目,如编解码器、比特率、帧率等truncatedEvents
对象包含已为此特定流触发的所有事件。
{ "$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" } ] } }
如果您计划将流式运行状况指标数据集成到您的应用程序中,您将使用其中一种 AWS 开发工具包。但是,如果您只是希望以较低频率查看健康指标数据,则可以通过 AWS 控制台查看它们。要查看 Amazon IVS 相关的健康指标,请选择所有指标,然后通过 Amazon CloudWatch 控制台选择IVS 。
例如,要按渠道查看指标,请选择按渠道,然后选择所需的时间段、渠道和指标。
我们已准备好使用 Amazon CloudWatch SDK 根据流的开始和结束时间提取通道的运行状况指标数据。 GetMetricDataCommand
需要一个GetMetricDataCommandInput
对象 ( docs )。
如上所述,该对象具有StartTime
和EndTime
属性,以及一个MetricDataQueries
属性,该属性应包含一组查询,具体取决于我们要检索的健康指标。我们在这里感兴趣的是与 Amazon IVS 通道健康相关的四个属性: IngestAudioBitrate
、 IngestVideoBitrate
、 IngestFramerate
和KeyframeInterval
。我们将为每个指标构建一个数组,使用AWS/IVS
作为Namespace
,并通过获取/
之后的通道 ARN 部分来过滤特定通道。
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') );
调用GetMetricDataCommand
的结果类似于以下输出:
{ "$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": [] }
请务必注意,Amazon CloudWatch 指标会随着时间的推移而累积,因此粒度分辨率会随着时间的推移而降低。
如果我们要在更大的时间范围内运行相同的查询(取决于上述数据的可用性),我们可以根据单个指标过滤和分组数据,并使用该结果呈现一个漂亮的值图表.
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));
这会生成一个对象数组,如下所示:
[ { "timestamp": "2023-01-20T14:47:05.000Z", "bitrate": 3497.9884859657454 } ]
我们可以使用这些过滤后的数据为我们的 UGC 仪表板创建一些漂亮的可视化效果。一些简单的例子:
另一个超酷的选择是直接通过 Amazon CloudWatch SDK 生成图表。查看文档了解详细信息。下面是一个通过 Amazon CloudWatch SDK 为IngestFramerate
指标生成图表的示例。
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') );
对GetMetricWidgetImageCommand
的调用返回如下所示的 JSON 对象:
{ '$metadata': { httpStatusCode: 200, requestId: '[redacted]', extendedRequestId: undefined, cfId: undefined, attempts: 1, totalRetryDelay: 0 }, MetricWidgetImage: Uint8Array(36660) [ 137, 80, 78, ... 36560 more items ] }
我们可以将Uint8Array
转换为 base64 字符串:
const buffer = Buffer.from(metricImage.MetricWidgetImage); console.log(buffer.toString('base64'));
它返回一个 base64 字符串:
iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAIAAAD9V4nPA...
可用于渲染图像:
我们甚至可以通过将附加指标传递给GetMetricWidgetImageCommand
来将多个指标合并到一个图像中。
在本文中,我们研究了如何检索 Amazon IVS 直播流的健康指标并将它们呈现为图表。请继续关注未来的帖子,我们将深入探讨通过 Amazon CloudWatch 提供的与直播观众相关的其他一些指标。