Как получить показатели работоспособности для Amazon IVS Live Stream и отобразить их в виде диаграмм

Как получить показатели работоспособности для Amazon IVS Live Stream и отобразить их в виде диаграмм

29 марта 2023 г.

Если вы планируете создать платформу пользовательского контента (UGC) с помощью Amazon Interactive Video Service (Amazon IVS), вам, вероятно, потребуется интегрировать какую-либо панель инструментов для мониторинга состояния прямых трансляций ваших пользователей. . Как всегда, в документации представлен отличный обзор мониторинга состояния потока.

В этом посте мы пойдем немного дальше и покажем несколько примеров того, как получить сеансы потоковой передачи и получить показатели работоспособности для прямой трансляции из Amazon CloudWatch. В качестве дополнительного бонуса мы также рассмотрим создание нескольких полезных диаграмм, которые можно добавить на панель пользовательского контента для мониторинга состояния в реальном времени.

Показатели работоспособности потоков Amazon IVS хранятся в Amazon CloudWatch. Чтобы получить эти показатели с помощью AWS SDK для JavaScript версии 3, мы можем использовать метод GetMetricDataCommand docs из клиента Amazon CloudWatch (@aws-sdk/client-cloudwatch).

Этот метод предполагает, что несколько свойств будут фильтровать метрики по определенному периоду времени и каналу Amazon IVS, как мы увидим ниже.

<цитата>

Примечание. В этом посте основное внимание будет уделено получению показателей работоспособности потока с помощью SDK Amazon CloudWatch, но жизненно важные показатели работоспособности потока также можно отслеживать с помощью Amazon EventBridge, чтобы вы могли предпринять любые необходимые действия, когда поток становится недоступным. нарушены неработоспособные или лимиты обслуживания. Дополнительные сведения см. в документации.

Получение сеансов Amazon IVS Stream

Поскольку для получения показателей работоспособности нам нужны 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 (документы). Этот метод ожидает 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 SDK. Но если вы просто хотите реже просматривать данные показателей работоспособности, вы можете просмотреть их через консоль AWS. Чтобы просмотреть показатели работоспособности, связанные с Amazon IVS, выберите Все показатели, а затем IVS в консоли Amazon CloudWatch.

Мы можем просмотреть данные показателей, выбрав параметр.

Например, чтобы просмотреть показатели по каналам, выберите По каналам и выберите нужный период времени, канал и показатель.

Получение показателей работоспособности потока с помощью SDK

Мы готовы использовать Amazon CloudWatch SDK для извлечения данных показателей работоспособности для канала на основе времени начала и окончания потока. GetMetricDataCommand ожидает объект GetMetricDataCommandInput (документы).

Как упоминалось выше, этот объект имеет свойства 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 со временем накапливаются, поэтому детализированное разрешение со временем снижается.

* 1-секундные метрики доступны в течение 3 часов. * 60-секундные метрики доступны в течение 15 дней. * 5-минутные метрики доступны в течение 63 дней. * Показатели за 1 час доступны в течение 455 дней (15 месяцев).

Если бы мы выполнили тот же запрос с большим временным диапазоном (в зависимости от доступности данных, как указано выше), мы могли бы отфильтровать и сгруппировать данные на основе одной метрики и использовать этот результат для отображения красивой диаграммы значений. .

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
  }
]

Мы можем использовать эти отфильтрованные данные для создания красивых визуализаций для наших информационных панелей пользовательского контента. Несколько быстрых примеров:

Битрейт загрузки видео

Битрейт загружаемого аудио

Частота кадров:

Интервал ключевого кадра:

Создание изображений диаграмм с помощью Amazon CloudWatch SDK

Еще один отличный вариант — создавать диаграммы напрямую с помощью Amazon CloudWatch SDK. Подробнее см. в документации. Вот пример создания диаграммы для метрики IngestFramerate с помощью Amazon CloudWatch SDK.

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, связанные со зрителями прямых трансляций.


Оригинал