本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
步骤 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 函数时传递。您还可以在创建KinesisVideoStream对象后发送编解码器的私有数据,同时在中调用 start 方法。KinesisVideoStream
在 Kinesis 视频流中存储 FRAES
您可以使用KinesisVideoStream::putFrame
传入包含标题和媒体数据的Frame
对象将媒体放入 Kinesis 视频流。此示例调用 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。putFrameMultiTrack 方法使用排队机制来确保 MKV 片段保持单调递增的帧时间戳,并且任意两个片段不重叠。例如,片段第一帧的 MKV 时间戳应始终大于前一片段最后一帧的 MKV 时间戳。
PutFrameHelper具有以下字段:
-
队列中的最大音频帧数。
-
队列中的最大视频帧数。
-
为单个音频帧分配的大小。
-
为单个视频帧分配的大小。
指标和指标日志
C++ 创建者开发工具包包括指标和指标日志记录的功能。
您可以使用getKinesisVideoMetrics
和 getKinesisVideoStreamMetrics
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 时)之间的差值,以 100 纳秒为单位。
-
overallViewDuration:内容视图的头部(对帧进行编码时)与尾部(当帧从内存中刷新时,要么是因为超过了为内容视图分配的总空间,要么是因为从 Kinesis Video Streams 接收到
PersistedAck
消息,并且已知存在的帧被刷新)之间的差异(以 100 纳秒为单位)。 -
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);