

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

# 使用 C\$1\$1 制作人库
<a name="producer-sdk-cpp"></a>

你可以使用 Amazon Kinesis Video Streams 提供的 C\$1\$1 制作器库来编写应用程序代码，将媒体数据从设备发送到 Kinesis 视频流。

## 物体模型
<a name="producer-sdk-cpp-objectmodel"></a>

C\$1\$1 库提供了以下对象来管理向 Kinesis 视频流发送数据：
+ **KinesisVideoProducer:** 包含有关您的媒体来源和 AWS 凭据的信息，并维护回调以报告 Kinesis Video Streams 事件。
+ **KinesisVideoStream:** 代表 Kinesis 视频流。包含有关视频流参数的信息，例如名称、数据保留期和媒体内容类型。

## 将媒体放入直播中
<a name="producer-sdk-cpp-putframe"></a>

您可以使用 C\$1\$1 库提供的方法（例如`PutFrame`）将数据放入`KinesisVideoStream`对象中。随后，该库将管理数据的内部状态，这可包含以下任务：
+ 执行身份验证。
+ 监视网络延迟。如果延迟太高，库可能会选择丢弃帧。
+ 跟踪正在进行的流式处理的状态。

## 回调接口
<a name="producer-sdk-cpp-callbacks"></a>

此层公开一组回调接口，使其能够与应用程序层进行通信。这些回调接口包括：


+ **服务回调 interface (`CallbackProvider`)：**该库在创建流、获取流描述和删除流时调用通过此接口获取的事件。
+ **客户端就绪状态或低存储事件接口 (`ClientCallbackProvider`)：**当客户端准备就绪或检测到可用存储空间或内存可能用完时，库会在此接口上调用事件。
+ **流事件回调接口 (`StreamCallbackProvider`)：**当直播事件发生时，该库会调用此接口上的事件，例如直播进入就绪状态、丢帧或直播错误。

Kinesis Video Streams 为这些接口提供了默认实现。您也可以提供自己的自定义实现，例如，如果您需要自定义网络逻辑或想要向用户界面公开低存储条件。

有关制作器库中回调的更多信息，请参阅[制作人 SDK 回调](producer-reference-callbacks.md)。

## 步骤：使用 C\$1\$1 制作器 SDK
<a name="producer-sdk-cpp-using"></a>

此过程演示如何在 C\$1\$1 应用程序中使用 Kinesis Video Streams 客户端和媒体源向你的 Kinesis 视频流发送数据。

该过程包括以下步骤：

**Topics**

# 先决条件
<a name="producer-sdk-cpp-prerequisites"></a>

在设置 C\$1\$1 制作器 SDK 之前，请确保满足以下先决条件：
+ **凭证：**在示例代码中，您可以通过指定在凭证配置文件中设置的配置文件来提供 AWS 凭证。如果尚未执行此操作，请先设置凭证配置文件。

  有关更多信息，请参阅[设置用于开发的 AWS 凭据和区域](https://docs.aws.amazon.com//sdk-for-java/v1/developer-guide/setup-credentials.html)。
+ **证书存储集成：**Kinesis Video Streams Video Streams 制作人库必须与其调用的服务建立信任。这是通过验证公共证书存储库中的证书颁发机构 (CAs) 来完成的。对于基于 Linux 的模型，此存储位于 `/etc/ssl`/ 目录中。

  从以下位置将证书下载到您的证书存储：

  [https://www.amazontrust.com/repository/SFSRootCAG2.pem](https://www.amazontrust.com/repository/SFSRootCAG2.pem)
+ 为 macOS 安装以下构建依赖项：
  + [Autoconf 2.69](http://www.gnu.org/software/autoconf/autoconf.html)（许可证 GPLv3 \$1/Autoconf：GNU GPL 版本 3 或更高版本） 
  + [CMake 3.7 或 3.8](https://cmake.org/)
  + [Pkg-Config](https://www.freedesktop.org/wiki/Software/pkg-config/)
  + xCode (macOS) / clang / gcc (xcode-选择版本 2347)
  + Java 开发工具包 (JDK) (用于 Java JNI 编译)
  + [Lib-Pkg](https://github.com/freebsd/pkg/tree/master/libpkg)
+ 为 Ubuntu 安装以下版本依赖项：
  + Git: `sudo apt install git`
  + [CMake](http://kitware.com/cmake): `sudo apt install cmake`
  + G\$1\$1: `sudo apt install g++`
  + pkg-配置：`sudo apt install pkg-config`
  + openJDK：`sudo apt install openjdk-8-jdk`
**注意**  
只有在构建 Java 原生接口 (JNI) 时才需要这样做。
  + 设置 `JAVA_HOME` 环境变量：`export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/`

# 下载并配置 C\$1\$1 制作器库代码
<a name="producersdk-cpp-download"></a>

有关如何下载和配置 C\$1\$1 制作人库的信息，请参阅 [Amazon Kinesis Video Streams CPP Producer GStreamer 、Plugin 和 JNI](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp)。

有关此示例的先决条件和更多信息，请参阅[使用 C\$1\$1 制作人库](producer-sdk-cpp.md)。

## CMake 争论
<a name="cmake-arguments"></a>

以下是 C\$1\$1 Producer SDK 专用参数 CMake 的参考表。您也可以将[标准 CMake 选项](https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html)传递给。 CMake 

**重要**  
这些都是可选的。

**用于包括或排除某些功能的标志**


| CMake 争论 | Type | 默认 | 说明 | 
| --- | --- | --- | --- | 
| `BUILD_DEPENDENCIES` |  布尔值  |  ON  | 从源代码构建依赖关系。否则，请使用系统上已安装的依赖项。如果找不到所需的依赖项之一，则将返回错误。 | 
| `BUILD_GSTREAMER_PLUGIN` | 布尔值 |  OFF  | 构建kvssink GStreamer 插件。 | 
|  `BUILD_JNI`  | 布尔值 |  OFF  | 构建 Java 原生接口 (JNI)，以便能够从 Java 运行时环境中调用此代码。 | 
|  `ALIGNED_MEMORY_MODEL`  | 布尔值 |  OFF  | 内存分配是否应与 8 字节边界对齐。某些架构不允许进行未对齐的内存访问。 | 
| `CONSTRAINED_DEVICE` | 布尔值 |  OFF  | 仅限非 Windows。启用时，将线程堆栈大小设置为0.5 MiB。[Alpine Linux](https://wiki.alpinelinux.org/wiki/Main_Page) 版本需要使用。否则，将使用操作系统的默认值。 | 
|  `BUILD_STATIC`  | 布尔值 |  OFF  | 将库和可执行文件构建为[共享](https://en.wikipedia.org/wiki/Shared_library) (OFF) 或[静态](https://en.wikipedia.org/wiki/Static_library) (ON)。 | 
|  `ADD_MUCLIBC`  | 布尔值 |  OFF  | 链接到 [ucLib](https://en.wikipedia.org/wiki/UClibc) c 而不是标准 C 库，后者是专为嵌入式系统设计的小型 C 标准库。 | 
|  `OPEN_SRC_INSTALL_PREFIX`  |  字符串  | .. /开源/本地 | 安装开源依赖项的位置（如果从源代码构建）。 | 

**交叉编译标志**

**重要**  
如果您的目标计算机和主机 CPU 架构不同，请设置这些架构。


| CMake 争论 | Type | 默认 | 说明 | 
| --- | --- | --- | --- | 
| `BUILD_LOG4CPLUS_HOST` |  字符串  |  ""  | 为指定的 CPU 架构构建log4cplus依赖关系。如果未设置，log4cplus将自动检测并使用主机的 CPU 架构。 | 
| `BUILD_OPENSSL_PLATFORM`  |  字符串  |  ""  | 为指定的 CPU 架构构建OpenSSL依赖关系。如果未设置，OpenSSL将自动检测并使用主机的 CPU 架构。 | 

**与测试相关的标志**


| CMake 争论 | Type | 默认 | 说明 | 
| --- | --- | --- | --- | 
| `BUILD_TEST` |  布尔值  |  OFF  | 构建单元测试和集成测试。要运行所有测试，请./tst/producerTest从 build 目录运行。 AWS 需要凭据才能运行测试。 | 
| `CODE_COVERAGE` | 布尔值 | OFF | 仅适用于 GNU/Clang 编译器。使用 [gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) 和报告生成启用代码覆盖率收集。 | 
| `COMPILER_WARNINGS` | 布尔值 | OFF | 仅适用于 GNU/Clang 编译器。启用所有编译器警告。 | 
| `ADDRESS_SANITIZER` | 布尔值 | OFF | 仅适用于 GNU/Clang 编译器。使用... 构建[AddressSanitizer](https://compiler-rt.llvm.org/)。 | 
| `MEMORY_SANITIZER` | 布尔值 | OFF | 仅适用于 GNU/Clang 编译器。使用... 构建[MemorySanitizer](https://compiler-rt.llvm.org/)。 | 
| `THREAD_SANITIZER` | 布尔值 | OFF | 仅适用于 GNU/Clang 编译器。使用... 构建[ThreadSanitizer](https://compiler-rt.llvm.org/)。 | 
| `UNDEFINED_BEHAVIOR_SANITIZER` | 布尔值 | OFF | 仅适用于 GNU/Clang 编译器。使用... 构建[UndefinedBehaviorSanitizer](https://compiler-rt.llvm.org/)。 | 

要使用这些 CMake 参数，`cmake ..`请在命令后面将它们作为空格分隔的`-Dkey=value`对列表传递。例如：

```
cmake .. -DBUILD_GSTREAMER_PLUGIN=ON -DBUILD_DEPENDENCIES=OFF -DALIGNED_MEMORY_MODEL=ON 
```

CMake 将通过跟随`$PATH`变量来寻找编译器工具链。在运行之前 CMake，请设置`CC`和`CXX`环境变量以显式设置用于交叉编译的工具链。

# 编写并检查代码
<a name="producersdk-cpp-write"></a>

在本节中[使用 C\$1\$1 制作人库](producer-sdk-cpp.md)，您将研究 C\$1\$1 测试工具（`tst/ProducerTestFixture.h`和其他文件）中的代码。您在上一部分中已下载该代码。

**平台独立的** C\$1\$1 示例演示了以下编码模式：
+ 创建实例`KinesisVideoProducer`以访问 Kinesis Video Streams。
+ 创建 `KinesisVideoStream` 的实例。 AWS 账户 如果同名视频流尚不存在，则会在你中创建 Kinesis 视频流。
+ 对于每个数据帧，当其可用时，对 `KinesisVideoStream` 调用 `putFrame` 以将其发送到流。

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



## 创建的实例 KinesisVideoProducer
<a name="producersdk-cpp-write-create-producer"></a>

您可以通过调用 `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（流）\$1 3（分钟）\$1 60（一分钟内的秒）\$1 10000（kb）\$1 1.2（碎片整理余量）= 194.4 Mb \$1 200 Mb**。
+ 一个 `ClientCallbackProvider` 对象，此对象返回报告客户端特定的事件的函数指针。
+ 一个 `StreamCallbackProvider` 对象，此对象返回在发生流特定的事件时将回调的函数指针。
+ 一个`CredentialProvider`对象，它提供对 AWS 凭证环境变量的访问权限。
+  AWS 区域 (“us-west-2”)。从区域确定服务终端节点。

## 创建的实例 KinesisVideoStream
<a name="producersdk-cpp-write-create-stream"></a>

您可以通过调用带 `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 Video Streams 中的数据保护](how-kms.md)。
+ 流式处理类型。目前唯一有效的值是 `STREAMING_TYPE_REALTIME`。
+ 媒体内容类型。
+ 媒体延迟。当前未使用此值，应将其设置为 0。
+ 每个片段的播放持续时间。
+ 媒体时间码标度。
+ 媒体是否使用关键帧片段。
+ 媒体是否使用时间码。
+ 媒体是否使用绝对片段时间。

## 在 Kinesis 视频流中添加音轨
<a name="producersdk-cpp-write-add-audiotrack-to-stream"></a>

您可以使用以下`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\$1AAC”）。
+ 轨道类型（例如，使用 MKV\$1TRACK\$1INFO\$1TYPE\$1AUDIO 的枚举值作为音频）。

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

## 在 Kinesis 视频流中放一帧
<a name="producersdk-cpp-write-putframe"></a>

你可以使用将媒体放入 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\$1\$1 生成器示例发送测试数据的缓冲区。在实际应用中，您应从媒体源 (例如摄像机) 的帧数据中获取帧缓冲区和大小。

`Frame` 对象具有以下字段：
+ 帧索引。这应是一个单调递增的值。
+ 与帧关联的标记。例如，如果编码器已配置为生成关键帧，则将为此帧分配 `FRAME_FLAG_KEY_FRAME` 标记。
+ 解码时间戳。
+ 演示时间戳。
+ 帧的持续时间 (最多 100 ns)。
+ 帧大小 (以字节为单位)。
+ 帧数据。

有关帧的格式的更多信息，请参阅 [Kinesis Video Streams 数据模型](how-data.md)。

## 将 a 放 KinesisVideoFrame 入特定的曲目中 KinesisVideoStream
<a name="producersdk-cpp-write-putframeintospecifictrack"></a>

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

`PutFrameHelper` 包含以下字段：
+ 队列中音频帧的最大数量。
+ 队列中视频帧的最大数量。
+ 为单个音频帧分配的大小。
+ 为单个视频帧分配的大小。

## 访问指标和指标记录
<a name="producersdk-cpp-write-metrics"></a>

C\$1\$1 制作器 SDK 包括指标和指标日志记录功能。

您可以使用`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 Video Streams 时）之间的差异，以 100 ns 为单位。
+ **overallViewDuration：**内容视图的头部（对帧进行编码时）与尾部（当帧从内存中刷新时，要么是因为超出了为内容视图分配的总空间，要么是因为收到来自 Kinesis Video Streams 的`PersistedAck`消息，并且已知保留的帧被刷新）之间的差异，以 100 ns 为单位。
+ **currentViewSize：**内容视图从头部（对帧进行编码时）到当前位置（帧发送到 Kinesis Video Streams 时）的大小（以字节为单位）。
+ **overallViewSize：**内容视图的总大小（以字节为单位）。
+ **currentFrameRate：**上次测量的直播速率，以每秒帧数为单位。
+ **currentTransferRate：**上次测量的流速率，以每秒字节数为单位。

## 分解
<a name="producersdk-cpp-write-teardown"></a>

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

```
kinesis_video_stream->stopSync();            
```

或者，您可以调用 `stop` 来结束流式传输：

```
kinesis_video_stream->stop();            
```

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

```
kinesis_video_producer_->freeStream(kinesis_video_stream);            
```

# 运行并验证代码
<a name="producersdk-cpp-test"></a>

要运行并验证的代码[使用 C\$1\$1 制作人库](producer-sdk-cpp.md)，请参阅以下特定于操作系统的说明：
+ [Linux](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp/blob/master/docs/linux.md)
+ [macOS](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp/blob/master/docs/macos.md)
+ [Windows](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp/blob/master/docs/windows.md)
+ [树莓派操作系统](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp/blob/master/docs/raspberry-pi.md)

您可以通过在 Amazon CloudWatch 控制台中查看与您的直播相关的指标来监控直播流量，例如`PutMedia.IncomingBytes`。

# 使用 C\$1\$1 制作器 SDK 作为 GStreamer 插件
<a name="producer-sdk-cpp-gstreamer"></a>

[GStreamer](https://gstreamer.freedesktop.org/)是一种流行的媒体框架，可供多个摄像机和视频源使用，通过组合模块化插件来创建自定义媒体管道。Kinesis Video GStreamer Streams 插件简化了 GStreamer 现有媒体管道与 Kinesis Video Streams 的集成。

有关使用 C\$1\$1 制作器 SDK 作为 GStreamer 插件的信息，请参阅[示例：Kinesis Video Streams 制作人 GStreamer SDK 插件-kvssink](examples-gstreamer-plugin.md)。

# 使用 C\$1\$1 制作器 SDK 作为 Docker 容器中的 GStreamer 插件
<a name="producer-sdk-cpp-gstreamer-docker"></a>

[GStreamer](https://gstreamer.freedesktop.org/)是一种流行的媒体框架，可供多个摄像机和视频源使用，通过组合模块化插件来创建自定义媒体管道。Kinesis Video GStreamer Streams 插件简化了 GStreamer 现有媒体管道与 Kinesis Video Streams 的集成。

此外，使用 [Docker]() 创建 GStreamer 管道可以标准化 Kinesis Video Streams 的操作环境，从而简化了应用程序的构建和运行。

有关在 Docker 容器中使用 C\$1\$1 制作器 SDK 作为 GStreamer 插件的信息，请参阅[在 Docker 容器中运行该 GStreamer 元素](examples-gstreamer-plugin.md#examples-gstreamer-plugin-docker)。

# 在 C\$1\$1 制作器 SDK 中使用日志功能
<a name="producer-sdk-cpp-logging"></a>

您可以在`kinesis-video-native-build`文件夹`kvs_log_configuration`的文件中为 C\$1\$1 制作器 SDK 应用程序配置日志记录。

以下示例显示了默认配置文件的第一行，它会将应用程序配置为将 `DEBUG` 级日志条目写入到 AWS 管理控制台：

```
log4cplus.rootLogger=DEBUG, KvsConsoleAppender
```

您可以将日志记录级别设置为 `INFO` 以减少详细日志记录。

要将应用程序配置为将日志条目写入日志文件，请将文件中的第一行更新为以下内容：

```
log4cplus.rootLogger=DEBUG, KvsConsoleAppender, KvsFileAppender
```

这会将应用程序配置为将日志条目写入到 `kvs.log` 文件夹中的 `kinesis-video-native-build/log`。

要更改日志文件位置，请使用新路径更新以下行：

```
log4cplus.appender.KvsFileAppender.File=./log/kvs.log
```

**注意**  
如果 `DEBUG` 级日志记录被写入到某个文件，日志文件可能快速用尽设备上的可用存储空间。