View a markdown version of this page

编写并检查代码 - Amazon Kinesis Video Streams

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

编写并检查代码

在本节中使用 C++ 制作者库,您将研究 C++ 测试工具(tst/ProducerTestFixture.h和其他文件)中的代码。您在上一部分中已下载该代码。

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

  • 创建KinesisVideoProducer用于访问 Kinesis Video Streams 的实例。

  • 创建 KinesisVideoStream 的实例。 AWS 账户 如果尚不存在同名视频流,则会在您的中创建 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对象,它提供对 AWS 凭据环境变量的访问权限。

  • AWS 区域 (“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 对象具有以下字段:

  • 流名称。

  • 数据保留期。

  • 流的标记。使用者应用程序可使用这些标记来查找正确的流或获取有关流的更多信息。也可以在 AWS 管理控制台中查看这些标记。

  • AWS KMS 直播的加密密钥。有关更多信息,请参阅 Kinesis 视频流中的数据保护

  • 流式处理类型。目前唯一有效的值是 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(与音频相同)。该值应为唯一的非零值。

  • User-defined 曲目名称(例如,音轨的 “音频”)。

  • 此曲目的编解码器 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 视频流数据模型

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

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

PutFrameHelper 包含以下字段:

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

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

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

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

访问指标和指标日志

C++ 生产者 SDK 包含指标和指标记录功能。

您可以使用getKinesisVideoMetricsgetKinesisVideoStreamMetrics API 操作来检索有关 Kinesis 视频流和活动直播的信息。

以下代码来自 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 对象包含以下信息:

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

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

  • 内容StoreAllocatedSize:内容存储中分配的内存。

  • 总计ContentViewsSize:用于内容视图的总内存。内容视图是内容存储库中一系列信息的索引。

  • 总计FrameRate:所有活动流中每秒的总帧数。

  • 总计TransferRate:所有流中发送的每秒总比特数 (bps)。

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

  • 当前ViewDuration:内容视图的标头(对帧进行编码时)和当前位置(将帧数据发送到 Kinesis 视频流时)之间的差异(以 100 ns 为单位)。

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

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

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

  • currentFrameRate:最后一次测量的数据流速率,以每秒帧数为单位。

  • cur TransferRate rent:最后一次测量的流速率,以字节每秒为单位。

分解

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

kinesis_video_stream->stopSync();

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

kinesis_video_stream->stop();

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

kinesis_video_producer_->freeStream(kinesis_video_stream);