第 2 步:编写并检查代码 - Amazon Kinesis Video Streams
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

第 2 步:编写并检查代码

C++ 创建者库过程的这一部分中,您需要在 C++ 测试框架中检查该代码(tst/ProducerTestFixture.h 和其他文件)。您在上一部分中已下载该代码。

平台独立的 C++ 示例演示了以下编码模式:

  • 创建实例KinesisVideoProducer以访问 Kinesis Video Streams。

  • 创建 KinesisVideoStream 的实例。 Amazon Web Services 账户 如果同名视频流尚不存在,则会在你中创建 Kinesis 视频流。

  • 对于每个数据帧,当其可用时,对 KinesisVideoStream 调用 putFrame 以将其发送到流。

以下各节提供了有关此编码模式的更多信息。

创建的实例 KinesisVideoProducer

您可以通过调用 KinesisVideoProducer::createSync 方法来创建 KinesisVideoProducer 对象。以下示例在 ProducerTestFixture.h 文件中创建 KinesisVideoProducer

kinesis_video_producer_ = KinesisVideoProducer::createSync(move(device_provider_), move(client_callback_provider_), move(stream_callback_provider_), move(credential_provider_), defaultRegion_);

createSync 方法采用以下参数:

  • 一个 DeviceInfoProvider 对象,此对象返回一个包含有关设备或存储配置的信息的 DeviceInfo 对象。

    注意

    您可以使用 deviceInfo.storageInfo.storageSize 参数配置内容存储大小。您的内容流共享内容存储。要确定存储大小要求,请将平均帧大小乘以为所有流存储最大持续时间的帧数。然后再乘以 1.2(考虑碎片整理)。例如,假设您的应用程序具有以下配置:

    • 三个流

    • 3 分钟的最大持续时间

    • 每个流为 30 帧/秒 (FPS)

    • 每个帧的大小为 10000 KB

    此应用程序的内容存储要求为 3(流)* 3(分钟)* 60(一分钟内的秒)* 10000(kb)* 1.2(碎片整理余量)= 194.4 Mb ~ 200 Mb

  • 一个 ClientCallbackProvider 对象,此对象返回报告客户端特定的事件的函数指针。

  • 一个 StreamCallbackProvider 对象,此对象返回在发生流特定的事件时将回调的函数指针。

  • 一个CredentialProvider对象,它提供对 Amazon 凭证环境变量的访问权限。

  • Amazon Web Services 区域 (“us-west-2”)。从区域确定服务终端节点。

创建的实例 KinesisVideoStream

您可以通过调用带 StreamDefinition 参数的 KinesisVideoProducer::CreateStream 方法来创建 KinesisVideoStream 对象。该示例在 ProducerTestFixture.h 文件中创建 KinesisVideoStream,轨道类型为视频,轨道 ID 为 1:

auto stream_definition = make_unique<StreamDefinition>(stream_name, hours(2), tags, "", STREAMING_TYPE_REALTIME, "video/h264", milliseconds::zero(), seconds(2), milliseconds(1), true, true, true); return kinesis_video_producer_->createStream(move(stream_definition));

StreamDefinition 对象具有以下字段:

  • 流名称。

  • 数据保留期。

  • 流的标记。使用者应用程序可使用这些标记来查找正确的流或获取有关流的更多信息。也可以在 Amazon Web Services Management Console中查看这些标记。

  • Amazon KMS 直播的加密密钥。有关更多信息,请参阅对 Kinesis Video Streams 使用服务器端加密

  • 流式处理类型。目前唯一有效的值是 STREAMING_TYPE_REALTIME

  • 媒体内容类型。

  • 媒体延迟。当前未使用此值,应将其设置为 0。

  • 每个片段的播放持续时间。

  • 媒体时间码标度。

  • 媒体是否使用关键帧片段。

  • 媒体是否使用时间码。

  • 媒体是否使用绝对片段时间。

在 Kinesis 视频流中添加音轨

您可以使用以下的 addTrack 方法将音轨详细信息添加到视频轨道流定义中 StreamDefinition:

stream_definition->addTrack(DEFAULT_AUDIO_TRACKID, DEFAULT_AUDIO_TRACK_NAME, DEFAULT_AUDIO_CODEC_ID, MKV_TRACK_INFO_TYPE_AUDIO);

addTrack 方法需要以下参数:

  • 曲目 ID(作为音频的 ID)。该值应为唯一的非零值。

  • 用户定义的轨道名称(例如,音轨的 “音频”)。

  • 此曲目的编解码器 ID(例如,音轨 “A_AAC”)。

  • 轨道类型(例如,使用 MKV_TRACK_INFO_TYPE_AUDIO 的枚举值作为音频)。

如果有用于音轨的编解码器专用数据,可在调用 addTrack 函数时传递。您也可以在中调用 start 方法的同时在创建 KinesisVideoStream 对象之后发送编解码器的私有数据。 KinesisVideoStream

在 Kinesis 视频流中放一帧

你可以使用将媒体放入 Kinesis 视频流KinesisVideoStream::putFrame,传入一个包含标题和媒体数据的Frame对象。此示例调用 ProducerApiTest.cpp 文件中的 putFrame

frame.duration = FRAME_DURATION_IN_MICROS * HUNDREDS_OF_NANOS_IN_A_MICROSECOND; frame.size = SIZEOF(frameBuffer_); frame.frameData = frameBuffer_; MEMSET(frame.frameData, 0x55, frame.size); while (!stop_producer_) { // Produce frames timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::system_clock::now().time_since_epoch()).count() / DEFAULT_TIME_UNIT_IN_NANOS; frame.index = index++; frame.decodingTs = timestamp; frame.presentationTs = timestamp; // Key frame every 50th frame.flags = (frame.index % 50 == 0) ? FRAME_FLAG_KEY_FRAME : FRAME_FLAG_NONE; ... EXPECT_TRUE(kinesis_video_stream->putFrame(frame));
注意

上一个 C++ 创建者示例发送测试数据缓冲区。在实际应用中,您应从媒体源 (例如摄像机) 的帧数据中获取帧缓冲区和大小。

Frame 对象具有以下字段:

  • 帧索引。这应是一个单调递增的值。

  • 与帧关联的标记。例如,如果编码器已配置为生成关键帧,则将为此帧分配 FRAME_FLAG_KEY_FRAME 标记。

  • 解码时间戳。

  • 演示时间戳。

  • 帧的持续时间 (最多 100 ns)。

  • 帧大小 (以字节为单位)。

  • 帧数据。

有关帧格式的更多信息,请参阅 Kinesis Video Streams 数据模型

将 a 放 KinesisVideoFrame 入特定的曲目中 KinesisVideoStream

您可以使用该 PutFrameHelper 类将帧数据放入特定的轨道中。首先,调用 getFrameData Buffer 以获取指向其中一个预先分配的缓冲区的指针,以填充数据。 KinesisVideoFrame 然后,您可以调用 putFrameMulti Track 来发送, KinesisVideoFrame 同时发送布尔值以指示帧数据的类型。如果是视频数据,请使用 true;如果帧包含音频数据,则使用 false。T putFrameMulti rack 方法使用排队机制来确保 MKV 片段保持单调递增的帧时间戳,并且任意两个片段不会重叠。例如,片段第一帧的 MKV 时间戳应始终大于前一片段最后一帧的 MKV 时间戳。

PutFrameHelper 有以下字段:

  • 队列中音频帧的最大数量。

  • 队列中视频帧的最大数量。

  • 为单个音频帧分配的大小。

  • 为单个视频帧分配的大小。

指标和指标记录

C++ 创建者开发工具包包括指标和指标日志记录的功能。

您可以使用getKinesisVideoMetricsgetKinesisVideoStreamMetrics API 操作来检索有关 Kinesis Video Streams 和您的活跃直播的信息。

以下代码来自 kinesis-video-pic/src/client/include/com/amazonaws/kinesis/video/client/Include.h 文件。

/** * Gets information about the storage availability. * * @param 1 CLIENT_HANDLE - the client object handle. * @param 2 PKinesisVideoMetrics - OUT - Kinesis Video metrics to be filled. * * @return Status of the function call. */ PUBLIC_API STATUS getKinesisVideoMetrics(CLIENT_HANDLE, PKinesisVideoMetrics); /** * Gets information about the stream content view. * * @param 1 STREAM_HANDLE - the stream object handle. * @param 2 PStreamMetrics - Stream metrics to fill. * * @return Status of the function call. */ PUBLIC_API STATUS getKinesisVideoStreamMetrics(STREAM_HANDLE, PStreamMetrics);

getKinesisVideoMetrics 填入的 PClientMetrics 对象包含以下信息:

  • contentStoreSize:内容存储的总大小(用于存储流数据的内存),以字节为单位。

  • contentStoreAvailable大小:内容存储中的可用内存,以字节为单位。

  • contentStoreAllocated大小:内容存储中分配的内存。

  • totalContentViews大小:用于内容视图的总内存。内容视图是内容存储中一系列信息的索引。

  • totalFrameRate:所有活动直播中每秒的总帧数。

  • totalTransferRate:所有流中发送的每秒总位数 (bps)。

getKinesisVideoStreamMetrics 填入的 PStreamMetrics 对象包含以下信息:

  • currentViewDuration:内容视图的头部(对帧进行编码时)和当前位置(当帧数据发送到 Kinesis Video Streams Video Streams 时)之间的差异,以 100 ns 为单位。

  • overallViewDuration:内容视图的头部(对帧进行编码时)与尾部(当帧从内存中刷新时,要么是因为超出了为内容视图分配的总空间,要么是因为收到来自 Kinesis Video Streams 的PersistedAck消息,并且已知保留的帧被刷新)之间的差异,以 100 ns 为单位。

  • currentViewSize:内容视图从头部(对帧进行编码时)到当前位置(帧发送到 Kinesis Video Streams 时)的大小(以字节为单位)。

  • overallViewSize:内容视图的总大小(以字节为单位)。

  • currentFrameRate:上次测量的直播速率,以每秒帧数为单位。

  • currentTransferRate:上次测量的流速率,以每秒字节数为单位。

分解

如果要发送缓冲区中的剩余字节并等待 ACK,您可以使用 stopSync

kinesis_video_stream->stopSync();

或者,您可以调用 stop 来结束流式传输:

kinesis_video_stream->stop();

停止流式传输后,您可以通过调用以下 API 释放流:

kinesis_video_producer_->freeStream(kinesis_video_stream);

后续步骤

步骤 3:运行并验证代码