

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

# 上传到 Kinesis Video Streams
<a name="producer-sdk"></a>

亚马逊 Kinesis Video Streams 制作人库是 Kinesis Video Streams 制作人软件开发工具包中的一组库。客户端使用这些库和 SDK 来构建设备端应用程序，以便安全地连接到 Kinesis Video Streams，并使用流媒体数据在控制台或客户端应用程序中实时查看。

媒体数据可通过以下方式进行流式传输：
+ 实时
+ 缓冲几秒钟后
+ 媒体上传后

创建 Kinesis Video Streams 直播后，就可以开始向其发送数据了。您可以使用软件开发工具包创建应用程序代码，用于从媒体源提取视频数据（称为帧）并将其上传到 Kinesis Video Streams。这些应用程序也称为*创建者* 应用程序。

生产者库包含以下组件：
+ [Kinesis Video Streams 制作人客户端](#producer-sdk-client)
+ [Kinesis Video Streams 制作人库](#producer-sdk-library)

## Kinesis Video Streams 制作人客户端
<a name="producer-sdk-client"></a>

Kinesis Video Streams 制作人客户端包含`KinesisVideoClient`一个类。该类管理媒体源，从源接收数据，并在数据从媒体源流向 Kinesis Video Streams 时管理流生命周期。它还提供了一个`MediaSource`界面，用于定义 Kinesis Video Streams 与您的专有硬件和软件之间的交互。

媒体源几乎可以是任何内容。例如，您可以使用摄像头媒体源或麦克风媒体源。媒体源不仅限于音频源和视频源。例如，数据日志可能是文本文件，但仍可作为数据流发送。您的手机上也可以安装多个摄像头以便同时流式处理数据。

要从这些源中的任意一个获取数据，可以实施 `MediaSource` 接口。此接口支持我们未提供内置支持的其他情况。例如，你可以选择向 Kinesis Video Streams 发送以下内容：
+ 诊断数据流 (例如，应用程序日志和事件)
+ 来自红外摄像机或深度摄像机的数据 RADARs

Kinesis Video Streams 不为摄像机等媒体制作设备提供内置实现。要从这些设备提取数据，您必须实施代码，从而创建您自己的自定义媒体源实施。然后，您可以显式注册您的自定义媒体源`KinesisVideoClient`，该媒体源会将数据上传到 Kinesis Video Streams。

Kinesis Video Streams 制作人客户端可用于 Java 和安卓应用程序。有关更多信息，请参阅[使用 Java 制作器库](producer-sdk-javaapi.md)和[使用安卓制作人库](producer-sdk-android.md)。

## Kinesis Video Streams 制作人库
<a name="producer-sdk-library"></a>

Kinesis Video Streams 制作人库包含在 Kinesis Video Streams 制作人客户端中。该库也可供那些想要与Kinesis Video Streams进行更深层次集成的用户直接使用。它支持与具有专有操作系统的设备、网络堆栈或有限的设备上资源进行集成。

Kinesis Video Streams 制作人库实现了直播到 Kinesis Video Streams 的状态机。它提供回调钩子，这需要您提供自己的传输实施，并显式处理传入和传出服务的每条消息。

出于以下原因，你可以选择直接使用 Kinesis Video Streams 制作人库：
+ 要在其上运行应用程序的设备没有 Java 虚拟机。
+ 您希望使用非 Java 语言编写应用程序代码。
+ 由于内存和处理能力等限制，您希望减少代码中的开销，并将其限制在最低的抽象级别。

目前，Kinesis Video Streams 制作人库可用于安卓、C、C\$1\$1 和 Java 应用程序。有关更多信息，请参阅以下*相关主题*中支持的语言。

## 了解什么是制作者库
<a name="producer-sdk-related-topics"></a>

 [使用 Java 制作器库](producer-sdk-javaapi.md) 

 [使用安卓制作人库](producer-sdk-android.md) 

 [使用 C\$1\$1 制作人库](producer-sdk-cpp.md) 

 [使用 C 制作人库](producer-sdk-c-api.md) 

 [在树莓派上使用 C\$1\$1 制作器 SDK](producersdk-cpp-rpi.md) 

# 使用 Java 制作器库
<a name="producer-sdk-javaapi"></a>

您可以使用 Amazon Kinesis Video Streams 提供的 Java 制作器库以最少的配置编写应用程序代码，将媒体数据从设备发送到 Kinesis 视频流。

执行以下步骤将您的代码与 Kinesis Video Streams 集成，以便您的应用程序可以开始将数据流式传输到您的 Kinesis 视频流：

1. 创建 `KinesisVideoClient` 对象的实例。

1. 通过提供媒体源信息创建 `MediaSource` 对象。例如，当创建摄像头媒体源时，您需要提供相应信息，例如，识别摄像头并指定摄像头所用编码方面的信息。

   如果要开始流式处理，您必须创建自定义媒体源。

1. 将媒体源注册到 `KinesisVideoClient`。

   将媒体源注册到 `KinesisVideoClient` 后，每当数据对媒体源可用时，都会随数据一起调用 `KinesisVideoClient`。

## 步骤：使用 Java 制作器 SDK
<a name="producer-sdk-java-using"></a>

此过程演示如何在 Java 应用程序中使用 Kinesis Video Streams Java 制作者客户端向你的 Kinesis 视频流发送数据。

这些步骤不需要您具备摄像头或麦克风等媒体源。相反，出于测试目的，该代码会生成包含一系列字节的示例帧。在您从摄像头和麦克风等实际源发送媒体数据时，您可以使用相同的编码模式。

该过程包括以下步骤：
+ [下载并配置代码](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producersdk-javaapi-downloadcode.html)
+ [编写并检查代码](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producersdk-javaapi-writecode.html)
+ [运行并验证代码](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producersdk-javaapi-reviewcode.html)

# 先决条件
<a name="producersdk-javaapi-prerequisites"></a>

在设置 Java Producer SDK 之前，请确保满足以下先决条件：
+ 在示例代码中，您可以通过指定在凭证配置文件中设置的配置文件来提供 AWS 证书。如果尚未执行此操作，请先设置凭证配置文件。有关更多信息，请参阅中的[设置用于开发的 AWS 凭据和区域*适用于 Java 的 AWS SDK*](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html)。
**注意**  
Java 示例使用`SystemPropertiesCredentialsProvider`对象获取您的证书。提供程序从 `aws.accessKeyId` 和 `aws.secretKey` Java 系统属性检索这些凭证。您可以在 Java 开发环境中设置这些系统属性。有关如何设置 Java 系统属性的信息，请参阅特定集成开发环境 (IDE) 的文档。
+ 您`NativeLibraryPath`必须包含您的`KinesisVideoProducerJNI`文件，可在 [https://github.com/awslabs/amazon-kinesis-video-streams-](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp) 中找到producer-sdk-cpp。此文件的文件扩展名取决于您的操作系统：
  + KinesisVideoProducer适用于 Linux 的 **jni.so**
  + KinesisVideoProducer适用于 m@@ **acOS 的 jni.dylib**
  + **KinesisVideoProducerJNI.dll 适用**于 Windows
**注意**  
[适用于 macOS、Ubuntu、Windows 和 Raspbian 的预建库可在-.git 中找到。`src/main/resources/lib` https://github.com/awslabs/ amazon-kinesis-video-streams producer-sdk-java](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java)对于其他环境，请编译 [C\$1\$1](producer-sdk-cpp.md)。

# 下载并配置 Java 制作器库代码
<a name="producersdk-javaapi-downloadcode"></a>

在 Java 生产者库过程的这一部分中，您将下载 Java 示例代码，将项目导入到 Java IDE 中，然后配置库的位置。

有关此示例的先决条件和其他详细信息，请参阅[使用 Java producer 库](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk-javaapi.html)。



1. 创建一个目录，然后从 GitHub存储库中克隆示例源代码。

   ```
   git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java
   ```

1. 打开你使用的 Java 集成开发环境 (IDE)（例如 Eclip [se 或 Intel JetBrains li](https://www.eclipse.org/) [J ID](https://www.jetbrains.com/idea/) EA），然后导入你下载的 Apache Maven 项目：
   + **在 IntelliJ IDEA 中：**选择 **Import**。导航到下载的程序包的根目录中的 `pom.xml` 文件。
   + **在 Eclipse 中：**选择 **File**、**Import**、**Maven**、**Existing Maven Projects**。然后，导航到 `kinesis-video-java-demo` 目录。

   有关更多信息，请参阅您的 IDE 的相应文档。

1. Java 示例代码使用当前的 AWS 凭据。要使用不同的凭证配置文件，请在 `DemoAppMain.java` 中找到以下代码：

   ```
   final KinesisVideoClient kinesisVideoClient = KinesisVideoJavaClientFactory
       .createKinesisVideoClient(
           Regions.US_WEST_2,
           AuthHelper.getSystemPropertiesCredentialsProvider());
   ```

   将该代码更改为以下内容：

   ```
   final KinesisVideoClient kinesisVideoClient = KinesisVideoJavaClientFactory
       .createKinesisVideoClient(
           Regions.US_WEST_2,
           new ProfileCredentialsProvider("credentials-profile-name"));
   ```

   有关更多信息，请参阅 *适用于 Java 的 AWS SDK* 参考中的 [ProfileCredentialsProvider](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/auth/profile/ProfileCredentialsProvider.html)。

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

在 [Java 生产者库过程](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk-javaapi.html)的这一部分中，您将编写并检查在上一节中下载的 Java 示例代码。

Java 测试应用程序 ([https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java/blob/master/src/main/demo/com/amazonaws/kinesisvideo/demoapp/DemoAppMain.java](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java/blob/master/src/main/demo/com/amazonaws/kinesisvideo/demoapp/DemoAppMain.java)) 会显示以下编码模式：
+ 创建 `KinesisVideoClient` 的实例。
+ 创建 `MediaSource` 的实例。
+ 将 `MediaSource` 注册到客户端。
+ 开始流式处理。启动`MediaSource`，它就会开始向客户端发送数据。

以下各节提供了详细信息。



## 创建的实例 KinesisVideoClient
<a name="producersdk-javaapi-review-code-create-client"></a>

您可以通过调用 `KinesisVideoClient` 操作来创建 `createKinesisVideoClient` 对象。

```
final KinesisVideoClient kinesisVideoClient = KinesisVideoJavaClientFactory
    .createKinesisVideoClient(
        Regions.US_WEST_2,
        AuthHelper.getSystemPropertiesCredentialsProvider());
```

`KinesisVideoClient` 需要凭证以进行身份验证，才能进行网络调用。您将传入一个 `SystemPropertiesCredentialsProvider` 实例，它会读取凭证文件中默认配置文件的 `AWSCredentials`：

```
[default]
aws_access_key_id = ABCDEFGHIJKLMOPQRSTU
aws_secret_access_key = AbCd1234EfGh5678IjKl9012MnOp3456QrSt7890
```





## 创建的实例 MediaSource
<a name="producersdk-javaapi-review-code-create-mediasource"></a>

要向 Kinesis 视频流发送字节，必须生成数据。Amazon Kinesis Video Streams 提供了`MediaSource`代表数据源的接口。

例如，Kinesis Video Streams Java 库提供了`ImageFileMediaSource`该接口的实现`MediaSource`。该类仅从一系列媒体文件中读取数据，而不是 Kinesis 视频流，但你可以用它来测试代码。

```
final MediaSource bytesMediaSource = createImageFileMediaSource();
```

## MediaSource 向客户端注册
<a name="producersdk-javaapi-review-code-register-mediasource"></a>

将您创建的媒体源注册到 `KinesisVideoClient`，使其能够识别该客户端 (并且可向客户端发送数据)。

```
kinesisVideoClient.registerMediaSource(mediaSource);
```



## 启动媒体源
<a name="producersdk-javaapi-review-code-start-mediasource"></a>

启动媒体源，使其可以开始生成数据并将其发送到客户端。

```
bytesMediaSource.start();
```



# 清理 资源
<a name="producersdk-javaapi-cleanup"></a>

为了避免内存泄漏，请执行以下操作从客户端取消注册媒体源并释放客户端。

```
try {
    kinesisVideoClient.unregisterMediaSource(mediaSource);
    kinesisVideoClient.free();
} catch (final KinesisVideoException e) {
    throw new RuntimeException(e);
}
```

如果您使用向缓存中添加了任何项目 [https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java/blob/master/src/main/java/com/amazonaws/kinesisvideo/java/service/CachedInfoMultiAuthServiceCallbacksImpl.java](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-java/blob/master/src/main/java/com/amazonaws/kinesisvideo/java/service/CachedInfoMultiAuthServiceCallbacksImpl.java)，例如：

```
serviceCallbacks.addStreamInfoToCache(streamName, streamInfo);
serviceCallbacks.addStreamingEndpointToCache(streamName, dataEndpoint);
```

完成后清除缓存：

```
serviceCallbacks.removeStreamFromCache(streamName);
```

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

要运行 Java [生产者库的 Java 测试工具](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk-javaapi.html)，请执行以下操作。

1. 选择 **DemoAppMain**。

1. 选择 “**运行**”，**“运行DemoAppMain”**。

1. 将您的凭证添加到此应用程序的 JVM 自变量：
   + **对于非临时 AWS 证书：**`"-Daws.accessKeyId={YourAwsAccessKey} -Daws.secretKey={YourAwsSecretKey} -Djava.library.path={NativeLibraryPath}"`
   + **对于临时 AWS 证书：**`"-Daws.accessKeyId={YourAwsAccessKey} -Daws.secretKey={YourAwsSecretKey} -Daws.sessionToken={YourAwsSessionToken} -Djava.library.path={NativeLibraryPath}" `

1. 登录 AWS 管理控制台 并打开 [Kinesis Video Streams](https://console.aws.amazon.com//kinesisvideo/home/) 控制台。

   在 **Manage Streams** 页面中选择您的流。

1. 示例视频将在嵌入式播放器中播放。可能需要等待一小段积累帧的时间 (标准带宽和处理器条件下最多十秒)，视频才会出现。

该代码示例会创建一个流。代码中的 `MediaSource` 启动时，它会开始将示例帧发送到 `KinesisVideoClient`。然后，客户端会将数据发送到您的 Kinesis 视频流。

# 使用安卓制作人库
<a name="producer-sdk-android"></a>

您可以使用亚马逊 Kinesis Video Streams 提供的安卓制作器库来编写应用程序代码，只需最少的配置，即可将媒体数据从安卓设备发送到 Kinesis 视频流。

执行以下步骤将您的代码与 Kinesis Video Streams 集成，以便您的应用程序可以开始将数据流式传输到您的 Kinesis 视频流：

1. 创建 `KinesisVideoClient` 对象的实例。

1. 通过提供媒体源信息创建 `MediaSource` 对象。例如，当创建摄像头媒体源时，您需要提供相应信息，例如，识别摄像头并指定摄像头所用编码方面的信息。

   如果要开始流式处理，您必须创建自定义媒体源。

## 程序：使用安卓制作人 SDK
<a name="producer-sdk-android-using"></a>

此过程演示如何在安卓应用程序中使用 Kinesis Video Streams 安卓制作人客户端向你的 Kinesis 视频流发送数据。

该过程包括以下步骤：
+ [先决条件](producersdk-android-prerequisites.md)
+ [下载并配置 Android 制作器库代码](producersdk-android-downloadcode.md)
+ [检查代码](producersdk-android-writecode.md)
+ [运行并验证代码](producersdk-android-reviewcode.md)

# 先决条件
<a name="producersdk-android-prerequisites"></a>

建议使用 [Android Studio](https://developer.android.com/studio/index.html) 检查、编辑和运行应用程序代码。我们建议使用最新的稳定版本。

在示例代码中，您需要提供亚马逊 Cognito 凭证。

**Topics**
+ [设置用户池](#set-up-user-pool)
+ [设置身份池](#set-up-identity-pool)

## 设置用户池
<a name="set-up-user-pool"></a>

**设置用户池**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)并验证区域是否正确。

1. 在左侧导航栏中，选择 “**用户池**”。

1. 在 “**用户池**” 部分，选择 “**创建用户池**”。

1. 完成以下各节：

   1. **第 1 步：配置登录体验**-在 **Cognito 用户池登录**选项部分，选择相应的选项。

      选择**下一步**。

   1. **步骤 2：配置安全要求**-选择相应的选项。

      选择**下一步**。

   1. **第 3 步：配置注册体验**-选择相应的选项。

      选择**下一步**。

   1. **步骤 4：配置消息传送**-选择相应的选项。

      在 **IAM 角色选择**字段中，选择现有角色或创建新角色。

      选择**下一步**。

   1. **第 5 步：集成您的应用程序**-选择相应的选项。

      在 “**初始应用程序客户端**” 字段中，选择 “**机密客户端**”。

      选择**下一步**。

   1. **步骤 6：查看并创建**-查看您在前面部分中的选择，然后选择**创建用户池**。

1. 在 “**用户池**” 页面上，选择您刚刚创建的池。

   复制**用户池 ID** 并记下来以备后用。在`awsconfiguration.json`文件中，这是`CognitoUserPool.Default.PoolId`。

1. 选择 “**应用程序集成**” 选项卡，然后转到页面底部。

1. 在**应用程序客户端列表**部分，选择您刚刚创建的**应用程序客户端名称**。

   复制**客户端 ID** 并记下来以备后用。在`awsconfiguration.json`文件中，这是`CognitoUserPool.Default.AppClientId`。

1. 出示**客户机密**并记下来以备后用。在`awsconfiguration.json`文件中，这是`CognitoUserPool.Default.AppClientSecret`。

## 设置身份池
<a name="set-up-identity-pool"></a>

**设置身份池**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)并验证区域是否正确。

1. 在左侧导航栏中，选择 “**身份池**”。

1. 选择**创建身份池**。

1. 配置身份池。

   1. **步骤 1：配置身份池信任**-完成以下部分：
      + **用户访问权限**-选择**经过身份验证的访问权限**
      + **经过身份验证的身份源**-选择 **Amazon Cognito** 用户池

      选择**下一步**。

   1. **步骤 2：配置权限**-在 “**经过身份验证的角色**” 部分，填写以下字段：
      + **IAM 角色**-选择**创建新的 IAM 角色**
      + **IAM 角色名称**-输入名称并记下来供后续步骤使用。

      选择**下一步**。

   1. **步骤 3：Connect 身份提供商**-在 “**用户池详情**” 部分填写以下字段：
      + **用户池 ID**-选择您之前创建的用户池。
      + **应用程序客户端 ID**-选择您之前创建的应用程序客户端 ID。

      选择**下一步**。

   1. **步骤 4：配置属性**-在**身份池名称字段中键入名称**。

      选择**下一步**。

   1. **第 5 步：查看并创建**-查看您在每个部分中的选择，然后选择**创建身份池**。

1. 在**身份池**页面上，选择您的新身份池。

   复制**身份池 ID** 并记下来以备后用。在`awsconfiguration.json`文件中，这是`CredentialsProvider.CognitoIdentity.Default.PoolId`。

1. 更新 IAM 角色的权限。

   1. 登录 AWS 管理控制台 并打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

   1. 在左侧导航栏中，选择 “**角色**”。

   1. 找到并选择您在上面创建的角色。
**注意**  
如果需要，请使用搜索栏。

   1. 选择附加的权限策略。

      选择**编辑**。

   1. 选择 **JSON** 选项卡，然后将策略替换为以下内容：

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "cognito-identity:*",
                      "kinesisvideo:*"
                  ],
                  "Resource": [
                      "*"
                  ]
              }
          ]
      }
      ```

------

      选择**下一步**。

   1. 如果尚未选中 “将**此新版本设为默认版本”** 旁边的复选框。

      选择**保存更改**。

# 下载并配置 Android 制作器库代码
<a name="producersdk-android-downloadcode"></a>

在安卓制作人库程序的这一部分中，您将下载安卓示例代码并在 Android Studio 中打开该项目。

有关此示例的先决条件和其他详细信息，请参阅[使用 Android 制作人库](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk-android.html)。



1. 创建一个目录，然后 适用于 Android 的 AWS Mobile SDK 从 GitHub存储库中克隆该目录。

   ```
   git clone https://github.com/awslabs/aws-sdk-android-samples
   ```

1. 打开 [Android Studio](https://developer.android.com/studio/index.html)。

1. 在起始屏幕中，选择 **Open an existing Android Studio project**。

1. 导航到 `aws-sdk-android-samples/AmazonKinesisVideoDemoApp` 目录，选择 **OK**。

1. 打开 `AmazonKinesisVideoDemoApp/src/main/res/raw/awsconfiguration.json` 文件。

   在`CredentialsProvider`节点中，提供[先决条件](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk-android.html#producersdk-android-prerequisites)部分中**设置身份池**过程中的身份池 ID，并提供您的 AWS 区域 （例如**us-west-2**）。

   在`CognitoUserPool`节点中，提供[先决条件](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk-android.html#producersdk-android-prerequisites)部分中**设置用户池过程中的应用程序客户端密钥、应用程序客户端 ID 和池** ID，并提供您的 AWS 区域 （例如**us-west-2**）。

1. `awsconfiguration.json` 文件类似如下：

   ```
   {
     "Version": "1.0",
     "CredentialsProvider": {
       "CognitoIdentity": {
         "Default": {
           "PoolId": "us-west-2:01234567-89ab-cdef-0123-456789abcdef",
           "Region": "us-west-2"
         }
       }
     },
     "IdentityManager": {
       "Default": {}
     },
     "CognitoUserPool": {
       "Default": {
         "AppClientSecret": "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmno",
         "AppClientId": "0123456789abcdefghijklmnop",
         "PoolId": "us-west-2_qRsTuVwXy",
         "Region": "us-west-2"
       }
     }
   }
   ```

1. `AmazonKinesisVideoDemoApp/src/main/java/com/amazonaws/kinesisvideo/demoapp/KinesisVideoDemoApp.java`使用您的地区更新（在以下示例中，将其设置为 **US\$1WEST\$1** 2）：

   ```
   public class KinesisVideoDemoApp extends Application {
       public static final String TAG = KinesisVideoDemoApp.class.getSimpleName();
       public static Regions KINESIS_VIDEO_REGION = Regions.US_WEST_2;
   ```

   有关 AWS 区域 常量的信息，请参阅[区域](https://aws-amplify.github.io/aws-sdk-android/docs/reference/com/amazonaws/regions/Regions.html)。

# 检查代码
<a name="producersdk-android-writecode"></a>

在 [Android 制作人库过程](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk-android.html)的这一部分中，您将研究示例代码。

Android 测试应用程序 (`AmazonKinesisVideoDemoApp`) 显示以下编码模式：
+ 创建 `KinesisVideoClient` 的实例。
+ 创建 `MediaSource` 的实例。
+ 开始流式处理。启动`MediaSource`，它就会开始向客户端发送数据。

以下各节提供了详细信息。



## 创建的实例 KinesisVideoClient
<a name="producersdk-android-review-code-create-client"></a>

您可以通过调用 `[KinesisVideoClient](https://github.com/aws-amplify/aws-sdk-android/blob/main/aws-android-sdk-kinesisvideo/src/main/java/com/amazonaws/kinesisvideo/client/KinesisVideoClient.java)` 操作来创建 `[createKinesisVideoClient](https://github.com/aws-amplify/aws-sdk-android/blob/main/aws-android-sdk-kinesisvideo/src/main/java/com/amazonaws/mobileconnectors/kinesisvideo/client/KinesisVideoAndroidClientFactory.java)` 对象。

```
mKinesisVideoClient = KinesisVideoAndroidClientFactory.createKinesisVideoClient(
                    getActivity(),
                    KinesisVideoDemoApp.KINESIS_VIDEO_REGION,
                    KinesisVideoDemoApp.getCredentialsProvider());
```

`KinesisVideoClient` 需要凭证以进行身份验证，才能进行网络调用。您传入了一个实例`AWSCredentialsProvider`，该实例会从您在上一节中修改`awsconfiguration.json`的文件中读取您的 Amazon Cognito 证书。

## 创建的实例 MediaSource
<a name="producersdk-android-review-code-create-mediasource"></a>

要向 Kinesis 视频流发送字节，必须生成数据。Amazon Kinesis Video Streams 提供了`[MediaSource](https://github.com/aws-amplify/aws-sdk-android/blob/main/aws-android-sdk-kinesisvideo/src/main/java/com/amazonaws/kinesisvideo/internal/client/mediasource/MediaSource.java)`代表数据源的接口。

例如，Kinesis Video Streams 安卓库提供了`[AndroidCameraMediaSource](https://github.com/aws-amplify/aws-sdk-android/blob/main/aws-android-sdk-kinesisvideo/src/main/java/com/amazonaws/mobileconnectors/kinesisvideo/mediasource/android/AndroidCameraMediaSource.java)`该接口的实现`MediaSource`。此类从设备的某个摄像头读取数据。

下面的代码示例 (摘自 `[fragment/StreamConfigurationFragment.java](https://github.com/awslabs/aws-sdk-android-samples/blob/main/AmazonKinesisVideoDemoApp/src/main/java/com/amazonaws/kinesisvideo/demoapp/fragment/StreamConfigurationFragment.java)` 文件) 创建媒体源配置：

```
private AndroidCameraMediaSourceConfiguration getCurrentConfiguration() {
return new AndroidCameraMediaSourceConfiguration(
        AndroidCameraMediaSourceConfiguration.builder()
                .withCameraId(mCamerasDropdown.getSelectedItem().getCameraId())
                .withEncodingMimeType(mMimeTypeDropdown.getSelectedItem().getMimeType())
                .withHorizontalResolution(mResolutionDropdown.getSelectedItem().getWidth())
                .withVerticalResolution(mResolutionDropdown.getSelectedItem().getHeight())
                .withCameraFacing(mCamerasDropdown.getSelectedItem().getCameraFacing())
                .withIsEncoderHardwareAccelerated(
                        mCamerasDropdown.getSelectedItem().isEndcoderHardwareAccelerated())
                .withFrameRate(FRAMERATE_20)
                .withRetentionPeriodInHours(RETENTION_PERIOD_48_HOURS)
                .withEncodingBitRate(BITRATE_384_KBPS)
                .withCameraOrientation(-mCamerasDropdown.getSelectedItem().getCameraOrientation())
                .withNalAdaptationFlags(StreamInfo.NalAdaptationFlags.NAL_ADAPTATION_ANNEXB_CPD_AND_FRAME_NALS)
                .withIsAbsoluteTimecode(false));
}
```

下面的代码示例 (摘自 `[fragment/StreamingFragment.java](https://github.com/awslabs/aws-sdk-android-samples/blob/main/AmazonKinesisVideoDemoApp/src/main/java/com/amazonaws/kinesisvideo/demoapp/fragment/StreamingFragment.java)` 文件) 创建媒体源：

```
mCameraMediaSource = (AndroidCameraMediaSource) mKinesisVideoClient
    .createMediaSource(mStreamName, mConfiguration);
```

## 启动媒体源
<a name="producersdk-android-review-code-start-mediasource"></a>

启动媒体源，以便开始生成数据并将数据发送到客户端。下面的代码示例摘自 `[fragment/StreamingFragment.java](https://github.com/awslabs/aws-sdk-android-samples/blob/main/AmazonKinesisVideoDemoApp/src/main/java/com/amazonaws/kinesisvideo/demoapp/fragment/StreamingFragment.java)` 文件：

```
mCameraMediaSource.start();
```



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

要运行 Android [制作人库的 Android](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk-android.html) 示例应用程序，请执行以下操作。

1. 连接 Android 设备。

1. 依次选择 **Run**、**Run...**、**Edit configurations...**。

1. 选择加号图标 (**\$1**)，**安卓应用程序**。在**名称**字段中，输入 **AmazonKinesisVideoDemoApp**。在 “**模块**” 下拉列表中，选择**AmazonKinesisVideoDemoApp**。选择**确定**。

1. 选择 **Run**、**Run**。

1. 在 **Select Deployment Target** 屏幕中，选择连接的设备，然后选择 **OK**。

1. 在设备上的**AWSKinesisVideoDemoApp**应用程序中，选择**创建新帐户**。

1. 为 **USERNAME**、**Password**、**Given name**、**Email address** 和 **Phone number** 输入值，然后选择 **Sign up**。
**注意**  
这些值具有以下约束：  
**密码：**必须包含大小写字母、数字和特殊字符。您可以在 [Amazon Cognito](https://console.aws.amazon.com/cognito/home) 控制台的用户池页面中更改这些限制。
**电子邮件地址：**必须是有效地址，您才能收到确认码。
**Phone number (电话号码)：**必须采用以下格式：**\$1*<Country code>**<Number>***，例如 **\$112065551212**。

1. 输入您通过电子邮件收到的验证码，然后选择**确认**。选择**确定**。

1. 在下一页上，保留默认值，然后选择**直播**。

1. 登录 AWS 管理控制台 并打开美国西部（俄勒冈）地区的 [Kinesis Video Stream](https://console.aws.amazon.com//kinesisvideo/home/) s 控制台。

   在 **Manage Streams** 页面上，选择 **demo-stream**。

1. 流视频将在嵌入式播放器中播放。可能需要等待一小段积累帧的时间 (标准带宽和处理器条件下最多十秒)，视频才会出现。
**注意**  
如果设备的屏幕发生旋转 (例如，从纵向到横向)，则应用程序会停止流视频。

该代码示例会创建一个流。代码中的 `MediaSource` 启动后，就开始将帧从摄像头发送到 `KinesisVideoClient`。**然后，客户端将数据发送到名为 demo-stream 的 Kinesis 视频流。**

# 使用 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` 级日志记录被写入到某个文件，日志文件可能快速用尽设备上的可用存储空间。

# 使用 C 制作人库
<a name="producer-sdk-c-api"></a>

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

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

[Kinesis Video Streams C 制作人库基于一个名为平台独立代码库 (PIC) 的通用组件，该组件可在-pic/ GitHub 上https://github.com/awslabs/amazon-kinesis-video-streams找到。](https://github.com/awslabs/amazon-kinesis-video-streams-pic/)PIC 包含基础组件的独立于平台的业务逻辑。Kinesis Video Streams C 制作人库将 PIC 与额外的 API 层封装在一起，允许特定于场景和平台的回调和事件。Kinesis Video Streams C 制作人库在 PIC 之上构建了以下组件：
+ **设备信息提供商** — 公开可以直接提供给 PIC API 的`DeviceInfo`结构。您可以配置一组提供程序，包括针对应用程序场景优化的提供程序，这些提供程序可以根据您的应用程序处理的流的数量和类型以及根据可用 RAM 量配置的所需缓冲量来优化内容存储。
+ **直播信息提供者** — 公开可以直接提供给 PIC API 的`StreamInfo`结构。有一组特定于应用程序类型和常见流媒体场景类型的提供商。其中包括视频、音频、音频和视频多轨等提供商。这些场景中的每一个都有默认值，您可以根据应用程序的要求对其进行自定义。
+ **回调提供程序** — 公开可以直接提供给 PIC API 的`ClientCallbacks`结构。这包括一组回调提供程序，用于联网（基于 CURL 的 API 回调）、授权（AWS 凭证 API）以及错误回调时重试直播。回调提供程序 API 需要许多参数进行配置，例如 AWS 区域 和授权信息。这可以通过使用 IoT 证书或使用 AWS AccessKeyId SecretKey、或来完成 SessionToken。如果您的应用程序需要进一步处理特定回调以实现某些应用程序特定的逻辑，则可以通过自定义回调来增强回调提供程序。
+ **FrameOrderCoordinator**— 帮助处理多轨场景的音频和视频同步。它具有默认行为，您可以对其进行自定义以处理应用程序的特定逻辑。在将帧元数据提交给低层 PIC API 之前，它还简化了 PIC 帧结构中的帧元数据打包。对于非多轨道场景，此组件直接传递到 PIC putFrame API。

C 库提供以下对象来管理向 Kinesis 视频流发送数据的过程：
+ **KinesisVideoClient**— 包含有关您的设备的信息，并维护用于报告 Kinesis Video Streams 事件的回调。
+ **KinesisVideoStream**— 表示有关视频流参数的信息，例如名称、数据保留期和媒体内容类型。

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

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

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

此过程演示如何在 C 应用程序中使用 Kinesis Video Streams 客户端和媒体源向你的 Kinesis 视频流发送 H.264 编码的视频帧。

该过程包括以下步骤：
+ [下载 C 制作器库代码](producersdk-c-download.md)
+ [编写并检查代码](producersdk-c-write.md)
+ [运行并验证代码](producersdk-c-test.md)

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

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

  有关更多信息，请参阅[设置用于开发的 AWS 凭据和区域](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html)。
+ **证书存储集成** — Kinesis 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_HOME` 环境变量：`export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/`

# 下载 C 制作器库代码
<a name="producersdk-c-download"></a>

在本节中，您将下载低级别库。有关此示例的先决条件及其他详细信息，请参阅 [使用 C\$1\$1 制作人库](producer-sdk-cpp.md)。





1. 创建一个目录，然后从 GitHub存储库中克隆示例源代码。

   ```
   git clone --recursive https://github.com/awslabs/amazon-kinesis-video-streams-producer-c.git
   ```
**注意**  
如果您错过使用 `--recursive` 运行 git 克隆，请在 `amazon-kinesis-video-streams-producer-c/open-source` 目录中运行 `git submodule update --init`。您还必须安装 pkg-config 和构建环境。 CMake  
有关更多信息，请参阅 in-p [https://github.com/awslabs/amazon-kinesis-video-streamsroducer-c `README.md` .git](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c.git) 中的。

1. 在您选定的集成开发环境 (IDE) (例如 [Eclipse](https://www.eclipse.org/)) 中打开您的代码。

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

在本节中，您将在-p [https://github.com/awslabs/amazon-kinesis-video-streamsroducer-c `samples`](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c) 存储库的文件夹`KvsVideoOnlyStreamingSample.c`中检查示例应用程序的代码。 GitHub您在上一步中已下载该代码。此示例演示如何使用 C 制作人库将文件夹内的 H.264 编码视频帧发送到`samples/h264SampleFrames`您的 Kinesis 视频流。

此示例应用程序包含三个部分：
+ 初始化和配置：
  + 初始化和配置特定于平台的媒体管道。
  +  KinesisVideoStream为管道初始 KinesisVideoClient 化和配置、设置回调、集成特定场景的身份验证、提取和提交编解码器私有数据，以及将流置于 READY 状态。
+ 主循环：
  + 使用时间戳和标志从媒体管道获取帧。
  + 将框架提交给 KinesisVideoStream.
+ 分解：
  + 正在停止（同步） KinesisVideoStream、释放 KinesisVideoStream、释 KinesisVideoClient放。

此示例应用程序完成以下任务：
+ 调用 `createDefaultDeviceInfo` API 来创建 `deviceInfo` 对象，其中包含有关设备或存储配置的信息。

  ```
  // default storage size is 128MB. Use setDeviceInfoStorageSize after create to change storage size.
  CHK_STATUS(createDefaultDeviceInfo(&pDeviceInfo));
  // adjust members of pDeviceInfo here if needed
      pDeviceInfo->clientInfo.loggerLogLevel = LOG_LEVEL_DEBUG;
  ```
+ 调用 `createRealtimeVideoStreamInfoProvider` API 以创建 `StreamInfo` 对象。

  ```
  CHK_STATUS(createRealtimeVideoStreamInfoProvider(streamName, DEFAULT_RETENTION_PERIOD, DEFAULT_BUFFER_DURATION, &pStreamInfo));
  // adjust members of pStreamInfo here if needed
  ```
+ 调用 `createDefaultCallbacksProviderWithAwsCredentials` API 以创建基于静态 AWS 凭证的默认回调提供程序。

  ```
  CHK_STATUS(createDefaultCallbacksProviderWithAwsCredentials(accessKey,
                                                                  secretKey,
                                                                  sessionToken,
                                                                  MAX_UINT64,
                                                                  region,
                                                                  cacertPath,
                                                                  NULL,
                                                                  NULL,
                                                                  FALSE,
                                                                  &pClientCallbacks));
  ```
+ 调用 `createKinesisVideoClient` API 创建包含设备存储相关信息的`KinesisVideoClient`对象，并维护回调以报告 Kinesis Video Streams 事件。

  ```
  CHK_STATUS(createKinesisVideoClient(pDeviceInfo, pClientCallbacks, &clientHandle));                
  ```
+ 调用 `createKinesisVideoStreamSync` API 以创建 `KinesisVideoStream` 对象。

  ```
  CHK_STATUS(createKinesisVideoStreamSync(clientHandle, pStreamInfo, &streamHandle));                
  ```
+ 设置示例帧并调用 `PutKinesisVideoFrame` API 将该帧发送到 `KinesisVideoStream` 对象。

  ```
   // setup sample frame
      MEMSET(frameBuffer, 0x00, frameSize);
      frame.frameData = frameBuffer;
      frame.version = FRAME_CURRENT_VERSION;
      frame.trackId = DEFAULT_VIDEO_TRACK_ID;
      frame.duration = HUNDREDS_OF_NANOS_IN_A_SECOND / DEFAULT_FPS_VALUE;
      frame.decodingTs = defaultGetTime(); // current time
      frame.presentationTs = frame.decodingTs;
  
      while(defaultGetTime() > streamStopTime) {
          frame.index = frameIndex;
          frame.flags = fileIndex % DEFAULT_KEY_FRAME_INTERVAL == 0 ? FRAME_FLAG_KEY_FRAME : FRAME_FLAG_NONE;
          frame.size = SIZEOF(frameBuffer);
  
          CHK_STATUS(readFrameData(&frame, frameFilePath));
  
          CHK_STATUS(putKinesisVideoFrame(streamHandle, &frame));
          defaultThreadSleep(frame.duration);
  
          frame.decodingTs += frame.duration;
          frame.presentationTs = frame.decodingTs;
          frameIndex++;
          fileIndex++;
          fileIndex = fileIndex % NUMBER_OF_FRAME_FILES;
      }
  ```
+ 分解：

  ```
  CHK_STATUS(stopKinesisVideoStreamSync(streamHandle));
  CHK_STATUS(freeKinesisVideoStream(&streamHandle));
  CHK_STATUS(freeKinesisVideoClient(&clientHandle));
  ```

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



要运行并验证的代码[使用 C\$1\$1 制作人库](producer-sdk-cpp.md)，请执行以下操作：

1. 运行以下命令在[下载的 C SDK](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c.git) 中创建一个`build`目录，然后`cmake`从中启动：

   ```
   mkdir -p amazon-kinesis-video-streams-producer-c/build; 
   cd amazon-kinesis-video-streams-producer-c/build; 
   cmake ..
   ```

   您可以将以下选项传递给 `cmake ..`
   + `-DBUILD_DEPENDENCIES`-是否从源代码构建依赖库。
   + `-DBUILD_TEST=TRUE`-构建单元和集成测试。可能有助于确认对您的设备的支持。

     `./tst/webrtc_client_test`
   + `-DCODE_COVERAGE`-启用覆盖率报告。
   + `-DCOMPILER_WARNINGS`-启用所有编译器警告。
   + `-DADDRESS_SANITIZER`-使用构建 AddressSanitizer。
   + `-DMEMORY_SANITIZER`-使用构建 MemorySanitizer。
   + `-DTHREAD_SANITIZER`-使用构建 ThreadSanitizer。
   + `-DUNDEFINED_BEHAVIOR_SANITIZER`-使用构建 UndefinedBehaviorSanitizer。
   + `-DALIGNED_MEMORY_MODEL` -为仅对齐内存模型的设备构建。默认值为 `OFF`。

1. 导航到您在上一步中刚刚创建的`build`目录，然后运行`make`以构建 WebRTC C SDK 及其提供的示例。

   ```
   make                
   ```

1. 示例应用程序`kinesis_video_cproducer_video_only_sample`将文件夹`samples/h264SampleFrames`内的 h.264 编码视频帧发送到 Kinesis Video Streams。以下命令将视频帧循环发送到 Kinesis Video Streams 十秒钟：

   ```
   ./kinesis_video_cproducer_video_only_sample YourStreamName 10
   ```

   如果要从其他文件夹（例如`MyH264FramesFolder`）发送 H.264 编码的帧，请使用以下参数运行示例：

   ```
   ./kinesis_video_cproducer_video_only_sample YourStreamName 10 MyH264FramesFolder
   ```

1. 若要启用详细日志，请定义 `HEAP_DEBUG` 并通过取消 `CMakeList.txt` 中相应行的注释进行 `LOG_STREAMING` C 定义。

您可以在 IDE 中的调试输出中监控测试套件的进度。您还可以通过在 Amazon CloudWatch 控制台中查看与您的直播相关的指标来监控直播流量，例如`PutMedia.IncomingBytes`。

**注意**  
由于测试框架仅发送空字节的帧，因此，控制台不会将数据显示为视频流。

# 在树莓派上使用 C\$1\$1 制作器 SDK
<a name="producersdk-cpp-rpi"></a>

Raspberry Pi 是一个小型经济型计算机，可用于教授和学习基本计算机编程技能。本教程介绍如何在 Raspberry Pi 设备上设置和使用 Amazon Kinesis Video Streams C\$1\$1 制作器 SDK。这些步骤还包括如何使用 GStreamer 演示应用程序验证安装。

**Topics**
+ [先决条件](producersdk-cpp-rpi-prerequisites.md)
+ [创建有权写入 Kinesis Video Streams 的 IAM 用户](producersdk-cpp-rpi-iam.md)
+ [加入你的 Raspberry Pi 到 Wi-Fi 网络](producersdk-cpp-rpi-wifi.md)
+ [远程连接到你的 Raspberry Pi](producersdk-cpp-rpi-connect.md)
+ [配置树莓派摄像头](producersdk-cpp-rpi-camera.md)
+ [安装软件先决条件](producersdk-cpp-rpi-software.md)
+ [下载并构建 Kinesis Video Streams C\$1\$1 制作人 SDK](producersdk-cpp-rpi-download.md)
+ [将视频流式传输到你的 Kinesis 视频流](producersdk-cpp-rpi-run.md)
+ [播放 Kinesis 视频流中的媒体](producersdk-cpp-rpi-playback.md)
+ [解决适用于 Raspberry Pi 的 C\$1\$1 制作器 SDK](troubleshoot-rpi.md)

# 先决条件
<a name="producersdk-cpp-rpi-prerequisites"></a>

在 Raspberry Pi 上设置 C\$1\$1 制作器 SDK 之前，请确保满足以下先决条件：
+ 使用以下配置的 Raspberry Pi 设备：
  + 面板版本：3 B 型号或更高版本。
  + 连接的[摄像头模块](https://www.raspberrypi.com/documentation/accessories/camera.html)或连接的 USB 摄像头（网络摄像头）。
  + 至少具有 8 GB 容量的 SD 卡。
  + 已安装 Raspbian 操作系统 (内核版本 4.9 或更高版本)。你可以从 Raspberry Pi [网站下载最新的 Raspberry Pi 操作系统（以前称为 Raspb](https://www.raspberrypi.com/software/) ian）镜像。按照 Raspberry Pi 说明[在 SD 卡上安装下载的映像](https://www.raspberrypi.com/documentation/computers/getting-started.html#install-an-operating-system)。
+ 还有一个 AWS 账户 Kinesis 视频流。有关更多信息，请参阅 [Kinesis Video Streams 入门](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/getting-started.html)。

# 创建有权写入 Kinesis Video Streams 的 IAM 用户
<a name="producersdk-cpp-rpi-iam"></a>

如果您尚未这样做，请设置一个有权写入 Kinesis 视频流的 AWS Identity and Access Management (IAM) 用户。

这些步骤旨在帮助您快速开始使用 AWS 访问密钥（access key pair）。设备可以使用 X.509 证书进行连接。 AWS IoT有关如何将设备配置为使用基于证书的身份验证的更多信息，请参阅[使用控制对 Kinesis Video Streams 资源的访问权限 AWS IoT](how-iot.md)。

1. 登录 AWS 管理控制台 并打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在左侧的导航菜单中，选择**用户**。

1. 要创建新的用户，请选择**添加用户**。

1. 为用户提供一个描述性的**用户名**，例如 **kinesis-video-raspberry-pi-producer**。

1. 在**访问类型**下面，选择**编程访问**。

1. 选择**下一步: 权限**。

1. 在 “**为 kinesis-video-raspberry-pi-producer 设置权限**” 下，选择 “**直接附加现有策略**”。

1. 选择**创建策略**。将在新的 Web 浏览器选项卡中打开**创建策略**页。

1. 选择 **JSON** 选项卡。

1. 将以下 JSON 策略复制并粘贴到文本区域中。此政策允许您的用户创建数据并将其写入 Kinesis 视频流。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [{
       "Effect": "Allow",
         "Action": [
         "kinesisvideo:DescribeStream",
         "kinesisvideo:CreateStream",
         "kinesisvideo:GetDataEndpoint",
         "kinesisvideo:PutMedia"
       ],
       "Resource": [
         "*"
       ]
     }]
   }
   ```

------

1. 选择**查看策略**。

1. 为策略提供**名称**，例如 **kinesis-video-stream-write-policy**。

1. 选择**创建策略**。

1. 在浏览器中返回到**添加用户**选项卡，然后选择**刷新**。

1. 在搜索框中，键入创建的策略的名称。

1. 在列表中选中新策略旁边的复选框。

1. 选择 **Next: Review (下一步: 审核)**。

1. 选择 **Create user**。

1. 控制台将显示新用户的**访问密钥 ID**。选择**显示**以显示**秘密访问密钥**。记录这些值；在配置应用程序时，需要使用这些值。

# 加入你的 Raspberry Pi 到 Wi-Fi 网络
<a name="producersdk-cpp-rpi-wifi"></a>

如果使用连接的显示器和键盘，请转到 [配置树莓派摄像头](producersdk-cpp-rpi-camera.md)。

编写这些说明是为了帮助您在*无头*模式（即没有连接键盘、显示器或网线）下运行时设置 Raspberry Pi。按照以下说明将您的 Raspberry Pi 配置为自动尝试连接到指定网络，从而使您的主机能够通过 SSH 连接到该网络。

1. 在您的计算机上，创建一个名为 `wpa_supplicant.conf` 的文件。

1. 复制以下文本并将其粘贴到`wpa_supplicant.conf`文件中：

   ```
   country=US
   ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
   update_config=1
   
   network={
   ssid="Your Wi-Fi SSID"
   scan_ssid=1
   key_mgmt=WPA-PSK
   psk="Your Wi-Fi Password"
   }
   ```

   与 `ssid` 和 `psk` 值替换为您的 Wi-Fi 网络的信息。

1. 将 `wpa_supplicant.conf` 文件复制到 SD 卡中。必须将其复制到 `boot` 卷的根目录中。

1. 将 SD 卡插入到 Raspberry Pi，然后打开设备电源。它将加入您的 Wi-Fi 网络并启用 SSH。

# 远程连接到你的 Raspberry Pi
<a name="producersdk-cpp-rpi-connect"></a>

如果使用连接的显示器和键盘，请转到 [配置树莓派摄像头](producersdk-cpp-rpi-camera.md)。

编写这些说明是为了帮助您在*无头*模式（即没有连接键盘、显示器或网线）下运行时设置 Raspberry Pi。按照以下说明在网络上找到 Raspberry Pi，然后从主机通过 SSH 连接到它。

1. 在远程连接到您的 Raspberry Pi 设备之前，请执行以下操作之一以确定其 IP 地址：
   + 如果您有权访问您的网络的 Wi-Fi 路由器，请查看连接的 Wi-Fi 设备。查找名为 `Raspberry Pi` 的设备以查找您的设备的 IP 地址。
   + 如果您无权访问您的网络的 Wi-Fi 路由器，您可以使用其他软件查找您的网络上的设备。[Fing ](https://www.fing.com/) 是一个常用的应用程序，它适用于 Android 和 iOS 设备。您可以使用该应用程序的免费版本查找您的网络上的设备的 IP 地址。

1. 如果您知道 Raspberry Pi 设备的 IP 地址，您可以使用任何终端应用程序进行连接。
   + 在 macOS 或 Linux 上，使用 `ssh`：

     ```
     ssh pi@<IP address>
     ```
   + 在 Windows 上，使用 [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html)，这是一个适用于 Windows 的免费 SSH 客户端。

   对于新安装的 Raspbian，用户名为 **pi**，密码为 **raspberry**。建议您[更改默认密码](https://www.raspberrypi.com/documentation/computers/configuration.html#change-user-password-nonint)。

# 配置树莓派摄像头
<a name="producersdk-cpp-rpi-camera"></a>

按照以下步骤将 [Raspberry Pi 摄像头模块](https://www.raspberrypi.com/documentation/accessories/camera.html)配置为将视频从设备发送到 Kinesis 视频流。

**注意**  
如果您使用的是 USB 网络摄像头，请跳至[安装软件先决条件](producersdk-cpp-rpi-software.md)。

------
#### [ Camera module 1 ]

按照以下说明更新模块文件、启用相机接口并验证相机的功能。更新模块文件会告知 Raspberry Pi 在启动时要加载哪些内核模块。为了节省未使用摄像头的 Raspberry Pi 设备上的系统资源，默认情况下不会加载相机驱动程序。

1.  打开编辑器对模块文件进行更改。打开终端，使用以下命令使用编辑器`nano`编辑文件：

   ```
   sudo nano /etc/modules
   ```

1. 将以下行添加到文件结尾 (如果尚未存在)：

   ```
   bcm2835-v4l2
   ```

1. 保存文件，然后退出编辑器。要使用`nano`编辑器保存并退出，请使用 Ctrl\$1X。

1. 重启 Raspberry Pi：

   ```
   sudo reboot
   ```

1. 如果远程进行连接，在设备重启时，请通过终端应用程序再次连接到该设备。

1. 打开 `raspi-config`:

   ```
   sudo raspi-config
   ```

1. 选择 “**接口选项**”、“**旧版相机**”。**在旧版本的 Raspbian 操作系统中，此菜单选项可能位于 “**接口选项” “摄像头**” 下。**

   启用摄像机 (如果尚未启用)，并在出现提示时重启。

1. 键入以下命令以验证摄像机是否正常工作：

   ```
   raspistill -v -o test.jpg
   ```

   如果您的相机配置正确，则此命令会从相机捕获图像，将其保存到名为的文件中`test.jpg`，并显示信息性消息。

------
#### [ Camera module 2 or 3 ]

如果您使用的是摄像头模块 2，则使用`bcm2835-v4l2`（旧版）或`libcamera`（现代）。但是，建议使用`libcamera`堆栈以获得更好的支持和功能。请按照以下步骤确认您的系统`libcamera`已 up-to-date启用。

1. [libcamera](https://www.raspberrypi.com/documentation/computers/camera_software.html#libcamera) 应该预装在你的 Raspberry Pi 上。检查是否有任何更新并更新到最新版本，以获取错误修复和安全更新。打开终端并键入以下命令：

   ```
   sudo apt-get update
   sudo apt-get upgrade
   ```

1. 重新启动系统以使更新生效。

   ```
   sudo reboot
   ```

1. 测试你的相机。此应用程序启动摄像机预览流并将其显示在屏幕上。

   ```
   libcamera-hello
   ```

   如果您的摄像头模块有问题，请参阅 [Raspberry Pi 文档](https://raspberrypi.com/documentation/computers/camera_software.html#troubleshooting)进行故障排除。

------

# 安装软件先决条件
<a name="producersdk-cpp-rpi-software"></a>

C\$1\$1 制作器 SDK 要求你在 Raspberry Pi 上安装以下软件先决条件。

1. 更新软件包列表并安装构建 SDK 所需的库。打开终端并键入以下命令：

   ```
   sudo apt-get update
   sudo apt-get install -y \
     automake \
     build-essential \
     cmake \
     git \
     gstreamer1.0-plugins-base-apps \
     gstreamer1.0-plugins-bad \
     gstreamer1.0-plugins-good \
     gstreamer1.0-plugins-ugly \
     gstreamer1.0-tools \
     gstreamer1.0-omx-generic \
     libcurl4-openssl-dev \
     libgstreamer1.0-dev \
     libgstreamer-plugins-base1.0-dev \
     liblog4cplus-dev \
     libssl-dev \
     pkg-config
   ```

1. 如果您使用的是`libcamera`堆栈，请同时安装该`libcamerasrc` GStreamer 插件。默认情况下未安装此 GStreamer 插件。

   ```
   sudo apt-get install gstreamer1.0-libcamera
   ```

1. 将以下 PEM 文件复制到 `/etc/ssl/cert.pem` 中：

   ```
   sudo curl https://www.amazontrust.com/repository/AmazonRootCA1.pem -o /etc/ssl/AmazonRootCA1.pem
   sudo chmod 644 /etc/ssl/AmazonRootCA1.pem
   ```

# 下载并构建 Kinesis Video Streams C\$1\$1 制作人 SDK
<a name="producersdk-cpp-rpi-download"></a>

按照以下步骤下载和构建 [Kinesis Video Streams C\$1\$1 制作人 S](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp) DK。确保已安装软件必备组件；有关这些步骤[安装软件先决条件](producersdk-cpp-rpi-software.md)，请参阅。

1. 导航到下载目录。打开终端并切换到您的首选下载目录。

   例如：

   ```
   cd ~/Downloads
   ```

1. 克隆 SDK 存储库。使用`git clone`命令从 GitHub 存储库下载 SDK。类型：

   ```
   git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp.git --single-branch -b master kvs-producer-sdk-cpp
   ```

   此命令仅克隆一个分支（分`master`支），从而减少了下载大小和时间。它还会将下载的内容放在当前目录`kvs-producer-sdk-cpp`中名为的文件夹中。

1. 验证下载。克隆过程完成后，列出该`kvs-producer-sdk-cpp`文件夹的内容以验证 SDK 是否已下载。

   ```
   ls kvs-producer-sdk-cpp
   ```

1. 准备一个构建目录。类型：

   ```
   mkdir -p kvs-producer-sdk-cpp/build
   cd kvs-producer-sdk-cpp/build
   ```

1. 配置构建。运行以下`cmake`命令以使用特定选项配置构建环境：

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

   [CMake](https://cmake.org/cmake/help/latest/manual/cmake.1.html)使用以下选项生成相应的`Makefiles`：
   + 使用项目文件夹 (`..`) 作为源目录。
   + 使用当前目录 (`.`) (`build/`) 生成输出。
   + `-DBUILD_GSTREAMER_PLUGIN=ON`启用 GStreamer 插件 kvssink 的构建。
   + `-DBUILD_DEPENDENCIES=OFF`禁止从源代码构建外部依赖关系。该项目将查找并使用上一步中安装的外部依赖项。
   + `-DALIGNED_MEMORY_MODEL=ON`禁用未对齐的内存模型。某些 Raspberry Pi 设备不支持未对齐的内存访问。
**注意**  
有关 CMake 参数的完整列表，请参阅[下载并配置 C\$1\$1 制作器库代码](producersdk-cpp-download.md)。

1. 构建项目。配置完版本后，使用`make`命令使用`Makefile`生成的进行编译`cmake`。

   ```
   make -j$(nproc)
   ```

   的`-j`参数`make`允许它并行运行多个编译作业。要缩短构建时间，请使用`nproc`命令动态计算 Raspberry Pi 上的 CPU 内核数量。

1. 确认`libgstkvssink.so`存在。

   列出当前目录中的文件。

   **提示：**

   ```
   ls
   ```

   **响应：**

   ```
   CMakeCache.txt       dependency                          kvs_gstreamer_sample
   CMakeFiles           kvs_gstreamer_audio_video_sample    kvssink_gstreamer_sample
   Makefile             kvs_gstreamer_file_uploader_sample  libKinesisVideoProducer.so
   cmake_install.cmake  kvs_gstreamer_multistream_sample    libgstkvssink.so
   ```

1. 确认 GStreamer 可以加载`kvssink`。

   将`GST_PLUGIN_PATH`环境变量设置为包含的目录`libgstkvssink.so`。

   ```
   export GST_PLUGIN_PATH=`pwd`
   ```

   有 GStreamer 负载`kvssink`：

   ```
   gst-inspect-1.0 kvssink
   ```

   你应该看到一些相关的文档`kvssink`。使用箭头键进行导航，然后`q`按退出。

1. （**可选**）更新 shell 的启动脚本以包括设置`GST_PLUGIN_PATH`环境变量。这样可以确保`GST_PLUGIN_PATH`在新的终端会话期间正确设置。在 Raspberry Pi 设备上，外壳程序的启动脚本是`~/.bashrc`。

   运行以下命令将该命令附加到 shell 启动脚本的末尾。

   ```
   echo "export GST_PLUGIN_PATH=~/Downloads/kvs-producer-sdk-cpp/build" >> ~/.bashrc
   ```

   键入以下命令来运行 shell 的启动脚本，或者关闭当前 shell 并打开一个新的 shell。

   ```
   source ~/.bashrc
   ```

   确认`GST_PLUGIN_PATH`已设置，即可加载`kvssink`。

   ```
   echo $GST_PLUGIN_PATH
   ```

   ```
   gst-inspect-1.0 kvssink
   ```

# 将视频流式传输到你的 Kinesis 视频流
<a name="producersdk-cpp-rpi-run"></a>

要运行示例应用程序，您需要具有以下信息：
+ 在[先决条件](producersdk-cpp-rpi-prerequisites.md)一节中创建的流的名称。
+ 在[创建有权写入 Kinesis Video Streams 的 IAM 用户](producersdk-cpp-rpi-iam.md)中创建的账户凭证 (访问密钥 ID 和秘密访问密钥)。
+ GStreamer 能够找到`kvssink`插件。请参阅[下载并构建 Kinesis Video Streams C\$1\$1 制作人 SDK](producersdk-cpp-rpi-download.md)了解更多信息。

1. 设置凭证和区域。

   ```
   export AWS_ACCESS_KEY_ID=YourAccessKey
   export AWS_SECRET_ACCESS_KEY=YourSecretKey
   export AWS_DEFAULT_REGION=us-west-2
   ```

   有关其他身份验证方法，请参阅[向提供凭证 `kvssink`](examples-gstreamer-plugin-parameters.md#credentials-to-kvssink)。
**注意**  
默认情况下，C\$1\$1 制作器 SDK 使用美国西部（俄勒冈`us-west-2`）() 区域。要使用默认设置，请在美国西部（俄勒冈）地区 AWS 区域 创建您的 Kinesis 视频流。  
要在 Kinesis 视频流中使用不同的区域，请将以下环境变量设置为您的区域（例如）：*us-east-1*  

   ```
   export AWS_DEFAULT_REGION=us-east-1 
   ```

1. 根据您的输入媒体，选择以下选项之一：

------
#### [ Sample GStreamer video ]

   该 GStreamer 管道生成具有标准测试模式的实时测试视频流，该视频流以每秒 10 帧的速度运行，分辨率为 640x480 像素。添加了一个显示当前系统时间和日期的叠加层。然后将视频编码为 H.264 格式，最多每 10 帧生成关键帧，从而使片段持续时间（也称为一组图片 (GoP) 大小）为 1 秒。kvssink 获取 H.264 编码的视频流，将其打包为 Matroska (MKV) 容器格式，然后将其上传到您的 Kinesis 视频流。

   运行如下命令：

   ```
   gst-launch-1.0 -v videotestsrc is-live=true \
     ! video/x-raw,framerate=10/1,width=640,height=480 \
     ! clockoverlay time-format="%a %B %d, %Y %I:%M:%S %p" \
     ! x264enc bframes=0 key-int-max=10 \
     ! h264parse \
     ! kvssink stream-name="YourStreamName"
   ```

   要停止 GStreamer 管道，请选择终端窗口并**按 CTRL\$1C**。

   示例视频 GStreamer 管道如下所示：

![\[带有叠加日期和时间戳的标准测试模式的图像。\]](http://docs.aws.amazon.com/zh_cn/kinesisvideostreams/latest/dg/images/sample-video.png)


------
#### [ USB web cam ]

   运行以下命令以 GStreamer 自动检测您的 USB 摄像头：

   ```
   gst-launch-1.0 autovideosrc \
     ! videoconvert \
     ! video/x-raw,format=I420,width=640,height=480 \
     ! x264enc bframes=0 key-int-max=45 tune=zerolatency byte-stream=true speed-preset=ultrafast \
     ! h264parse \
     ! video/x-h264,stream-format=avc,alignment=au,profile=baseline \
     ! kvssink stream-name="YourStreamname"
   ```

   要停止 GStreamer 管道，请选择终端窗口并**按 CTRL\$1C**。

   与其让 GStreamer 自动检测，不如`v4l2src`使用特定的设备标识符。运行如下命令：

   ```
   gst-device-monitor-1.0
   ```

   在输出中，您将看到一些设备以及有关如何使用该设备的 GStreamer 管道的开始：

   ```
   Device found:
   
       name  : H264 USB Camera: USB Camera
       class : Video/Source
       caps  : video/x-h264, stream-format=(string)byte-stream, alignment=(string)au, width=(int)1920, height=(int)1080, pixel-aspect-ratio=(fraction)1/1, colorimetry=(string){ 2:4:7:1 }, framerate=(fraction){ 30/1, 25/1, 15/1 };
               ...
       properties:
           device.path = /dev/video4
           udev-probed = false
           device.api = v4l2
           v4l2.device.driver = uvcvideo
           v4l2.device.card = "H264\ USB\ Camera:\ USB\ Camera"
           v4l2.device.bus_info = usb-3f980000.usb-1.3
           v4l2.device.version = 265767 (0x00040e27)
           v4l2.device.capabilities = 2216689665 (0x84200001)
           v4l2.device.device_caps = 69206017 (0x04200001)
       gst-launch-1.0 v4l2src device=/dev/video4 ! ...
   ```

   要停止 GStreamer 管道，请选择终端窗口并**按 CTRL\$1C**。

------
#### [ Raspberry Pi camera module 1 ]

   如果您使用的是 Pi 摄像头模块 1 或 Pi 摄像头模块 2`bcm2835-v4l2`，请使用以下内容：

   ```
   gst-launch-1.0 v4l2src device=/dev/video0 \
     ! videoconvert \
     ! video/x-raw,format=I420,width=640,height=480 \
     ! x264enc bframes=0 key-int-max=45 bitrate=500 tune=zerolatency \
     ! h264parse ! video/x-h264,stream-format=avc,alignment=au,profile=baseline \
     ! kvssink stream-name="YourStreamname"
   ```

   要停止 GStreamer 管道，请选择终端窗口并**按 CTRL\$1C**。

------
#### [ Raspberry Pi camera module 2 or 3 ]

   如果您使用的是现代`libcamera`堆栈，请使用以下 GStreamer 管道：

   ```
   gst-launch-1.0 libcamerasrc \
     ! video/x-raw,width=640,height=480,framerate=30/1,format=I420 \
     ! videoconvert \
     ! x264enc speed-preset=ultrafast tune=zerolatency byte-stream=true key-int-max=75 \
     ! video/x-h264,level='(string)4' \
     ! h264parse \
     ! video/x-h264,stream-format=avc,alignment=au,width=640,height=480,framerate=30/1 \
     ! kvssink stream-name="YourStreamname"
   ```

   要停止 GStreamer 管道，请选择终端窗口并**按 CTRL\$1C**。

------
#### [ Sample RTSP camera ]

   在本示例中，我们使用 Gst-Rtsp-Server在本地托管演示 RTSP 摄像机源。然后，我们构建一个 GStreamer 管道，将 RTSP 摄像机源上传到指定的 Kinesis 视频流。

   **在 Raspberry Pi Gst-Rtsp-Server 上进行设置**

   1. 安装必要的依赖库来构建 Gst-Rtsp-Server项目。确保您还安装了软件必备组件。在终端中键入以下内容：

      ```
      sudo apt-get update
      sudo apt-get install libgstrtspserver-1.0
      ```

   1. 在你的 Raspberry Pi GStreamer 上下载 1.22 版本。

      ```
      git clone https://gitlab.freedesktop.org/gstreamer/gstreamer.git --single-branch -b 1.22
      ```

   1. 将目录更改为中的示例目录 gst-rtsp-server。

      ```
      cd gstreamer
      cd subprojects
      cd gst-rtsp-server
      cd examples
      ```

   1. 使用 gcc 将 test-launch.c 编译成名为 test-launch 的可执行文件。

      ```
      gcc -o test-launch test-launch.c `pkg-config --cflags --libs gstreamer-rtsp-server-1.0`
      ```

   1. 使用以下参数运行可执行文件。注意：首次加载 GStreamer 可能需要一些时间。

      ```
      ./test-launch "videotestsrc is-live=true ! video/x-raw,height=480,width=640,framerate=10/1 ! videoconvert ! x264enc tune=zerolatency bitrate=512 key-int-max=25 bframes=0 ! h264parse ! rtph264pay ! name=pay0 pt=96"
      ```

      您应看到以下输出：

      ```
      stream ready at rtsp://127.0.0.1:8554/test
      ```

   1. 验证 RTSP 视频流。您可以使用任何 RTSP 查看器。例如，VLC 媒体播放器。要使用 VLC 媒体播放器观看直播，请打开新终端并键入：

      ```
      sudo apt-get install vlc
      ```

      安装 VLC 媒体播放器。然后键入：

      ```
      vlc rtsp://127.0.0.1:8554/test
      ```

      应该会弹出一个包含直播的 VLC 窗口。如果不是，请检查测试启动可执行文件是否仍在运行，并检查输出是否存在任何错误。

      验证 RTSP 流的另一种方法是使用 gst-discoverer-1.0 实用程序。类型：

      ```
      gst-discoverer-1.0 "rtsp://127.0.0.1:8554/test"
      ```

      预期的输出如下所示：

      ```
      Analyzing rtsp://127.0.0.1:8554/test
      Done discovering rtsp://127.0.0.1:8554/test
      
      Properties:
        Duration: 99:99:99.999999999
        Seekable: no
        Live: yes
        unknown #0: application/x-rtp
          video #1: H.264 (Constrained Baseline Profile)
            Stream ID: 359314d7d4bba383223927d7e57d4244d0800e629c626be81c505055c62170e2/video:0:0:RTP:AVP:96
            Width: 640
            Height: 480
            Depth: 24
            Frame rate: 10/1
            Pixel aspect ratio: 1/1
            Interlaced: false
            Bitrate: 0
            Max bitrate: 0
      ```

   **使用 kvssink 将 RTSP 提要发送到你的 Kinesis 视频流**

   此 GStreamer 管道用于连接`rtspsrc`到 RTSP 服务器以获取 RTP 视频流。它将帧传递给`rtph264depay`，后者从 RTP 数据包中提取出 H.264 编码的视频帧。 `h264parse`将视频帧分组为`kvssink`可以理解的格式。 `kvssink`获取 H.264 编码的视频流，将其打包为 Matroska (MKV) 容器格式，然后将其上传到你的 Kinesis 视频流中。

   运行如下命令：

   ```
   gst-launch-1.0 -v rtspsrc location="rtsp://127.0.0.1:8554/test" short-header=true \
     ! rtph264depay \
     ! h264parse \
     ! video/x-h264,format=avc,alignment=au \
     ! kvssink stream-name="YourStreamName"
   ```

   要停止 GStreamer 管道，请选择终端窗口并**按 CTRL\$1C**。

------

## 利用硬件
<a name="producersdk-cpp-rpi-utilize"></a>

某些 Raspberry Pi 型号带有硬件加速的 H.264 编码器。你可以用它们来代替`x264enc`，后者是一个软件编码器。

1. 确保 GStreamer 插件已安装：

   ```
   sudo apt-get install gstreamer1.0-tools gstreamer1.0-plugins-bad
   ```

1. 类型：

   ```
   gst-inspect-1.0 | grep h264
   ```

   确定以下元素是否可用：
   + omxh264enc
   + v4l2h264enc

   如果它们可用，你可以使用它们。以下是一些使用这些元素的管道示例：

   **`omxh264enc`:**

   ```
   gst-launch-1.0 v4l2src device=/dev/video0 \
     ! videoconvert \
     ! video/x-raw,format=I420,width=640,height=480 \
     ! omxh264enc control-rate=2 target-bitrate=512000 periodicity-idr=45 inline-header=FALSE \
     ! h264parse ! video/x-h264,stream-format=avc,alignment=au,profile=baseline \
     ! kvssink stream-name="raspberry"
   ```

   **`v4l2h264enc`和`v4l2convert`：**

   ```
   gst-launch-1.0 libcamerasrc \
     ! video/x-raw,width=640,height=480,framerate=30/1,format=I420 \
     ! v4l2convert \
     ! v4l2h264enc extra-controls="controls,repeat_sequence_header=1" \
     ! video/x-h264,level='(string)4' \
     ! h264parse \
     ! video/x-h264,stream-format=avc,alignment=au,width=640,height=480,framerate=30/1 \
     ! kvssink stream-name="test-stream"
   ```

## 运行时问题
<a name="rpi-troubleshoot-runtime"></a>

以下是一些经常遇到的运行时问题以及如何解决这些问题。

### 没有这样的元素 “xxxxxxxxx”
<a name="rpi-troubleshoot-missing-plugin"></a>

如果你收到类似以下的错误，那就意味着你缺少了一个 GStreamer插件：

```
WARNING: erroneous pipeline: no element "videoconvert"
```

**解决方法：**

根据缺少哪个元素，确定相应的操作：
+ `kvssink`: 请参阅[下载并构建 Kinesis Video Streams C\$1\$1 制作人 SDK](producersdk-cpp-rpi-download.md)。
+ `libcamerasrc`: [“缓冲池激活失败” 错误](#rpi-troubleshoot-buffer) 要安装该`libcamerasrc` GStreamer 元素，请参阅。
+ `omxh264enc` 或 `v4l2h264enc`：

  [安装软件先决条件](producersdk-cpp-rpi-software.md)按照步骤安装所有 GStreamer 库。如果你已经全部安装了它们但这些元素没有出现，那就意味着你的 Raspberry Pi 没有硬件。`x264enc`改用软件编码器。
+ 其他：[安装软件先决条件](producersdk-cpp-rpi-software.md)按照操作安装所有 GStreamer 库。在不同的 GStreamer 插件组中可以找到不同的 GStreamer 元素（好、坏、丑），因此请务必全部安装它们。

### “缓冲池激活失败” 错误
<a name="rpi-troubleshoot-buffer"></a>

如果您收到类似以下的错误，则表示正在使用的管道正在使用`v4l2src`，但应该`libcamerasrc`改用。

```
ERROR bufferpool gstbufferpool.c:572:gst_buffer_pool_set_active:source:pool0:src start failed
WARN v4l2src gstv4l2src.c:976:gst_v4l2src_decide_allocation: error: Failed to allocate required memory.
WARN v4l2src gstv4l2src.c:976:gst_v4l2src_decide_allocation: error: Buffer pool activation failed
WARN basesrc gstbasesrc.c:3352:gst_base_src_prepare_allocation: Subclass failed to decide allocation
Error received from element source: Failed to allocate required memory.
WARN basesrc gstbasesrc.c:3132:gst_base_src_loop: error: Internal data stream error.
Debugging information: ../sys/v4l2/gstv4l2src.c(976): gst_v4l2src_decide_allocation (): /GstPipeline:live-kinesis-pipeline/GstV4l2Src:source:
Buffer pool activation failed
WARN basesrc gstbasesrc.c:3132:gst_base_src_loop: error: streaming stopped, reason not-negotiated (-4)
```

例如，如果您在未`libcamerasrc`安装摄像头模块 2 的情况下使用以下管道，则在尝试自动检测要使用哪些元素时 GStreamer 可能会遇到此错误。

```
gst-launch-1.0 autovideosrc ! videoconvert ! autovideosink
```

**解决方法：**

确保`libcamerasrc`已安装并使用它作为源元素，而不是`v4l2src`。键入以下内容来安装该`libcamerasrc` GStreamer 元素：

```
sudo apt-get update
sudo apt-get install gstreamer1.0-libcamera
```

安装完成后`libcamerasrc`，如果您正在使用该`autovideosrc`元素，则 GStreamer 应自动切换为使用正确的来源，`libcamerasrc`而不是`v4l2src`。

### 总线错误
<a name="rpi-troubleshoot-bus"></a>

如果您在启动后不久`kvssink`（通常在 HTTP 调用`PutMedia`完成时）收到总线错误，则表示您的 Raspberry Pi 不支持未对齐的内存访问。日志将如下所示：

```
INFO Camera camera.cpp:1197 configuring streams: (0) 640x480-YUV420
INFO RPI pisp.cpp:1450 Sensor: /base/axi/pcie@120000/rp1/i2c@88000/imx708@1a - Selected sensor format: 1536x864-SBGGR10_1X10 - Selected CFE format: 1536x864-PC1B
[INFO ] kinesisVideoStreamFormatChanged(): Stream format changed.
[DEBUG] setRequestHeader(): Appending header to request: user-agent -> AWS-SDK-KVS-CPP-CLIENT/3.4.2/1.5.3 GCC/12.2.0 Linux/6.6.51+rpt-rpi-v8 aarch64 CPPSDK
[DEBUG] setRequestHeader(): Appending header to request: x-amzn-stream-name -> demo-stream
[DEBUG] setRequestHeader(): Appending header to request: x-amzn-producer-start-timestamp -> 1732012345.678
[DEBUG] setRequestHeader(): Appending header to request: x-amzn-fragment-acknowledgment-required -> 1
[DEBUG] setRequestHeader(): Appending header to request: x-amzn-fragment-timecode-type -> ABSOLUTE
[DEBUG] setRequestHeader(): Appending header to request: transfer-encoding -> chunked
[DEBUG] setRequestHeader(): Appending header to request: connection -> keep-alive
[INFO ] putStreamResultEvent(): Put stream result event. New upload handle 0
[WARN ] notifyDataAvailable(): [demo-stream] Failed to un-pause curl with error: 43. Curl object 0xe2f6f418
Bus error
```

Kinesis Video Streams PIC 使用未对齐的内存访问来优化内存使用情况，但并非所有设备都支持这种方式。

**解决方法：**

要在对齐的内存访问模式下使用 SDK，您需要在编译`ON`时将该`ALIGNED_MEMORY_MODEL` CMake 标志明确设置为`kvssink`，因为它默认为`OFF`。[下载并构建 Kinesis Video Streams C\$1\$1 制作人 SDK](producersdk-cpp-rpi-download.md)有关更多详细说明，请参阅。

### 时间戳冻结，管道停滞
<a name="rpi-troubleshoot-pipeline"></a>

在 GStreamer 管道`x264enc`中使用时，您可能会遇到管道的时间表在几秒钟内显著减慢或完全停滞的情况。

之所以出现这种情况，是因为`x264enc`默认设置会引入较高的编码延迟，这会超过默认输入缓冲区的容量。结果，输入缓冲区被填满，导致上游元素阻塞，管道停滞。

有关详情，请参阅 [GStreamer 文档](https://gstreamer.freedesktop.org/documentation/x264/index.html?gi-language=c)。

**解决方法：**

`x264enc`使用`zerolatency`调整选项进行配置。这通过针对实时场景进行优化，确保帧的处理和输出速度更快，从而显著减少了编码延迟。

示例配置：

```
... ! x264enc tune=zerolatency byte-stream=true speed-preset=ultrafast bframes=0 key-int-max=60 ! ...
```

**注意**  
虽然此解决方案可以有效防止流水线停滞，但它可能会影响编码效率和质量。对于同时需要低延迟和高质量的场景，可以考虑其他方法，例如使用硬件优化或寻找可以直接输出 H.264 的网络摄像头，跳过此编码步骤。  
有关更多信息，请参阅 [利用硬件](#producersdk-cpp-rpi-utilize)。

### 无法同时在同一台`v4l2`设备上运行多个管道
<a name="rpi-troubleshoot-multiple-pipelines"></a>

诸如之类的设备一次`/dev/video0`只能由一个进程访问。如果多个进程尝试同时访问它，则第二个进程会等到第一个进程完成。

**解决方法：**

创建环回设备，允许多个进程同时使用环回接口。有关更多信息，请参阅[堆栈交换](https://raspberrypi.stackexchange.com/questions/19630/take-picam-image-while-motion-is-running/19897#19897)。

### 内部数据流错误
<a name="rpi-troubleshoot-internal-error"></a>

创建 GStreamer 管线时，通过将一个元素的源焊盘链接到另一个元素的吸盘来连接元素。这种链接过程允许数据从源元素流向接收器元素，从而形成数据管道。

日志中的错误消息 “Pad link failed” 表示尝试在管道中两个元素的焊盘之间建立连接（链接）时 GStreamer遇到了问题。

```
Pad link failed
Error received from element udpsrc0: Internal data stream error.
```

**解决方法：**

确定哪些元素无法相互关联。要缩小管道范围，请从管道中移除元素。将最右边的元素替换为`fakesink`并逐个移除元素。

您可能需要调整 c [apsfilter](https://gstreamer.freedesktop.org/documentation/coreelements/capsfilter.html?gi-language=c) 元素， and/or 更改管道使用的元素。

常见的情况是要求相机不支持`framerate`或`resolution`相机不支持。`gst-device-monitor-1.0`在终端中使用以获取支持的`framerates``resolutions`、和`formats`。你可以使用 [videoscal](https://gstreamer.freedesktop.org/documentation/videoconvertscale/videoscale.html?gi-language=c) e GStreamer 元素来调整视频分辨率，使用 [videorate](https://gstreamer.freedesktop.org/documentation/videorate/?gi-language=c) 来调整视频帧速率。

要检查单个 GStreamer 元素支持的格式，请在终端`gst-inspect-1.0 element-name`中键入。

# 播放 Kinesis 视频流中的媒体
<a name="producersdk-cpp-rpi-playback"></a>

打开 [Kinesis Video St](https://console.aws.amazon.com//kinesisvideo/home/) **reams 控制台，**然后为你创建的直播选择直播名称。

将在控制台中显示从 Raspberry Pi 发送的视频流。

**注意**  
视频可能需要几秒钟才能显示在控制台中。

直播开始播放后，你可以在控制台中尝试以下功能：
+ 在 **Video preview** (视频预览) 部分中，使用导航控件后退和快进流。
+ 在**直播信息**部分，查看直播的编解码器、分辨率和比特率。Raspberry Pi 上的分辨率和比特率值被故意设置为较低，以最大限度地减少本教程的带宽使用量。

  要查看正在为您的直播创建的 Amazon CloudWatch 指标，请在中选择**查看直播指标 CloudWatch**。
+ 在 **Data retention period** (数据保留期) 下面，可以看到视频流保留 1 天。您可以编辑该值并将其设置为 **No data retention** (不保留数据)，或者设置 1 天到几年之间的值。
+ 在**服务器端加密**下，请注意，您的数据是使用由 AWS Key Management Service (AWS KMS) 维护的密钥进行静态加密的。

## 播放问题
<a name="rpi-troubleshoot-playback"></a>

以下是一些经常遇到的播放问题以及如何解决这些问题。

### 没有媒体，但日志中有 PERSITED Ack
<a name="rpi-troubleshoot-no-media"></a>

如果你在日志中看到 PERSISTED Acks，则表示 Kinesis Video Streams 已成功摄取并存储了上传的媒体。`kvssink`从 Kinesis Video Streams 收到的 acks 看起来像这样。在 JSON 中，查看`"EventType"`密钥的值。

```
{"EventType":"RECEIVED","FragmentTimecode":252200,"FragmentNumber":"12345678901234567890123456724587702494771079511"}
{"EventType":"BUFFERING","FragmentTimecode":252467,"FragmentNumber":"12345678901234567890123456781729223736853277017"}
{"EventType":"RECEIVED","FragmentTimecode":252467,"FragmentNumber":"12345678901234567890123456781729223736853277017"}
{"EventType":"BUFFERING","FragmentTimecode":253000,"FragmentNumber":"12345678901234567890123456738870744847093249408"}
{"EventType":"PERSISTED","FragmentTimecode":252200,"FragmentNumber":"12345678901234567890123456724587702494771079511"}
{"EventType":"PERSISTED","FragmentTimecode":252467,"FragmentNumber":"1234567890123456789012345671729223736853277017"}
```

**解决方法：**

在 Kinesis Video Streams 控制台中等待一两分钟，然后使用双右箭头。如果未显示任何媒体，请确认您的直播已发送到正确的区域，并检查直播名称的拼写。你可以在日志中找到这些信息。

[提供一个区域给 `kvssink`](examples-gstreamer-plugin-parameters.md#kvssink-region)有关 kvssink 如何确定要使用哪个区域的更多信息，请参阅。

### 媒体需要很长时间才能加载到 AWS 管理控制台
<a name="rpi-troubleshoot-load-time"></a>

**重要**  
主机播放体验与 HLS 和 DASH 的播放体验不同。也可以使用中的示例媒体播放器[托管的网页](https://aws-samples.github.io/amazon-kinesis-video-streams-media-viewer/) GitHub 来测试播放。该网页的源代码可以[在这里](https://github.com/aws-samples/amazon-kinesis-video-streams-media-viewer)找到。

由于网络带宽差或设备受限，控制台中的媒体加载速度可能很慢，但也可能与视频编码和分段有关。

**视频编码基础知识：**
+ H.264 和 H.265 编码器使用关键帧（I 帧）和预测帧（P 帧）来实现高效压缩。
+ 关键帧包含完整的图像数据，而 P 帧仅包含与之前帧相比的更改。
+ “关键帧间隔” 决定了关键帧在视频流中出现的频率。

**直播中的碎片：**
+ 在 Kinesis Video Streams 中，新的片段从每个关键帧开始。有关更多信息，请参阅 [Kinesis Video Streams 数据模型](how-data.md)。
+ *片段长度（以秒为单位）可以估计为：*关键帧间隔 ^帧速*率*

  **示例**：

  对于关键帧间隔为 30、帧速为 15 fps 的直播：

  片段长度 = 30 ε 15 = 2 秒

由于键帧间隔较大，较长的片段会增加流媒体的延迟。

**解决方法：**

要缩短加载时间，请考虑缩短关键帧间隔。这将创建更短的片段，从而减少延迟，但也会增加视频文件的大小。

对于`x264enc` GStreamer 元素，您可以通过属性显式设置关键帧间隔：`key-int-max`

```
x264enc bframes=0 key-int-max=60
```

查看日志输出时，请注意上传客户端 ACKs从 Kinesis Video Streams 接收日志的频率。生成的关键帧越多，返回的关键帧 ACKs 就越多。

### 媒体失真或有伪影
<a name="rpi-troubleshoot-distortion"></a>

要解决此问题，请确保所有电缆都连接紧密。查看相机模块的输出`libcamera-hello`（或`raspistill`传统的 Pi 相机）。

在您的 GStreamer 管道中，`kvssink`使用`autovideosink`或`matroskamux`和替换`filesink`。例如：

```
... x264enc tune=zerolatency speed-preset=ultrafast bframes=0 key-int-max=60 byte-stream=true ! h264parse ! matroskamux ! filesink location=output.mkv 
```

查看使用时打开的媒体播放器的输出文件`autovideosink`，看看是否还有伪影。`filesink`

另请查看以下管道的输出：

```
gst-launch-1.0 autovideosrc ! videoconvert ! autovideosink
```

在管道中添加元素（例如 [dewarp](https://gstreamer.freedesktop.org/documentation/opencv/dewarp.html?gi-language=c)）可以校正 fish eye 相机的输出。

查看相机支持的输出编解码器，并根据需要调整元素。

例如，如果您的 USB 摄像头仅支持 JPEG 输出，则需要使用`jpegparse`和`jpegdec`元素来转换媒体，然后再使用将其编码为 H.264。`x264enc`在 GStreamer 论坛上搜索其他具有类似管道和/或网络摄像头设置的用户的帮助。

# 解决适用于 Raspberry Pi 的 C\$1\$1 制作器 SDK
<a name="troubleshoot-rpi"></a>

如果您遇到构建问题并想尝试不同的 CMake 参数，请确保执行干净的构建。在重试之前 `open-source``dependency`，请删除、和`build`文件夹。

## 使用 OpenSSL 构建问题
<a name="troubleshoot-rpi-build"></a>

如果您收到类似以下内容的输出，则表明 OpenSSL 未正确检测到您的系统架构。

```
crypto/md5/md5-aarch64.S: Assembler messages:
crypto/md5/md5-aarch64.S:3: Error: unrecognized symbol type ""
crypto/md5/md5-aarch64.S:6: Error: bad instruction `stp x19,x20,[sp,#-80]!'
crypto/md5/md5-aarch64.S:7: Error: bad instruction `stp x21,x22,[sp,#16]'
crypto/md5/md5-aarch64.S:8: Error: bad instruction `stp x23,x24,[sp,#32]'
crypto/md5/md5-aarch64.S:9: Error: bad instruction `stp x25,x26,[sp,#48]'
```

在此示例中，它正在尝试构建 64 位版本 (`linux-aarch64`)，而这个 Raspberry Pi 实际上是 32 位。某些 Raspberry Pi 设备具有 64 位内核，但有 32 位用户空间。

确定 OpenSSL 正在尝试为哪个架构构建。你可以在 OpenSSL 的`configure`步骤中找到日志行：

```
[ 33%] Performing update step for 'project_libopenssl'
-- Already at requested tag: OpenSSL_1_1_1t
[ 44%] No patch step for 'project_libopenssl'
[ 55%] Performing configure step for 'project_libopenssl'
Operating system: x86_64-whatever-linux2
Configuring OpenSSL version 1.1.1t (0x1010114fL) for linux-x86_64
Using os-specific seed configuration
Creating configdata.pm
Creating Makefile
```

验证您的系统架构：
+ 查看内核位数：运行 `uname -m`
+ 查看用户空间位数：运行 `getconf LONG_BIT`

您也可以使用`cat /proc/cpuinfo`或`lscpu`命令查看您的 CPU 信息。

**解决方法：**

要解决此问题，请在构建时添加以下 CMake 参数，以确保 OpenSSL 正确构建 32 位 ARM 架构：

```
-DBUILD_OPENSSL_PLATFORM=linux-armv4 
```

## 对中的`kvssink`加载问题进行故障排除 GStreamer
<a name="troubleshoot-rpi-kvssink"></a>

确认 `GST_PLUGIN_PATH`

确保当前 shell 会话中的`GST_PLUGIN_PATH`环境变量指向包含的目录`kvssink`。环境变量是特定于会话的，因此您需要为每个新会话设置它们。要使此更改永久化，请参阅 “更新外壳程序的启动脚本以包括设置 GST\$1PLUGIN\$1PATH 环境变量”。

**错误：无法打开共享目标文件：没有这样的文件或目录**

如果遇到错误`Cannot open shared object file: No such file or directory`，请运行以下命令：

```
gst-inspect-1.0 /path/to/libgstkvssink.so
```

如果您收到以下输出，则表示动态链接器找不到所需的`kvssink`库。这通常是由于：
+ 搬`kvssink`到与建造地不同的位置。
+ 针对错误的 CPU 架构进行交叉编译。
+ 缺少必需的依赖关系。

**输出**：

```
WARNING: erroneous pipeline: no element "kvssink"
error while loading shared libraries: libcproducer.so: cannot open shared object file: No such file or directory
```

**解决方法：**

对于**已移动的库**，请将包含缺失库的目录添加到`LD_LIBRARY_PATH`。

在原始存储库的根目录中，您可以使用该`find`实用程序找到缺失的库。在终端中，键入：

```
find . -name "*libcproducer*" 
```

**输出**：

```
./build/dependency/libkvscproducer/kvscproducer-src/libcproducer.so
```

Linux 设备上的文件路径分隔符是`:`。以下命令将新的文件夹路径附加到现有`LD_LIBRARY_PATH`环境变量，同时保留之前的所有值。

在您的终端中，键入：

```
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/build/dependency/libkvscproducer/kvscproducer-src
```

**重要**  
环境变量是特定于会话的。要在会话之间保留更改，请修改 shell 的启动脚本。

您可能还需要将添加`open-source/local/lib`到`$LD_LIBRARY_PATH`。

**错误：。 /path/to/libcproducer.so.1: ELF 标头无效**

如果您在加载**共享库**时收到此错误，则可能是由于符号链接损坏 (`symlinks`) 所致。如果主机的操作系统与目标计算机的操作系统不匹配，符号链接可能会中断。例如，在 Raspberry Pi 上 MacBook进行交叉编译。

另一个可能的原因是构建的二进制文件用于错误的架构。例如，如果二进制文件是为 x86 构建的（Raspberry Pi 使用 ARM CPUs）。

导航到错误中指定的库位置，然后键入:`ls -la`以检查库`symlinks`。

**响应：**

```
drwxr-xr-x  16 me  staff      512 Sep 10 17:16 .
drwxr-xr-x   7 me  staff      224 Jan  6 23:46 ..
drwxr-xr-x   4 me  staff      128 Sep 10 17:16 engines-1.1
-rwxr-xr-x   1 me  staff  2294496 Sep 10 17:16 libcrypto.1.1.so
-rw-r--r--   1 me  staff  4002848 Sep 10 17:16 libcrypto.a
lrwxr-xr-x   1 me  staff       19 Sep 10 17:16 libcrypto.so -> libcrypto.1.1.so
-rwxr-xr-x   1 me  staff   631176 Sep 10 17:12 liblog4cplus-2.0.3.so
lrwxr-xr-x   1 me  staff       24 Sep 10 17:12 liblog4cplus.so -> liblog4cplus-2.0.3.so
-rwxr-xr-x   1 me  staff     1012 Sep 10 17:12 liblog4cplus.a
-rwxr-xr-x   1 me  staff   694328 Sep 10 17:12 liblog4cplusU-2.0.3.so
lrwxr-xr-x   1 me  staff       25 Sep 10 17:12 liblog4cplusU.dylib -> liblog4cplusU-2.0.3.so
-rwxr-xr-x   1 me  staff     1017 Sep 10 17:12 liblog4cplusU.a
-rwxr-xr-x   1 me  staff   536416 Sep 10 17:16 libssl.1.1.so
-rw-r--r--   1 me  staff   795184 Sep 10 17:16 libssl.a
lrwxr-xr-x   1 me  staff       16 Sep 10 17:16 libssl.so -> libssl.1.1.so
drwxr-xr-x   6 me  staff      192 Sep 10 17:16 pkgconfig
```

在上面的示例输出中，`symlinks`未损坏。Bro `symlinks` ken 不会有箭指向目标。

**解决方法：**

修复符号链接有两个选项：
+ **推荐：**`symlink`使用`ln`命令重新创建。类型：

  ```
  ln -s /path/to/actual/library /path/to/symlink
  ```
+ 复制实际的库文件并对其进行重命名以匹配`symlink`。
**注意**  
此选项会增加存储使用量。

最佳做法是，使用像 Docker 这样的工具在同一个操作系统上进行编译，以避免交叉编译问题。

**缺少依赖关系：**

如果缺少的库名称以开头`libkvs`，请参阅上面的 “已移动库” 部分，将 Kinesis Video Streams 库从主机设备安装到目标设备。

否则，[安装软件先决条件](producersdk-cpp-rpi-software.md)请按照以下步骤操作，确保目标设备上已安装所有开源软件先决条件。

# 错误代码参考
<a name="producer-sdk-errors"></a>

此部分包含 [上传到 Kinesis Video Streams](producer-sdk.md) 的错误和状态代码信息。

有关常见问题解决方法的信息，请参阅 [对 Kinesis Video Streams 进行故障排除](troubleshooting.md)

**Topics**
+ [PutFrame 回调返回的错误和状态码-平台独立代码 (PIC)](#producer-sdk-errors-putframe)
+ [PutFrame 回调返回的错误和状态码-C 制作人库](#producer-sdk-errors-putframe-c)

## PutFrame 回调返回的错误和状态码-平台独立代码 (PIC)
<a name="producer-sdk-errors-putframe"></a>

以下各节包含平台独立代码 (PIC) 中`PutFrame`操作的回调返回的错误和状态信息。

**Topics**
+ [客户端库返回的错误和状态码](#producer-sdk-errors-client)
+ [持续时间库返回的错误和状态码](#producer-sdk-errors-duration)
+ [公共库返回的错误和状态码](#producer-sdk-errors-common)
+ [堆库返回的错误和状态码](#producer-sdk-errors-heap)
+ [MKVGen 库返回的错误和状态码](#producer-sdk-errors-mkvgen)
+ [Trace 库返回的错误和状态码](#producer-sdk-errors-trace)
+ [Utils 库返回的错误和状态码](#producer-sdk-errors-utils)
+ [View 库返回的错误和状态码](#producer-sdk-errors-view)

### 客户端库返回的错误和状态码
<a name="producer-sdk-errors-client"></a>

下表包含 Kinesis Video `Client` Streams 库中的方法返回的错误和状态信息。


****  

| 代码 | Message | 说明 | 推荐操作 | 
| --- | --- | --- | --- | 
| 0x52000001 | STATUS\$1MAX\$1STREAM\$1COUNT | 已达到最大流数。 | 在 DeviceInfo 中指定更大的最大流数，该数量是在[制作人 SDK 配额](limits.md#producer-sdk-limits)中指定的。 | 
| 0x52000002 | STATUS\$1MIN\$1STREAM\$1COUNT | 最小流数错误。 | 在中指定大于零的流的最大数量DeviceInfo。 | 
| 0x52000003 | STATUS\$1INVALID\$1DEVICE\$1NAME\$1LENGTH | 设备名称长度无效。 | 请参阅中指定的以字符为单位的最大设备名称长度[制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x52000004 | STATUS\$1INVALID\$1DEVICE\$1INFO\$1VERSION | DeviceInfo 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x52000005 | STATUS\$1MAX\$1TAG\$1COUNT | 已达到最大标记数。 | 请参阅中指定的当前最大标签数[制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x52000006 | STATUS\$1DEVICE\$1FINGERPRINT\$1LENGTH | 
| 0x52000007 | STATUS\$1INVALID\$1CALLBACKS\$1VERSION | Callbacks 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x52000008 | STATUS\$1INVALID\$1STREAM\$1INFO\$1VERSION | StreamInfo 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x52000009 | STATUS\$1INVALID\$1STREAM\$1NAME\$1LENGTH | 流名称长度无效。 | 请参阅中指定的以字符为单位的最大直播名称长度[制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x5200000a | STATUS\$1INVALID\$1STORAGE\$1SIZE | 指定的存储大小无效。 | 存储大小 (字节) 必须在[制作人 SDK 配额](limits.md#producer-sdk-limits)中指定的限制内。 | 
| 0x5200000b | STATUS\$1INVALID\$1ROOT\$1DIRECTORY\$1LENGTH | 根目录字符串长度无效。 | 请参阅中指定的最大根目录路径长度[制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x5200000c | STATUS\$1INVALID\$1SPILL\$1RATIO | 溢出率无效。 | 以 0—100 之间的百分比表示溢出率。 | 
| 0x5200000d | STATUS\$1INVALID\$1STORAGE\$1INFO\$1VERSION | StorageInfo 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x5200000e | STATUS\$1INVALID\$1STREAM\$1STATE | 流处于不允许执行当前操作的状态。 | 最常见的是，当 SDK 无法达到执行请求的操作所需的状态时，就会发生此错误。例如，如果 GetStreamingEndpoint API 调用失败，并且客户端应用程序忽略该失败并继续将帧放入流中，则会出现该错误。 | 
| 0x5200000f | STATUS\$1SERVICE\$1CALL\$1CALLBACKS\$1MISSING | 对于某些必需函数，Callbacks 结构具有缺少的函数入口点。 | 验证强制回调是否已在客户端应用程序中实现。此错误仅暴露于平台独立代码 (PIC) 客户端。C\$1\$1 和其他更高级别的包装程序满足这些调用的要求。 | 
| 0x52000010 | STATUS\$1SERVICE\$1CALL\$1NOT\$1AUTHORIZED\$1ERROR | 未授权。 | 验证安全令牌、证书、安全令牌集成和到期。验证令牌是否具有正确的关联权限。对于 Kinesis Video Streams 示例应用程序，请验证环境变量设置是否正确。 | 
| 0x52000011 | STATUS\$1DESCRIBE\$1STREAM\$1CALL\$1FAILED | DescribeStream API 失败。 | 在 DescribeStream API 重试失败后，将返回该错误。PIC 客户端在停止重试后返回此错误。 | 
| 0x52000012 | STATUS\$1INVALID\$1DESCRIBE\$1STREAM\$1RESPONSE | DescribeStreamResponse 结构无效。 | 传递给 DescribeStreamResultEvent 的结构为 Null 或包含无效的项目，例如，Null Amazon 资源名称 (ARN)。 | 
| 0x52000013 | STATUS\$1STREAM\$1IS\$1BEING\$1DELETED\$1ERROR | 正在删除流。 | API 失败是由正在删除的流造成的。确认在使用该流时，没有其他进程正在尝试删除该流。 | 
| 0x52000014 | STATUS\$1SERVICE\$1CALL\$1INVALID\$1ARG\$1ERROR | 为服务调用指定的参数无效。 | 当服务调用参数无效或 SDK 遇到无法解释的错误时，后端会返回此错误。 | 
| 0x52000015 | STATUS\$1SERVICE\$1CALL\$1DEVICE\$1NOT\$1FOUND\$1ERROR | 找不到设备。 | 确认设备在使用过程中未被删除。 | 
| 0x52000016 | STATUS\$1SERVICE\$1CALL\$1DEVICE\$1NOT\$1PROVISIONED\$1ERROR | 未预置设备。 | 验证设备是否已配置。 | 
| 0x52000017 | STATUS\$1SERVICE\$1CALL\$1RESOURCE\$1NOT\$1FOUND\$1ERROR | 找不到从服务中返回的常规资源。 | 在服务找不到资源 (例如，流) 时，将会出现该错误。在不同的上下文中，它可能意味着不同的含义，但可能的原因是在创建直播 APIs 之前使用的。使用 SDK 确认直播已先创建。 | 
| 0x52000018 | STATUS\$1INVALID\$1AUTH\$1LEN | 身份验证信息长度无效。 | 请参阅[制作人 SDK 配额](limits.md#producer-sdk-limits)中指定的当前值。 | 
| 0x52000019 | STATUS\$1CREATE\$1STREAM\$1CALL\$1FAILED | CreateStream API 调用失败。 | 有关操作失败原因的更详细信息，请参阅错误字符串。 | 
| 0x5200002a | STATUS\$1GET\$1STREAMING\$1TOKEN\$1CALL\$1FAILED | GetStreamingToken 调用失败。 | 有关操作失败原因的更详细信息，请参阅错误字符串。 | 
| 0x5200002b | STATUS\$1GET\$1STREAMING\$1ENDPOINT\$1CALL\$1FAILED | GetStreamingEndpoint API 调用失败。 | 有关操作失败原因的更详细信息，请参阅错误字符串。 | 
| 0x5200002c | STATUS\$1INVALID\$1URI\$1LEN | 从 GetStreamingEndpoint API 中返回的 URI 字符串长度无效。 | 请参阅[制作人 SDK 配额](limits.md#producer-sdk-limits)中指定的当前最大值。 | 
| 0x5200002d | STATUS\$1PUT\$1STREAM\$1CALL\$1FAILED | PutMedia API 调用失败。 | 有关操作失败原因的更详细信息，请参阅错误字符串。 | 
| 0x5200002e | STATUS\$1STORE\$1OUT\$1OF\$1MEMORY | 内容存储内存不足。 | 内容存储是在流之间共享的，应具有足够的容量以存储所有流的最大持续时间内的内容 \$1 \$120% (考虑碎片整理)。请切勿使存储溢出。请选择与累计存储大小和容许的延迟对应的每个流的最大持续时间值。我们建议在框架从内容视图窗口中掉出来时将其丢掉，而不是直接放置（内容存储内存压力）。这是因为丢帧会启动直播压力通知回调。然后，应用程序可以调整上游媒体组件 (如编码器) 以降低比特率，删除帧或执行相应的操作。 | 
| 0x5200002f | STATUS\$1NO\$1MORE\$1DATA\$1AVAILABLE | 流当前没有更多的可用数据。 | 在媒体管道生成帧的速度比网络线程使用发送到服务的帧的速度慢时，这可能是一个有效的结果。更高级别的客户端（例如 C\$1\$1、Java 或 Android）不会看到此警告，因为它是在内部处理的。 | 
| 0x52000030 | STATUS\$1INVALID\$1TAG\$1VERSION | Tag 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x52000031 | STATUS\$1SERVICE\$1CALL\$1UNKNOWN\$1ERROR | 从网络堆栈中返回未知或常规错误。 | 有关更详细信息，请参阅日志。 | 
| 0x52000032 | STATUS\$1SERVICE\$1CALL\$1RESOURCE\$1IN\$1USE\$1ERROR | 正在使用资源。 | 这是从服务中返回的。有关更多信息，请参阅 Kinesis Video Streams API 参考。 | 
| 0x52000033 | STATUS\$1SERVICE\$1CALL\$1CLIENT\$1LIMIT\$1ERROR | 客户端限制。 | 这是从服务中返回的。有关更多信息，请参阅 Kinesis Video Streams API 参考。 | 
| 0x52000034 | STATUS\$1SERVICE\$1CALL\$1DEVICE\$1LIMIT\$1ERROR | 设备限制。 | 这是从服务中返回的。有关更多信息，请参阅 Kinesis Video Streams API 参考。 | 
| 0x52000035 | STATUS\$1SERVICE\$1CALL\$1STREAM\$1LIMIT\$1ERROR | 流限制。 | 这是从服务中返回的。有关更多信息，请参阅 Kinesis Video Streams API 参考。 | 
| 0x52000036 | STATUS\$1SERVICE\$1CALL\$1RESOURCE\$1DELETED\$1ERROR | 已删除或正在删除资源。 | 这是从服务中返回的。有关更多信息，请参阅 Kinesis Video Streams API 参考。 | 
| 0x52000037 | STATUS\$1SERVICE\$1CALL\$1TIMEOUT\$1ERROR | 服务调用超时。 | 调用特定服务 API 导致超时。验证您的网络连接是否有效。PIC 将自动重试该操作。 | 
| 0x52000038 | STATUS\$1STREAM\$1READY\$1CALLBACK\$1FAILED | 流就绪通知。 | 该通知从 PIC 发送到客户端，表示已创建异步流。 | 
| 0x52000039 | STATUS\$1DEVICE\$1TAGS\$1COUNT\$1NON\$1ZERO\$1TAGS\$1NULL | 指定的标记无效。 | 标签数不为零，但标签为空。验证标签是否已指定或计数为零。 | 
| 0x5200003a | STATUS\$1INVALID\$1STREAM\$1DESCRIPTION\$1VERSION | StreamDescription 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x5200003b | STATUS\$1INVALID\$1TAG\$1NAME\$1LEN | 标记名称长度无效。 | 请参阅[制作人 SDK 配额](limits.md#producer-sdk-limits)中指定的标记名称限制。 | 
| 0x5200003c | STATUS\$1INVALID\$1TAG\$1VALUE\$1LEN | 标记值长度无效。 | 请参阅[制作人 SDK 配额](limits.md#producer-sdk-limits)中指定的标记值限制。 | 
| 0x5200003d | STATUS\$1TAG\$1STREAM\$1CALL\$1FAILED | TagResource API 失败。 | TagResource API 调用失败。检查有效的网络连接。有关该失败的更多信息，请参阅日志。 | 
| 0x5200003e | STATUS\$1INVALID\$1CUSTOM\$1DATA | 调用 PIC 的自定义数据无效 APIs。 | 在调用 PIC 时指定了无效的自定义数据 APIs。仅在直接使用 PIC 的客户端中可能会发生这种情况。 | 
| 0x5200003f | STATUS\$1INVALID\$1CREATE\$1STREAM\$1RESPONSE | CreateStreamResponse 结构无效。 | 结构或其成员字段无效 (即，ARN 为 Null 或大于[制作人 SDK 配额](limits.md#producer-sdk-limits)中指定的值)。 | 
| 0x52000040 | STATUS\$1CLIENT\$1AUTH\$1CALL\$1FAILED  | 客户端身份验证失败。 | 多次重试后，PIC 未能获得正确的身份验证信息（AccessKeyId或SecretAccessKey）。检查身份验证集成。示例应用程序使用环境变量将凭证信息传入到 C\$1\$1 创建者库。 | 
| 0x52000041 | STATUS\$1GET\$1CLIENT\$1TOKEN\$1CALL\$1FAILED | 获取安全令牌调用失败。 | 仅在直接使用 PIC 的客户端中可能会发生这种情况。在重试一定次数后，调用失败并出现该错误。 | 
| 0x52000042 | STATUS\$1CLIENT\$1PROVISION\$1CALL\$1FAILED | 预置错误。 | 未实现配置。 | 
| 0x52000043 | STATUS\$1CREATE\$1CLIENT\$1CALL\$1FAILED | 无法创建创建者客户端。 | 在客户端创建失败时，在重试一定次数后，PIC 返回一个常规错误。 | 
| 0x52000044 | STATUS\$1CLIENT\$1READY\$1CALLBACK\$1FAILED | 无法将创建者客户端置于就绪状态。 | 这是在 PIC 无法变为就绪状态时 PIC 状态机返回的。有关根本原因的更多信息，请参阅日志。 | 
| 0x52000045 | STATUS\$1TAG\$1CLIENT\$1CALL\$1FAILED | 创建者客户端的 TagResource 失败。 | 创建者客户端的 TagResource API 调用失败。有关根本原因的更多信息，请参阅日志。 | 
| 0x52000046 | STATUS\$1INVALID\$1CREATE\$1DEVICE\$1RESPONSE | 设备/创建者创建失败。 | 更高级别的 SDKs （例如，C\$1\$1 或 Java）尚未实现设备或制作者创建 API。直接使用 PIC 的客户端可以使用结果通知指示失败。 | 
| 0x52000047 | STATUS\$1ACK\$1TIMESTAMP\$1NOT\$1IN\$1VIEW\$1WINDOW | 在视图中不显示收到的 ACK 的时间戳。 | 如果与收到的 ACK 对应的帧没有位于内容视图窗口中，则会出现该错误。通常，如果 ACK 传输速度较慢，则会发生这种情况。可以将其解释为警告，并指示下行链路速度较慢。 | 
| 0x52000048 | STATUS\$1INVALID\$1FRAGMENT\$1ACK\$1VERSION | FragmentAck 结构版本无效。 | 指定正确的当前 FragmentAck 结构版本。 | 
| 0x52000049 | STATUS\$1INVALID\$1TOKEN\$1EXPIRATION | 安全令牌到期日期无效。 | 安全令牌到期后的绝对时间戳应大于当前时间戳，并带有宽限期。有关宽限期的限制，请参阅[制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x5200004a | STATUS\$1END\$1OF\$1STREAM | 流结束 (EOS) 指示符。 | 在 GetStreamData API 调用中，指示当前上传处理会话已结束。如果会话结束或出现错误，或者会话令牌已过期并且正在轮换会话，则会发生这种情况。 | 
| 0x5200004b | STATUS\$1DUPLICATE\$1STREAM\$1NAME | 重复的流名称。 | 多个流不能具有相同的流名称。为流选择唯一的名称。 | 
| 0x5200004c | STATUS\$1INVALID\$1RETENTION\$1PERIOD | 保留期无效。 | 在 StreamInfo 结构中指定的保留期无效。有关有效的保留期值范围的信息，请参阅[制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x5200004d | STATUS\$1INVALID\$1ACK\$1KEY\$1START | 无效 FragmentAck。 | 无法解析片段 ACK 字符串。键开始指示符无效。片段 ACK 字符串可能已损坏。它可以自行更正，并且可以将该错误视为警告。 | 
| 0x5200004e | STATUS\$1INVALID\$1ACK\$1DUPLICATE\$1KEY\$1NAME | 无效 FragmentAck。 | 无法解析片段 ACK 字符串。多个键具有相同的名称。片段 ACK 字符串可能已损坏。它可以自行更正，并且可以将该错误视为警告。 | 
| 0x5200004f | STATUS\$1INVALID\$1ACK\$1INVALID\$1VALUE\$1START | 无效 FragmentAck。 | 无法解析片段 ACK 字符串，因为键值开始指示符无效。片段 ACK 字符串可能已损坏。它可以自行更正，并且可以将该错误视为警告。 | 
| 0x52000050 | STATUS\$1INVALID\$1ACK\$1INVALID\$1VALUE\$1END | 无效 FragmentAck。 | 无法解析片段 ACK 字符串，因为键值结束指示符无效。片段 ACK 字符串可能已损坏。它可以自行更正，并且可以将该错误视为警告。 | 
| 0x52000051 | STATUS\$1INVALID\$1PARSED\$1ACK\$1TYPE | 无效 FragmentAck。 | 无法解析片段 ACK 字符串，因为指定的 ACK 类型无效。 | 
| 0x52000052 | STATUS\$1STREAM\$1HAS\$1BEEN\$1STOPPED | 已停止流。 | 已停止流，但仍在将帧放入流中。 | 
| 0x52000053 | STATUS\$1INVALID\$1STREAM\$1METRICS\$1VERSION | StreamMetrics 结构版本无效。 | 指定正确的当前 StreamMetrics 结构版本。 | 
| 0x52000054 | STATUS\$1INVALID\$1CLIENT\$1METRICS\$1VERSION | ClientMetrics 结构版本无效。 | 指定正确的当前 ClientMetrics 结构版本。 | 
| 0x52000055 | STATUS\$1INVALID\$1CLIENT\$1READY\$1STATE | 创建者初始化无法达到就绪状态。 | 在创建者客户端初始化期间，无法达到就绪状态。有关更多信息，请参阅日志。 | 
| 0x52000056 | STATUS\$1STATE\$1MACHINE\$1STATE\$1NOT\$1FOUND | 内部状态机错误。 | 不是公开可见的错误。 | 
| 0x52000057 | STATUS\$1INVALID\$1FRAGMENT\$1ACK\$1TYPE | 在 FragmentAck 结构中指定的 ACK 类型无效。 | FragmentAck 结构应包含公共标头中定义的 ACK 类型。 | 
| 0x52000058 | STATUS\$1INVALID\$1STREAM\$1READY\$1STATE | 内部状态机转换错误。 | 不是公开可见的错误。 | 
| 0x52000059 | STATUS\$1CLIENT\$1FREED\$1BEFORE\$1STREAM | 在释放创建者后释放流对象。 | 尝试在释放创建者对象后释放流对象。仅在直接使用 PIC 的客户端中可能会发生这种情况。 | 
| 0x5200005a | STATUS\$1ALLOCATION\$1SIZE\$1SMALLER\$1THAN\$1REQUESTED | 内部存储错误。 | 内部错误，表示来自内容存储的实际分配大小小于已打包的帧和片段的大小。 | 
| 0x5200005b | STATUS\$1VIEW\$1ITEM\$1SIZE\$1GREATER\$1THAN\$1ALLOCATION | 内部存储错误。 | 内容视图中存储的分配大小大于内容存储中的分配大小。 | 
| 0x5200005c | STATUS\$1ACK\$1ERR\$1STREAM\$1READ\$1ERROR | 流读取错误 ACK。 | ACK 从后端返回的错误，表示流读取或解析错误。在后端无法检索流时，通常会发生这种情况。自动重新流式传输通常可以纠正该错误。 | 
| 0x5200005d | STATUS\$1ACK\$1ERR\$1FRAGMENT\$1SIZE\$1REACHED | 已达到最大片段大小。 | 在[制作人 SDK 配额](limits.md#producer-sdk-limits)中定义了最大片段大小 (字节)。该错误表示具有非常大的帧，或者没有用于创建可管理大小的片段的关键帧。检查编码器设置并验证关键帧是否正确生成。对于具有较高密度的流，请将编码器配置为生成具有较短持续时间的片段以管理最大大小。 | 
| 0x5200005e | STATUS\$1ACK\$1ERR\$1FRAGMENT\$1DURATION\$1REACHED | 已达到最大片段持续时间。 | 在[制作人 SDK 配额](limits.md#producer-sdk-limits)中定义了最大片段持续时间。该错误表示每秒具有非常少的帧，或者没有用于创建可管理持续时间的片段的关键帧。检查编码器设置并验证关键帧是否按固定间隔正确生成。 | 
| 0x5200005f | STATUS\$1ACK\$1ERR\$1CONNECTION\$1DURATION\$1REACHED | 已达到最大连接持续时间。 | Kinesis Video Streams 强制执行中指定的最大连接持续时间。[制作人 SDK 配额](limits.md#producer-sdk-limits)在达到最大值之前，Producer SDK 会自动轮换直播或令牌。使用 SDK 的客户不应收到此错误。 | 
| 0x52000060 | STATUS\$1ACK\$1ERR\$1FRAGMENT\$1TIMECODE\$1NOT\$1MONOTONIC | 时间码不是单调递增的。 | Producer SDK 强制使用时间戳，因此使用 SDK 的客户端不应收到此错误。 | 
| 0x52000061 | STATUS\$1ACK\$1ERR\$1MULTI\$1TRACK\$1MKV | 在 MKV 中具有多个音轨。 | Producer SDK 强制使用单轨流，因此使用 SDK 的客户端不应收到此错误。 | 
| 0x52000062 | STATUS\$1ACK\$1ERR\$1INVALID\$1MKV\$1DATA | MKV 数据无效。 | 后端 MKV 解析器在解析流时遇到错误。如果直播在过渡期间损坏，使用 SDK 的客户端可能会遇到此错误。如果缓冲压力迫使 SDK 丢掉部分传输的尾帧，也会发生这种情况。在后一种情况下，我们建议您要么降低 FPS 和分辨率，提高压缩率，要么（如果有 “爆发” 的网络）允许更大的内容存储和缓冲持续时间以适应临时压力。 | 
| 0x52000063 | STATUS\$1ACK\$1ERR\$1INVALID\$1PRODUCER\$1TIMESTAMP | 创建者时间戳无效。 | 如果创建者时钟大幅漂移到将来的时间，服务将返回该错误 ACK。更高级别 SDKs （例如 Java 或 C\$1\$1）使用某个版本的系统时钟来满足 PIC 的当前时间回调。验证系统时钟设置是否正确。直接使用 PIC 的客户端应验证其回调函数是否返回了正确的时间戳。 | 
| 0x52000064 | STATUS\$1ACK\$1ERR\$1STREAM\$1NOT\$1ACTIVE | 非活动流。 | 在流未处于“活动”状态时，对后端 API 进行了调用。如果客户端创建流并立即继续将帧推入流中，则会发生这种情况。SDK 通过状态机和恢复机制处理这种情况。 | 
| 0x52000065 | STATUS\$1ACK\$1ERR\$1KMS\$1KEY\$1ACCESS\$1DENIED | AWS KMS 访问被拒绝错误。 | 在账户没有指定密钥的访问权限时返回。 | 
| 0x52000066 | STATUS\$1ACK\$1ERR\$1KMS\$1KEY\$1DISABLED | AWS KMS 密钥已禁用。 | 已禁用指定的密钥。 | 
| 0x52000067 | STATUS\$1ACK\$1ERR\$1KMS\$1KEY\$1VALIDATION\$1ERROR  | AWS KMS 密钥验证错误。 | 常规验证错误。有关更多信息，请参阅 [AWS Key Management Service API 参考](https://docs.aws.amazon.com/kms/latest/APIReference/)。 | 
| 0x52000068 | STATUS\$1ACK\$1ERR\$1KMS\$1KEY\$1UNAVAILABLE | AWS KMS key 不可用。 | 密钥不可用。有关更多信息，请参阅 [AWS Key Management Service API 参考](https://docs.aws.amazon.com/kms/latest/APIReference/)。 | 
| 0x52000069 | STATUS\$1ACK\$1ERR\$1KMS\$1KEY\$1INVALID\$1USAGE | KMS 密钥的使用无效。 | 未配置为在此上下文中使用。 AWS KMS key 有关更多信息，请参阅 [AWS Key Management Service API 参考](https://docs.aws.amazon.com/kms/latest/APIReference/)。 | 
| 0x5200006a | STATUS\$1ACK\$1ERR\$1KMS\$1KEY\$1INVALID\$1STATE | AWS KMS 状态无效。 | 有关更多信息，请参阅 [AWS Key Management Service API 参考](https://docs.aws.amazon.com/kms/latest/APIReference/)。 | 
| 0x5200006b | STATUS\$1ACK\$1ERR\$1KMS\$1KEY\$1NOT\$1FOUND | 找不到 KMS 密钥。 | 找不到密钥。有关更多信息，请参阅 [AWS Key Management Service API 参考](https://docs.aws.amazon.com/kms/latest/APIReference/)。 | 
| 0x5200006c | STATUS\$1ACK\$1ERR\$1STREAM\$1DELETED | 已删除或正在删除流。 | 正在由另一个应用程序或通过 AWS 管理控制台删除流。 | 
| 0x5200006d | STATUS\$1ACK\$1ERR\$1ACK\$1INTERNAL\$1ERROR | 内部错误。 | 常规服务内部错误。 | 
| 0x5200006e | STATUS\$1ACK\$1ERR\$1FRAGMENT\$1ARCHIVAL\$1ERROR | 片段存档错误。 | 在服务无法持久保留片段并为其编制索引时返回。虽然非常少见，但可能会出于各种原发生这种情况。默认情况下，SDK 再次尝试发送片段。 | 
| 0x5200006f | STATUS\$1ACK\$1ERR\$1UNKNOWN\$1ACK\$1ERROR | 未知错误。 | 服务返回未知错误。 | 
| 0x52000070 | STATUS\$1MISSING\$1ERR\$1ACK\$1ID | 缺少 ACK 信息。 | ACK 解析器已完成解析，但缺少 FragmentAck 信息。 | 
| 0x52000071 | STATUS\$1INVALID\$1ACK\$1SEGMENT\$1LEN | ACK 段长度无效。 | 为 ACK 解析器指定的 ACK 段字符串具有无效的长度。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x52000074 | STATUS\$1MAX\$1FRAGMENT\$1METADATA\$1COUNT | 已向片段中添加最大数目的元数据项目。 | Kinesis 视频流最多可以向片段添加 10 个元数据项，方法是向片段添加非永久项目，也可以向元数据队列中添加永久项目。有关更多信息，请参阅 [在 Kinesis Video Streams 中使用直播元数据](how-meta.md)。 | 
| 0x52000075 | STATUS\$1ACK\$1ERR\$1FRAGMENT\$1METADATA\$1LIMIT\$1REACHED | 已达到限制（最大元数据计数、元数据名称长度或元数据值长度）。 | 创建者开发工具包限制元数据项目的数量和大小。除非更改了 Producer SDK 代码中的限制，否则不会发生此错误。有关更多信息，请参阅 [在 Kinesis Video Streams 中使用直播元数据](how-meta.md)。 | 
| 0x52000076 | STATUS\$1BLOCKING\$1PUT\$1INTERRUPTED\$1STREAM\$1TERMINATED | 未实现。 |  | 
| 0x52000077 | STATUS\$1INVALID\$1METADATA\$1NAME | 元数据名称无效。 | 元数据名称不能以字符串 “AWS” 开头。如果发生此错误，则不会将元数据项添加到片段或元数据队列中。有关更多信息，请参阅 [在 Kinesis Video Streams 中使用直播元数据](how-meta.md)。 | 
| 0x52000078 | STATUS\$1END\$1OF\$1FRAGMENT\$1FRAME\$1INVALID\$1STATE | 片段帧的结尾处于无效状态。 | 片段的结尾不应以 non-key-frame碎片流形式发送。 | 
| 0x52000079 | STATUS\$1TRACK\$1INFO\$1MISSING | 缺少轨道信息。 | 曲目编号必须大于零且与曲目 ID 相匹配。 | 
| 0x5200007a | STATUS\$1MAX\$1TRACK\$1COUNT\$1EXCEEDED | 超出最大轨道数。 | 每个直播最多可以有三首曲目。 | 
| 0x5200007b | STATUS\$1OFFLINE\$1MODE\$1WITH\$1ZERO\$1RETENTION | 离线流式处理模式保留时间设置为零。 | 离线直播模式的保留时间不应设置为零。 | 
| 0x5200007c | STATUS\$1ACK\$1ERR\$1TRACK\$1NUMBER\$1MISMATCH | 错误 ACK 的轨道编号不匹配。 |  | 
| 0x5200007d | STATUS\$1ACK\$1ERR\$1FRAMES\$1MISSING\$1FOR\$1TRACK | 轨道缺少帧。 |  | 
| 0x5200007e | STATUS\$1ACK\$1ERR\$1MORE\$1THAN\$1ALLOWED\$1TRACKS\$1FOUND | 超出允许的最大轨道数。 |  | 
| 0x5200007f | STATUS\$1UPLOAD\$1HANDLE\$1ABORTED | 上传处理已中止。 |  | 
| 0x52000080 | STATUS\$1INVALID\$1CERT\$1PATH\$1LENGTH | 证书路径长度无效。 |  | 
| 0x52000081 | STATUS\$1DUPLICATE\$1TRACK\$1ID\$1FOUND | 找到重复的轨道 ID。 |  | 
| 0x52000082 | STATUS\$1INVALID\$1CLIENT\$1INFO\$1VERSION |  |  | 
| 0x52000083 | STATUS\$1INVALID\$1CLIENT\$1ID\$1STRING\$1LENGTH |  |  | 
| 0x52000084 | STATUS\$1SETTING\$1KEY\$1FRAME\$1FLAG\$1WHILE\$1USING\$1EOFR |  |  | 
| 0x52000085 | STATUS\$1MAX\$1FRAME\$1TIMESTAMP\$1DELTA\$1BETWEEN\$1TRACKS\$1EXCEEDED |  |  | 
| 0x52000086 | STATUS\$1STREAM\$1SHUTTING\$1DOWN |  |  | 
| 0x52000087 | STATUS\$1CLIENT\$1SHUTTING\$1DOWN |  |  | 
| 0x52000088 | STATUS\$1PUTMEDIA\$1LAST\$1PERSIST\$1ACK\$1NOT\$1RECEIVED |  |  | 
| 0x52000089 | STATUS\$1NON\$1ALIGNED\$1HEAP\$1WITH\$1IN\$1CONTENT\$1STORE\$1ALLOCATORS |  |  | 
| 0x5200008a | STATUS\$1MULTIPLE\$1CONSECUTIVE\$1EOFR |  |  | 
| 0x5200008b | STATUS\$1DUPLICATE\$1STREAM\$1EVENT\$1TYPE |  |  | 
| 0x5200008c | STATUS\$1STREAM\$1NOT\$1STARTED |  |  | 
| 0x5200008d | STATUS\$1INVALID\$1IMAGE\$1PREFIX\$1LENGTH |  |  | 
| 0x5200008e | STATUS\$1INVALID\$1IMAGE\$1METADATA\$1KEY\$1LENGTH |  |  | 
| 0x5200008f | STATUS\$1INVALID\$1IMAGE\$1METADATA\$1VALUE\$1LENGTH |  |  | 

### 持续时间库返回的错误和状态码
<a name="producer-sdk-errors-duration"></a>

下表包含`Duration`库中方法返回的错误和状态信息。


****  

| 代码 | Message | 
| --- | --- | 
| 0xFFFFFFFFFFFFFFFF | INVALID\$1DURATION\$1VALUE | 

### 公共库返回的错误和状态码
<a name="producer-sdk-errors-common"></a>

下表包含`Common`库中方法返回的错误和状态信息。

**注意**  
这些错误和状态信息代码对许多人来说都很常见 APIs。


****  

| 代码 | 不带前导 0 的代码 | Message | 说明 | 
| --- | --- | --- | --- | 
| 0x00000001  | 0x1 | STATUS\$1NULL\$1ARG | 为必需参数传递了 NULL。 | 
| 0x00000002  | 0x2 | STATUS\$1INVALID\$1ARG  | 为参数指定的值无效。 | 
| 0x00000003  | 0x3 | STATUS\$1INVALID\$1ARG\$1LEN  | 指定的参数长度无效。 | 
| 0x00000004  | 0x4 | STATUS\$1NOT\$1ENOUGH\$1MEMORY  | 无法分配足够的内存。 | 
| 0x00000005  | 0x5 | STATUS\$1BUFFER\$1TOO\$1SMALL  | 指定的缓冲区大小太小。 | 
| 0x00000006  | 0x6 | STATUS\$1UNEXPECTED\$1EOF  | 到达意外的文件末尾。 | 
| 0x00000007  | 0x7 | STATUS\$1FORMAT\$1ERROR  | 遇到无效的格式。 | 
| 0x00000008  | 0x8 | STATUS\$1INVALID\$1HANDLE\$1ERROR  | 句柄值无效。 | 
| 0x00000009  | 0x9 | STATUS\$1OPEN\$1FILE\$1FAILED  | 无法打开文件。 | 
| 0x0000000a  | 0xa | STATUS\$1READ\$1FILE\$1FAILED | 无法从文件中读取。 | 
| 0x0000000b  | 0xb | STATUS\$1WRITE\$1TO\$1FILE\$1FAILED  | 无法写入到文件中。 | 
| 0x0000000c  | 0xc | STATUS\$1INTERNAL\$1ERROR  | 通常不会出现的内部错误，可能表示 SDK 或服务 API 错误。 | 
| 0x0000000d  | 0xd | STATUS\$1INVALID\$1OPERATION  | 具有无效的操作，或者不允许执行该操作。 | 
| 0x0000000e  | 0xe | STATUS\$1NOT\$1IMPLEMENTED  | 未实现该功能。 | 
| 0x0000000f  | 0xf | STATUS\$1OPERATION\$1TIMED\$1OUT  | 操作已超时。 | 
| 0x00000010  | 0x10 | STATUS\$1NOT\$1FOUND  | 找不到所需的资源。 | 
| 0x00000011 | 0x11 | STATUS\$1CREATE\$1THREAD\$1FAILED  | 创建话题失败。 | 
| 0x00000012 | 0x12 | STATUS\$1THREAD\$1NOT\$1ENOUGH\$1RESOURCES  | 资源不足，无法创建另一个线程，或者遇到了系统对线程数施加的限制。 | 
| 0x00000013  | 0x13 | STATUS\$1THREAD\$1INVALID\$1ARG  | 指定的话题属性无效，或者其他话题已在等待加入此话题。 | 
| 0x00000014  | 0x14 | STATUS\$1THREAD\$1PERMISSIONS  | 没有权限设置线程属性中指定的调度策略和参数。 | 
| 0x00000015  | 0x15 | STATUS\$1THREAD\$1DEADLOCKED  | 检测到死锁或者加入的线程指定了调用线程。 | 
| 0x00000016  | 0x16 | STATUS\$1THREAD\$1DOES\$1NOT\$1EXIST  | 找不到具有指定话题 ID 的话题。 | 
| 0x00000017  | 0x17 | STATUS\$1JOIN\$1THREAD\$1FAILED  | 线程加入操作返回未知或一般错误。 | 
| 0x00000018  | 0x18 | STATUS\$1WAIT\$1FAILED  | 已超过等待条件变量的最长时间。 | 
| 0x00000019  | 0x19 | STATUS\$1CANCEL\$1THREAD\$1FAILED  | 线程取消操作返回未知或一般错误。 | 
| 0x0000001a  | 0x1a | STATUS\$1THREAD\$1IS\$1NOT\$1JOINABLE  | 在不可连接的线程上请求线程加入操作。 | 
| 0x0000001b  | 0x1b | STATUS\$1DETACH\$1THREAD\$1FAILED   | 线程分离操作返回未知或一般错误。 | 
| 0x0000001c  | 0x1c | STATUS\$1THREAD\$1ATTR\$1INIT\$1FAILED  | 无法初始化线程属性对象。 | 
| 0x0000001d  | 0x1d | STATUS\$1THREAD\$1ATTR\$1SET\$1STACK\$1SIZE\$1FAILED  | 未能为线程属性对象设置堆栈大小。 | 
| 0x0000001e  | 0x1e | STATUS\$1MEMORY\$1NOT\$1FREED  | 仅在测试中使用。表示未释放所有请求的内存。 | 
| 0x0000001f | 0x1f | STATUS\$1INVALID\$1THREAD\$1PARAMS\$1VERSION  | “ThreadParams” 结构版本无效。指定正确的当前结构版本。 | 

### 堆库返回的错误和状态码
<a name="producer-sdk-errors-heap"></a>

下表包含`Heap`库中方法返回的错误和状态信息。


****  

| 代码 | Message | 说明 | 
| --- | --- | --- | 
| 0x10000001  | STATUS\$1HEAP\$1FLAGS\$1ERROR  | 指定的标记组合无效。 | 
| 0x10000002  | STATUS\$1HEAP\$1NOT\$1INITIALIZED  | 在初始化堆之前尝试执行一个操作。 | 
| 0x10000003  | STATUS\$1HEAP\$1CORRUPTED  | 堆已损坏或已覆盖保护频段 (在调试模式下)。客户端代码中的缓冲区溢出可能导致堆损坏。 | 
| 0x10000004  | STATUS\$1HEAP\$1VRAM\$1LIB\$1MISSING  | VRAM（视频 RAM）用户或内核模式库无法加载或缺失。检查底层平台是否支持 VRAM 分配。 | 
| 0x10000005  | STATUS\$1HEAP\$1VRAM\$1LIB\$1REOPEN  | 无法打开 VRAM 库。 | 
| 0x10000006  | STATUS\$1HEAP\$1VRAM\$1INIT\$1FUNC\$1SYMBOL  | 无法加载 INIT 函数导出。 | 
| 0x10000007  | STATUS\$1HEAP\$1VRAM\$1ALLOC\$1FUNC\$1SYMBOL  | 无法加载 ALLOC 函数导出。 | 
| 0x10000008  | STATUS\$1HEAP\$1VRAM\$1FREE\$1FUNC\$1SYMBOL  | 无法加载 FREE 函数导出。 | 
| 0x10000009  | STATUS\$1HEAP\$1VRAM\$1LOCK\$1FUNC\$1SYMBOL  | 无法加载 LOCK 函数导出。 | 
| 0x1000000a  | STATUS\$1HEAP\$1VRAM\$1UNLOCK\$1FUNC\$1SYMBOL  | 无法加载 UNLOCK 函数导出。 | 
| 0x1000000b  | STATUS\$1HEAP\$1VRAM\$1UNINIT\$1FUNC\$1SYMBOL  | 无法加载 UNINIT 函数导出。 | 
| 0x1000000c  | STATUS\$1HEAP\$1VRAM\$1GETMAX\$1FUNC\$1SYMBOL  | 无法加载 GETMAX 函数导出。 | 
| 0x1000000d  | STATUS\$1HEAP\$1DIRECT\$1MEM\$1INIT  | 无法初始化混合堆中的主堆池。 | 
| 0x1000000e  | STATUS\$1HEAP\$1VRAM\$1INIT\$1FAILED  | VRAM 动态初始化失败。 | 
| 0x1000000f  | STATUS\$1HEAP\$1LIBRARY\$1FREE\$1FAILED  | 无法取消分配并释放 VRAM 库。 | 
| 0x10000010  | STATUS\$1HEAP\$1VRAM\$1ALLOC\$1FAILED  | VRAM 分配失败。 | 
| 0x10000011  | STATUS\$1HEAP\$1VRAM\$1FREE\$1FAILED  | VRAM 释放失败。 | 
| 0x10000012  | STATUS\$1HEAP\$1VRAM\$1MAP\$1FAILED  | VRAM 映射失败。 | 
| 0x10000013  | STATUS\$1HEAP\$1VRAM\$1UNMAP\$1FAILED  | VRAM 取消映射失败。 | 
| 0x10000014  | STATUS\$1HEAP\$1VRAM\$1UNINIT\$1FAILED  | VRAM 取消初始化失败。 | 
| 0x10000015 | STATUS\$1INVALID\$1ALLOCATION\$1SIZE |  | 
| 0x10000016 | STATUS\$1HEAP\$1REALLOC\$1ERROR |  | 
| 0x10000017 | STATUS\$1HEAP\$1FILE\$1HEAP\$1FILE\$1CORRUPT |  | 

### MKVGen 库返回的错误和状态码
<a name="producer-sdk-errors-mkvgen"></a>

下表包含`MKVGen`库中方法返回的错误和状态信息。


****  

| 代码 | Message | 描述/建议的操作 | 
| --- | --- | --- | 
| 0x32000001  | STATUS\$1MKV\$1INVALID\$1FRAME\$1DATA  | Frame 数据结构的成员无效。确保时长、大小和帧数据有效且在中指定的限制范围内[制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x32000002  | STATUS\$1MKV\$1INVALID\$1FRAME\$1TIMESTAMP  | 帧时间戳无效。计算的 PTS（演示时间戳）和 DTS（解码时间戳）大于或等于片段开始帧的时间戳。这表示潜在的媒体管道重新启动或编码器稳定性问题。有关故障排除信息，请参阅[错误：“Failed to submit frame to Kinesis Video client”(无法将帧提交到 Kinesis 视频客户端)](troubleshooting.md#troubleshooting-producer-failed-frame-client)。 | 
| 0x32000003  | STATUS\$1MKV\$1INVALID\$1CLUSTER\$1DURATION  | 指定的片段持续时间无效。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x32000004  | STATUS\$1MKV\$1INVALID\$1CONTENT\$1TYPE\$1LENGTH  | 内容类型字符串长度无效。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x32000005  | STATUS\$1MKV\$1NUMBER\$1TOO\$1BIG  | 尝试编码的数字太大，无法使用 EBML (可扩展二进制元语言) 格式表示。不会向 SDK 客户端显示该错误。 | 
| 0x32000006  | STATUS\$1MKV\$1INVALID\$1CODEC\$1ID\$1LENGTH  | 编解码器 ID 字符串长度无效。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x32000007  | STATUS\$1MKV\$1INVALID\$1TRACK\$1NAME\$1LENGTH  | 音轨名称字符串长度无效。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x32000008  | STATUS\$1MKV\$1INVALID\$1CODEC\$1PRIVATE\$1LENGTH  | 编解码器私有数据长度无效。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x32000009  | STATUS\$1MKV\$1CODEC\$1PRIVATE\$1NULL  | 编解码器私有数据 (CPD) 为空，而 CPD 大小大于零。 | 
| 0x3200000a  | STATUS\$1MKV\$1INVALID\$1TIMECODE\$1SCALE  | 时间码标度值无效。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x3200000b  | STATUS\$1MKV\$1MAX\$1FRAME\$1TIMECODE  | 帧时间码大于最大值。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x3200000c  | STATUS\$1MKV\$1LARGE\$1FRAME\$1TIMECODE  | 已达到最大帧时间码。MKV 格式使用有符号 16 位表示帧相对于集群开头的时间码。如果无法表示帧时间码，则会生成错误。该错误表示选择的时间码标度不正确或集群持续时间太长，因此，表示帧时间码将导致有符号 16 位空间溢出。 | 
| 0x3200000d  | STATUS\$1MKV\$1INVALID\$1ANNEXB\$1NALU\$1IN\$1FRAME\$1DATA  | 遇到无效的 Annex-B 启动代码。例如，指定了 Annex-B 适配标记，并且代码遇到包含超过三个零的无效开始序列。有效的 Annex-B 格式应具有“模拟防护”序列，以便对字节流中包含三个或更多零的序列进行转义。有关更多信息，请参阅 MPEG 规范。有关 Android 上的此错误的信息，请参阅 [Android 上的 STATUS\$1MKV\$1INVALID\$1ANNEXB\$1NALU\$1IN\$1FRAME\$1DATA (0x3200000d) 错误](troubleshooting.md#troubleshooting-producer-android-invalid-annexb)。 | 
| 0x3200000e  | STATUS\$1MKV\$1INVALID\$1AVCC\$1NALU\$1IN\$1FRAME\$1DATA  | 指定自适应 AVCC 标志时，AVCC NALU 打包无效。验证字节流是否为有效的 AVCC 格式。有关更多信息，请参阅 MPEG 规范。 | 
| 0x3200000f  | STATUS\$1MKV\$1BOTH\$1ANNEXB\$1AND\$1AVCC\$1SPECIFIED  | 对改编AVCC和附件B都进行了具体说明 NALUs 。指定其中的一个 NAL，或者不指定任何 NAL。 | 
| 0x32000010  | STATUS\$1MKV\$1INVALID\$1ANNEXB\$1NALU\$1IN\$1CPD  | 在指定了适配 Annex-B 标记时，CPD 的 Annex-B 格式无效。验证 CPD 的格式是否有效 Annex-B。如果不是，则移除 CPD Annex-B 适应标志。 | 
| 0x32000011  | STATUS\$1MKV\$1PTS\$1DTS\$1ARE\$1NOT\$1SAME  | Kinesis Video Streams 强制片段起始帧的 PTS（演示时间戳）和 DTS（解码时间戳）相同。这些是片段开头的关键帧。 | 
| 0x32000012  | STATUS\$1MKV\$1INVALID\$1H264\$1H265\$1CPD  | 无法解析 H264/H265 编解码器私有数据。 | 
| 0x32000013  | STATUS\$1MKV\$1INVALID\$1H264\$1H265\$1SPS\$1WIDTH  | 无法从编解码器私有数据中提取宽度。 | 
| 0x32000014  | STATUS\$1MKV\$1INVALID\$1H264\$1H265\$1SPS\$1HEIGHT  | 无法从编解码器私有数据中提取高度。 | 
| 0x32000015  | STATUS\$1MKV\$1INVALID\$1H264\$1H265\$1SPS\$1NALU  | H264/H265 SPS NALU 无效。 | 
| 0x32000016  | STATUS\$1MKV\$1INVALID\$1BIH\$1CPD  | 编解码器私有数据中的位图信息标头格式无效。 | 
| 0x32000017  | STATUS\$1MKV\$1INVALID\$1HEVC\$1NALU\$1COUNT  | 高效高级音频编码 (HEVC) 网络抽象层单元 (NALU) 计数无效。 | 
| 0x32000018  | STATUS\$1MKV\$1INVALID\$1HEVC\$1FORMAT  | HEVC 格式无效。 | 
| 0x32000019  | STATUS\$1MKV\$1HEVC\$1SPS\$1NALU\$1MISSING  | 序列参数集 (SPS) NALUs 中缺少 HEVC。 | 
| 0x3200001a  | STATUS\$1MKV\$1INVALID\$1HEVC\$1SPS\$1NALU\$1SIZE   | HEVC SPS NALU 大小无效。 | 
| 0x3200001b  | STATUS\$1MKV\$1INVALID\$1HEVC\$1SPS\$1CHROMA\$1FORMAT\$1IDC   | 色度格式 IDC 无效。 | 
| 0x3200001c  | STATUS\$1MKV\$1INVALID\$1HEVC\$1SPS\$1RESERVED   | HEVC 保留 SPS 无效。 | 
| 0x3200001d  | STATUS\$1MKV\$1MIN\$1ANNEX\$1B\$1CPD\$1SIZE   |  AnnexBb 编解码器私有测试版的最小值大小。对于 H264，该值必须等于或大于 11。对于 H265，该值必须等于或大于 15。 | 
| 0x3200001e  | STATUS\$1MKV\$1ANNEXB\$1CPD\$1MISSING\$1NALUS  | 附件 NALUs B中缺少编解码器的私有数据。 | 
| 0x3200001f  | STATUS\$1MKV\$1INVALID\$1ANNEXB\$1CPD\$1NALUS  | Ann NALUs ex-B 中的编解码器私有测试版无效。 | 
| 0x32000020  | STATUS\$1MKV\$1INVALID\$1TAG\$1NAME\$1LENGTH   | 标记名称长度无效。有效值大于 0 且小于 128。 | 
| 0x32000021  | STATUS\$1MKV\$1INVALID\$1TAG\$1VALUE\$1LENGTH   | 标记值长度无效。有效值大于零且小于 256。 | 
| 0x32000022  | STATUS\$1MKV\$1INVALID\$1GENERATOR\$1STATE\$1TAGS   | 生成器状态标签无效。 | 
| 0x32000023  | STATUS\$1MKV\$1INVALID\$1AAC\$1CPD\$1SAMPLING\$1FREQUENCY\$1INDEX   | AAC 编解码器专用数据采样频率索引无效。 | 
| 0x32000024  | STATUS\$1MKV\$1INVALID\$1AAC\$1CPD\$1CHANNEL\$1CONFIG   | AAC 编解码器专用数据通道配置无效。 | 
| 0x32000025  | STATUS\$1MKV\$1INVALID\$1AAC\$1CPD   | AAC 编解码器专用数据无效。 | 
| 0x32000026  | STATUS\$1MKV\$1TRACK\$1INFO\$1NOT\$1FOUND   | 找不到轨道信息。 | 
| 0x32000027  | STATUS\$1MKV\$1INVALID\$1SEGMENT\$1UUID   | 片段 UUID 无效。 | 
| 0x32000028  | STATUS\$1MKV\$1INVALID\$1TRACK\$1UID   | 轨道 UID 无效。 | 
| 0x32000029 | STATUS\$1MKV\$1INVALID\$1CLIENT\$1ID\$1LENGTH |  | 
| 0x3200002a | STATUS\$1MKV\$1INVALID\$1AMS\$1ACM\$1CPD |  | 
| 0x3200002b | STATUS\$1MKV\$1MISSING\$1SPS\$1FROM\$1H264\$1CPD |  | 
| 0x3200002c | STATUS\$1MKV\$1MISSING\$1PPS\$1FROM\$1H264\$1CPD |  | 
| 0x3200002d | STATUS\$1MKV\$1INVALID\$1PARENT\$1TYPE |  | 

### Trace 库返回的错误和状态码
<a name="producer-sdk-errors-trace"></a>

下表包含`Trace`库中方法返回的错误和状态信息。


****  

| 代码 | Message | 
| --- | --- | 
| 0x10100001 | STATUS\$1MIN\$1PROFILER\$1BUFFER  | 

### Utils 库返回的错误和状态码
<a name="producer-sdk-errors-utils"></a>

下表包含`Utils`库中方法返回的错误和状态信息。


****  

| 代码 | Message | 
| --- | --- | 
| 0x40000001 | STATUS\$1INVALID\$1BASE64\$1ENCODE  | 
| 0x40000002 | STATUS\$1INVALID\$1BASE  | 
| 0x40000003 | STATUS\$1INVALID\$1DIGIT  | 
| 0x40000004 | STATUS\$1INT\$1OVERFLOW  | 
| 0x40000005 | STATUS\$1EMPTY\$1STRING  | 
| 0x40000006 | STATUS\$1DIRECTORY\$1OPEN\$1FAILED  | 
| 0x40000007 | STATUS\$1PATH\$1TOO\$1LONG  | 
| 0x40000008 | STATUS\$1UNKNOWN\$1DIR\$1ENTRY\$1TYPE  | 
| 0x40000009 | STATUS\$1REMOVE\$1DIRECTORY\$1FAILED  | 
| 0x4000000a | STATUS\$1REMOVE\$1FILE\$1FAILED  | 
| 0x4000000b | STATUS\$1REMOVE\$1LINK\$1FAILED  | 
| 0x4000000c | STATUS\$1DIRECTORY\$1ACCESS\$1DENIED  | 
| 0x4000000d | STATUS\$1DIRECTORY\$1MISSING\$1PATH  | 
| 0x4000000e | STATUS\$1DIRECTORY\$1ENTRY\$1STAT\$1ERROR  | 
| 0x4000000f | STATUS\$1STRFTIME\$1FALIED | 
| 0x40000010 | STATUS\$1MAX\$1TIMESTAMP\$1FORMAT\$1STR\$1LEN\$1EXCEEDED | 
| 0x40000011 | STATUS\$1UTIL\$1MAX\$1TAG\$1COUNT | 
| 0x40000012 | STATUS\$1UTIL\$1INVALID\$1TAG\$1VERSION | 
| 0x40000013 | STATUS\$1UTIL\$1TAGS\$1COUNT\$1NON\$1ZERO\$1TAGS\$1NULL | 
| 0x40000014 | STATUS\$1UTIL\$1INVALID\$1TAG\$1NAME\$1LEN | 
| 0x40000015 | STATUS\$1UTIL\$1INVALID\$1TAG\$1VALUE\$1LEN | 
| 0x4000002a | STATUS\$1EXPONENTIAL\$1BACKOFF\$1INVALID\$1STATE | 
| 0x4000002b | STATUS\$1EXPONENTIAL\$1BACKOFF\$1RETRIES\$1EXHAUSTED | 
| 0x4000002c | STATUS\$1THREADPOOL\$1MAX\$1COUNT | 
| 0x4000002d | STATUS\$1THREADPOOL\$1INTERNAL\$1ERROR | 
| 0x40100001 | STATUS\$1HASH\$1KEY\$1NOT\$1PRESENT | 
| 0x40100002 | STATUS\$1HASH\$1KEY\$1ALREADY\$1PRESENT | 
| 0x40100003 | STATUS\$1HASH\$1ENTRY\$1ITERATION\$1ABORT | 
| 0x41000001 | STATUS\$1BIT\$1READER\$1OUT\$1OF\$1RANGE | 
| 0x41000002 | STATUS\$1BIT\$1READER\$1INVALID\$1SIZE | 
| 0x41100001 | STATUS\$1TIMER\$1QUEUE\$1STOP\$1SCHEDULING | 
| 0x41100002 | STATUS\$1INVALID\$1TIMER\$1COUNT\$1VALUE | 
| 0x41100003 | STATUS\$1INVALID\$1TIMER\$1PERIOD\$1VALUE | 
| 0x41100004 | STATUS\$1MAX\$1TIMER\$1COUNT\$1REACHED | 
| 0x41100005 | STATUS\$1TIMER\$1QUEUE\$1SHUTDOWN | 
| 0x41200001 | STATUS\$1SEMAPHORE\$1OPERATION\$1AFTER\$1SHUTDOWN | 
| 0x41200002 | STATUS\$1SEMAPHORE\$1ACQUIRE\$1WHEN\$1LOCKED | 
| 0x41300001 | STATUS\$1FILE\$1LOGGER\$1INDEX\$1FILE\$1INVALID\$1SIZE | 

### View 库返回的错误和状态码
<a name="producer-sdk-errors-view"></a>

下表包含`View`库中方法返回的错误和状态信息。


****  

| 代码 | Message | 说明 | 
| --- | --- | --- | 
| 0x30000001  | STATUS\$1MIN\$1CONTENT\$1VIEW\$1ITEMS  | 指定的内容视图项目数无效。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x30000002  | STATUS\$1INVALID\$1CONTENT\$1VIEW\$1DURATION  | 指定的内容视图持续时间无效。有关更多信息，请参阅 [制作人 SDK 配额](limits.md#producer-sdk-limits)。 | 
| 0x30000003  | STATUS\$1CONTENT\$1VIEW\$1NO\$1MORE\$1ITEMS  | 尝试获取的位置超过标头。 | 
| 0x30000004  | STATUS\$1CONTENT\$1VIEW\$1INVALID\$1INDEX  | 指定的索引无效。 | 
| 0x30000005  | STATUS\$1CONTENT\$1VIEW\$1INVALID\$1TIMESTAMP  | 具有无效的时间戳，或者时间戳发生重叠。帧解码时间戳应大于或等于前一帧的时间戳，再加上前一帧的持续时间：。`DTS(n) >= DTS(n-1) \$1 Duration(n-1)`该错误通常表示“不稳定”编码器。编码器生成一组突发编码帧，并且其时间戳小于帧内的持续时间。或者，流配置为使用 SDK 时间戳，并且发送帧的速度比帧持续时间快。为了帮助解决编码器中的一些“抖动”问题，请在 StreamInfo.StreamCaps 结构中指定较小的帧持续时间。例如，如果直播为 25 FPS，则每帧的持续时间为 40 毫秒。但是，为了处理编码器的 “抖动”，我们建议您使用该帧持续时间的一半（20 毫秒）。某些流要求更精确地控制错误检测时间。 | 
| 0x30000006  | STATUS\$1INVALID\$1CONTENT\$1VIEW\$1LENGTH  | 指定的内容视图项目数据长度无效。 | 

## PutFrame 回调返回的错误和状态码-C 制作人库
<a name="producer-sdk-errors-putframe-c"></a>

以下部分包含 C producer 库中`PutFrame`操作的回调返回的错误和状态信息。


****  

| 代码 | Message | 说明 | 推荐操作 | 
| --- | --- | --- | --- | 
| 0x15000001 | STATUS\$1STOP\$1CALLBACK\$1CHAIN | 回调链已停止。 |  | 
| 0x15000002 | STATUS\$1MAX\$1CALLBACK\$1CHAIN | 已达到最大回调链数。 |  | 
| 0x15000003 | STATUS\$1INVALID\$1PLATFORM\$1CALLBACKS\$1VERSION | PlatformCallbacks 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x15000004 | STATUS\$1INVALID\$1PRODUCER\$1CALLBACKS\$1VERSION | ProducerCallbacks 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x15000005 | STATUS\$1INVALID\$1STREAM\$1CALLBACKS\$1VERSION | StreamCallbacks 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x15000006 | STATUS\$1INVALID\$1AUTH\$1CALLBACKS\$1VERSION | AuthCallbacks 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x15000007 | STATUS\$1INVALID\$1API\$1CALLBACKS\$1VERSION | ApiCallbacks 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x15000008 | STATUS\$1INVALID\$1AWS\$1CREDENTIALS\$1VERSION | AwsCredentials 结构版本无效。 | 指定正确的当前结构版本。 | 
| 0x15000009 | STATUS\$1MAX\$1REQUEST\$1HEADER\$1COUNT | 已达到最大请求标头数。 |  | 
| 0x1500000a | STATUS\$1MAX\$1REQUEST\$1HEADER\$1NAME\$1LEN | 已达到最大请求标头名称长度。 |  | 
| 0x1500000b | STATUS\$1MAX\$1REQUEST\$1HEADER\$1VALUE\$1LEN | 已达到最大请求标头值长度。 |  | 
| 0x1500000c | STATUS\$1INVALID\$1API\$1CALL\$1RETURN\$1JSON | API 调用的返回 JSON 无效。 |  | 
| 0x1500000d | STATUS\$1CURL\$1INIT\$1FAILED | Curl 初始化失败。 |  | 
| 0x1500000e | STATUS\$1CURL\$1LIBRARY\$1INIT\$1FAILED | Curl lib 初始化失败。 |  | 
| 0x1500000f | STATUS\$1INVALID\$1DESCRIBE\$1STREAM\$1RETURN\$1JSON | 的返回 JSON 无效 DescribeStream。 |  | 
| 0x15000010 | STATUS\$1HMAC\$1GENERATION\$1ERROR | HMAC 生成错误。 |  | 
| 0x15000011 | STATUS\$1IOT\$1FAILED | 物联网授权失败。 |  | 
| 0x15000012 | STATUS\$1MAX\$1ROLE\$1ALIAS\$1LEN\$1EXCEEDED | 已达到最大角色别名长度。 | 请指定较短的别名长度。 | 
| 0x15000013 | STATUS\$1MAX\$1USER\$1AGENT\$1NAME\$1POSTFIX\$1LEN\$1EXCEEDED | 已达到最大代理名称后缀长度。 |  | 
| 0x15000014 | STATUS\$1MAX\$1CUSTOM\$1USER\$1AGENT\$1LEN\$1EXCEEDED | 已达到最大客户用户代理长度。 |  | 
| 0x15000015 | STATUS\$1INVALID\$1USER\$1AGENT\$1LENGTH | 无效的用户代理长度。 |  | 
| 0x15000016 | STATUS\$1INVALID\$1ENDPOINT\$1CACHING\$1PERIOD | 无效的终端节点缓存期。 | 指定小于 24 小时的缓存期。 | 
| 0x15000017 | STATUS\$1IOT\$1EXPIRATION\$1OCCURS\$1IN\$1PAST | IoT 过期时间戳发生在过去。 |  | 
| 0x15000018 | STATUS\$1IOT\$1EXPIRATION\$1PARSING\$1FAILED | 物联网过期解析失败。 |  | 
| 0x15000019 | STATUS\$1DUPLICATE\$1PRODUCER\$1CALLBACK\$1FREE\$1FUNC |  |  | 
| 0x1500001a | STATUS\$1DUPLICATE\$1STREAM\$1CALLBACK\$1FREE\$1FUNC |  |  | 
| 0x1500001b | STATUS\$1DUPLICATE\$1AUTH\$1CALLBACK\$1FREE\$1FUNC |  |  | 
| 0x1500001c | STATUS\$1DUPLICATE\$1API\$1CALLBACK\$1FREE\$1FUNC |  |  | 
| 0x1500001d | STATUS\$1FILE\$1LOGGER\$1INDEX\$1FILE\$1TOO\$1LARGE |  |  | 
| 0x1500001e | STATUS\$1MAX\$1IOT\$1THING\$1NAME\$1LENGTH |  |  | 
| 0x1500001f | STATUS\$1IOT\$1CREATE\$1LWS\$1CONTEXT\$1FAILED |  |  | 
| 0x15000020 | STATUS\$1INVALID\$1CA\$1CERT\$1PATH |  |  | 
| 0x15000022 | STATUS\$1FILE\$1CREDENTIAL\$1PROVIDER\$1OPEN\$1FILE\$1FAILED |  |  | 
| 0x15000023 | STATUS\$1FILE\$1CREDENTIAL\$1PROVIDER\$1INVALID\$1FILE\$1LENGTH |  |  | 
| 0x15000024 | STATUS\$1FILE\$1CREDENTIAL\$1PROVIDER\$1INVALID\$1FILE\$1FORMAT |  |  | 
| 0x15000026 | STATUS\$1STREAM\$1BEING\$1SHUTDOWN |  |  | 
| 0x15000027 | STATUS\$1CLIENT\$1BEING\$1SHUTDOWN |  |  | 
| 0x15000028 | STATUS\$1CONTINUOUS\$1RETRY\$1RESET\$1FAILED |  |  | 
| 0x16000001 | STATUS\$1CURL\$1PERFORM\$1FAILED |  CURL 返回了一个不成功的代码。  |  查看日志以获取更多信息。常见的 CURL 错误是 “无法解析主机名。 “，请检查设备的互联网连接。 另一个常见的错误是 403 错误代码。这表明 IoT 证书的创建或指定不正确。检查物联网证书的文件路径，权限设置是否正确。请参阅[使用控制对 Kinesis Video Streams 资源的访问权限 AWS IoT](how-iot.md)了解更多信息。  | 
| 0x16000002 | STATUS\$1IOT\$1INVALID\$1RESPONSE\$1LENGTH |  获取 IoT 凭据时收到长度为 0 的响应。  |  查看 AWS 运行状况控制面板，稍后重试。  | 
| 0x16000003 | STATUS\$1IOT\$1NULL\$1AWS\$1CREDS |  从物联网凭证端点返回的 JSON 不包含凭证对象。  |  查看 JSON 中的 “消息” 项以了解更多信息。  | 
| 0x16000004 | STATUS\$1IOT\$1INVALID\$1URI\$1LEN |  传递到获取物联网凭证函数的网址长度不在 1 到 10,000 之间。  |  查看传入此函数的 URL。  | 
| 0x16000005 | STATUS\$1TIMESTAMP\$1STRING\$1UNRECOGNIZED\$1FORMAT |  获取物联网凭证的 JSON 中的 “过期” 项的格式不是:`YYYY-MM-DDTHH:mm:SSZ`.  |  查看 AWS 运行状况控制面板，稍后重试。  | 

# 网络抽象层 (NAL) 适配标记参考
<a name="producer-reference-nal"></a>

本节包含有关 `StreamInfo.NalAdaptationFlags` 枚举的可用标记的信息。

应用程序中的[基本流](https://en.wikipedia.org/wiki/Elementary_stream)可以采用 **Annex-B** 或 **AVCC** 格式：
+ **Annex-B** 格式用两个字节的零，后跟一三个字节的零，然后是数字 *1（称为**起始码**，例如 00000001*[）来分隔NALUs （网络抽象层单元](https://en.wikipedia.org/wiki/Network_Abstraction_Layer#NAL_units)）。
+ **AVCC** 格式也会换行 NALUs，但每个 NALU 前面都有一个值，该值表示 NALU 的大小（通常为四个字节）。

许多编码器生成 Annex-B 比特流格式。一些更高级别的比特流处理器（例如播放引擎或中的[媒体源扩展 (MSE) 播放器）](https://en.wikipedia.org/wiki/Media_Source_Extensions)在帧中 AWS 管理控制台使用 AVCC 格式。

编解码器私有数据 (CPD)，即 H.264 编解码器的 SPS/PPS （序列参数集/图片参数集），也可以采用 Annex-B 或 AVCC 格式。但是，对 CPD 而言，格式与前面描述的有所不同。

这些标志告诉 SDK 将帧数据和 CPD 改编 NALUs 为 AVCC 或 Annex-B，如下所示：


****  

| 标记 | 适配 | 
| --- | --- | 
| NAL\$1ADAPTATION\$1FLAG\$1NONE | 没有改编。 | 
| NAL\$1ADAPTATION\$1ANNEXB\$1NALS | 将附件 B 改编成 AVC NALUs C。 NALUs | 
| NAL\$1ADAPTATION\$1AVCC\$1NALS | 将 AVCC 改编 NALUs 成附件 B NALUs。 | 
| NAL\$1ADAPTATION\$1ANNEXB\$1CPD\$1NALS | 将编解码器私 NALUs 有数据的附件 B 改编为 AVCC 格式。 NALUs | 
| NAL\$1ADAPTATION\$1ANNEXB\$1CPD\$1AND\$1FRAME\$1NALS | 将编解码器 NALUs 的 Annex-B 和帧私有数据改编为 AVCC 格式。 NALUs | 

有关 NALU 类型的更多信息，请参阅 **RFC 3984** 中的 [Section 1.3: Network Abstraction Layer Unit Types](https://www.ietf.org/rfc/rfc3984.txt)。

# 制作人 SDK 结构
<a name="producer-reference-structures-producer"></a>

本节包含有关可用于向 Kinesis Video Streams Producer 对象提供数据的结构的信息。

**Topics**
+ [DeviceInfo/DefaultDeviceInfoProvider](#producer-reference-structures-producer-deviceinfo)
+ [StorageInfo](#producer-reference-structures-producer-storageinfo)

## DeviceInfo/DefaultDeviceInfoProvider
<a name="producer-reference-structures-producer-deviceinfo"></a>

**DeviceInfo**和**DefaultDeviceInfoProvider**对象控制 Kinesis Video Streams Producer 对象的行为。

### 成员字段
<a name="producer-reference-structures-producer-deviceinfo-fields"></a>
+ **version**-一个整数值，用于确保在当前版本的代码库中使用正确的结构版本。当前版本使用 `DEVICE_INFO_CURRENT_VERSION` 宏指定。
+ **name** — 设备的人类可读名称。
+ **tagCount/tags** — 当前未使用。
+ **StreamCount** — 设备可以处理的最大直播数量。这会为最初指向流对象的指针预分配存储，但实际流对象将稍后创建。默认值为 16 个流，但可在 `DefaultDeviceInfoProvider.cpp` 文件中更改此数字。
+ **storageInfo**：描述主存储配置的对象。有关更多信息，请参阅 [StorageInfo](#producer-reference-structures-producer-storageinfo)。

## StorageInfo
<a name="producer-reference-structures-producer-storageinfo"></a>

指定 Kinesis Video Streams 的主存储配置。

默认实施基于低片段快速堆实施，这一实施针对流式处理进行了优化。它使用 `MEMALLOC` 分配器，可以在指定平台上覆盖。一些平台具有虚拟内存分配，没有物理页分配的支持。由于使用了内存，虚拟页由物理页提供支持。在存储利用不充分时，这会导致整个系统面临内存不足压力。

根据以下公式计算默认存储大小。`DefragmentationFactor` 应设置为 1.2 (20%)。

```
Size = NumberOfStreams * AverageFrameSize * FramesPerSecond * BufferDurationInSeconds * DefragmentationFactor
```

在以下示例中，设备具有音频和视频流。音频流每秒采样 512 次，平均样本 100 字节。视频流每秒 25 帧，平均 10000 字节。每个流的缓冲时长为 3 分钟。

```
Size = (512 * 100 * (3 * 60) + 25 * 10000 * (3 * 60)) * 1.2 = (9216000 + 45000000) * 1.2 = 65059200 = ~ 66MB.
```

如果设备有更多可用内存，我们建议您在存储空间中添加更多内存，以避免出现严重的碎片。

验证存储大小是否足以容纳编码复杂度高（当帧大小因高动态而变大时）或带宽较低时的所有流的完整缓冲区。如果生产者达到内存压力，它就会发出存储溢出压力回调 () `StorageOverflowPressureFunc`。但是，当内容存储中没有可用内存时，它会丢弃正在推送到Kinesis Video Streams的帧并显示错误`STATUS_STORE_OUT_OF_MEMORY = 0x5200002e`（）。有关更多信息，请参阅 [客户端库返回的错误和状态码](producer-sdk-errors.md#producer-sdk-errors-client)。如果应用程序确认 (ACKs) 不可用，或者持久化延 ACKs 迟，也可能发生这种情况。在这种情况下，在前一帧开始丢失之前，缓冲区将填充到 “缓冲持续时间” 容量。

### 成员字段
<a name="producer-reference-structures-producer-storageinfo-fields"></a>
+ **version**-一个整数值，用于确保在当前版本的代码库中使用正确的结构版本。
+ **StorageT** ype — `DEVICE_STORAGE_TYPE` 一个枚举，用于指定存储的底层支持和实现。目前唯一支持的值是 `DEVICE_STORAGE_TYPE_IN_MEM`。未来的实施中将支持 `DEVICE_STORAGE_TYPE_HYBRID_FILE`，指示存储回退到由文件支持的内容存储。
+ **存储大小**-要预分配的存储大小（以字节为单位）。最小分配大小为 10 MB，最大为 10 GB。（在未来实施由文件支持的内容存储时，这会有所更改。）
+ **sp** illRatio — 一个整数值，表示要从直接内存存储类型 (RAM) 与二级溢出存储（文件存储）中分配的存储空间的百分比。当前未使用。
+ **rootDirectory**：由文件支持的内容存储所在目录的路径。当前未使用。

# Kinesis 视频流结构
<a name="producer-reference-structures-stream"></a>

您可以使用以下结构向 Kinesis 视频流的实例提供数据。

**Topics**
+ [StreamDefinition/StreamInfo](#producer-reference-structures-stream-streaminfo)
+ [ClientMetrics](#producer-reference-structures-stream-clientmetrics)
+ [StreamMetrics](#producer-reference-structures-stream-streammetrics)

## StreamDefinition/StreamInfo
<a name="producer-reference-structures-stream-streaminfo"></a>

C\$1\$1 层中的 `StreamDefinition` 对象在独立于平台的代码中封装 `StreamInfo` 对象，并在构造函数中提供一些默认值。

### 成员字段
<a name="producer-reference-structures-stream-streaminfo-fields"></a>


****  

| 字段 | 数据类型 | 说明 | 默认 值 | 
| --- | --- | --- | --- | 
| stream\$1name | string | 可选的流名称。有关流名称长度的更多信息，请参阅[制作人 SDK 配额](limits.md#producer-sdk-limits)。每个流应具有唯一的名称。 | 如果未指定名称，则将随机生成一个名称。 | 
| retention\$1period | duration<uint64\$1t, ratio<3600>> | 流的保留期，以秒为单位。指定 0 表示不保留。 | 3600 (1 小时) | 
| tags | const map<string, string>\$1  | 包含用户信息的键-值对的映射。如果流已有一组标志，则新标志将附加到现有一组标志之后。 | 无标签 | 
| kms\$1key\$1id | string | 用于加密直播的密 AWS KMS 钥 ID。有关更多信息，请参阅 [Kinesis Video Streams 中的数据保护](how-kms.md)。 | 默认 KMS 密钥 (aws/kinesisvideo)。 | 
| streaming\$1type | STREAMING\$1TYPE 枚举 | STREAMING\$1TYPE\$1REALTIME 是唯一受支持的值。 |  | 
| content\$1type | string | 流的内容格式。Kinesis Video Streams 控制台可以播放video/h264该格式的内容。 | video/h264 | 
| max\$1latency | duration<uint64\$1t, milli> | 数据流的最大延迟，以毫秒为单位。当缓冲持续时间超过此时间量时，将调用流延迟压力回调（如果指定）。指定 0 表示将不调用流延迟压力回调。 | milliseconds::zero() | 
| fragment\$1duration | duration<uint64\$1t>  | 所需的片段持续时间，以秒为单位。此值与 key\$1frame\$1fragmentation 值结合使用。如果此值为false，Kinesis Video Streams 将在该持续时间过去后在关键帧上生成片段。例如，高级音频编码 (AAC) 音频流将每个帧作为关键帧。指定 key\$1frame\$1fragmentation = false 将导致在经过此持续时间之后，在关键帧上片段化，生成 2 秒的片段。 | 2 | 
| timecode\$1scale | duration<uint64\$1t, milli>  | MKV 时间码标度以毫秒为单位，这指定 MKV 集簇中帧的时间码粒度。MKV 帧时间码始终相对于集簇的开始。MKV 使用一个有符号的 16 位值 (0-32767) 来表示集簇内的时间码（片段）。验证帧时间码是否可以用给定的时间码比例来表示。默认时间码标度值 1 毫秒确保可以表示的最大帧为 32767 ms \$1 = 32 秒。这是在[亚马逊 Kinesis Video Streams 服务配额](limits.md)指定的最大片段持续时间（10 秒）内。 | 1 | 
| key\$1frame\$1fragmentation | bool | 是否在关键帧上生成片段。如果为 true，则开发工具包将在每次出现关键帧时生成片段的开始。如果false，Kinesis Video Streams fragment\$1duration 至少会等待，然后在紧随其后的关键帧上生成一个新的片段。 | true | 
| frame\$1timecodes | bool | 是否使用帧时间码或者使用当前时间回调生成时间戳。许多编码器不在帧中生成时间戳。因此，指定false此参数可确保帧在放入 Kinesis Video Streams 时带有时间戳。 | true | 
| absolute\$1fragment\$1times | bool | Kinesis Video Streams 使用 MKV 作为其底层打包机制。MKV 规范具有严格的帧时间码，相对于集簇（片段）的开始位置，但集簇时间码可以是绝对的，也可以相对于流的开始时间。如果时间戳是相对的，PutMedia 服务 API 调用将使用可选的流开始时间戳并调整集群时间戳。该服务始终存储片段及其绝对时间戳。 | true | 
| fragment\$1acks | bool | 是否接收应用程序级片段 ACKs （确认）。 | true，这意味着 SDK 将收到 ACKs并采取相应的行动。 | 
| restart\$1on\$1error | bool | 是否在出现特定错误时重启。 | true 意味着开发工具包在出现任意错误时将尝试重新启动流。 | 
| recalculate\$1metrics | bool | 是否重新计算指标。每个检索度量的调用可以重新计算这些值，以获取最新的“正在运行”值，这可能会导致较小的 CPU 影响。在极低功耗/容量的设备上，可能需要将此值设置为 false 以避免占用 CPU 周期。否则，我们不建议使用false此值。 | true | 
| nal\$1adaptation\$1flags | uint32\$1t  |  指定网络抽象层单元 (NALU) 自适应标志。如果比特流采用 H.264 编码，则可以将其作为原始数据处理或打包进去。 NALUs后者可以为 Annex-B 或 AVCC 格式。大多数基本流制作者和使用者（读取编码器和解码器）都使用 Annex-B 格式，因为它具有诸如错误恢复等优点。高级系统使用 AVCC 格式，这是 MPEG、HLS、DASH 等的默认格式。控制台播放使用浏览器的 MSE (Media Source Extensions) 来解码和播放使用 AVCC 格式的流。对于 H.264（以及对于 M-JPEG 和 H.265），开发工具包提供自适应功能。 许多基本流采用以下格式。在此示例中，`Ab` 是 Annex-B 开始代码（001 或 0001）。 <pre>Ab(Sps)Ab(Pps)Ab(I-frame)Ab(P/B-frame) Ab(P/B-frame)…. Ab(Sps)Ab(Pps)Ab(I-frame)Ab(P/B-frame) Ab(P/B-frame)</pre> 对于 H.264，编解码器私有数据 (CPD) 位于 SPS（序列参数集）和 PPS（图像参数集）参数中，并且可以调整为 AVCC 格式。除非媒体管道单独提供 CPD，否则应用程序可以从帧中提取 CPD。它可以通过查找第一个 IDR 帧（其中应包含 SPS 和 PPS），提取两个 NALUs （它们是`Ab(Sps)Ab(Pps)`），然后将其设置在 CPD 中来实现。`StreamDefinition` 有关更多信息，请参阅 [网络抽象层 (NAL) 适配标记参考](producer-reference-nal.md)。  | 默认情况下，帧数据和编解码器私有数据均为从 Annex-B 格式更改为 AVCC 格式。 | 
| frame\$1rate | uint32\$1t  | 预期的帧率。此值用于更好地计算缓冲需求。 | 25 | 
| avg\$1bandwidth\$1bps | uint32\$1t  | 流的预期平均带宽。此值用于更好地计算缓冲需求。 | 4 \$1 1024 \$1 1024  | 
| buffer\$1duration | duration<uint64\$1t>  | 流缓冲持续时间，以秒为单位。SDK 将帧保留在内容存储中的时间最长buffer\$1duration，之后随着窗口向前移动，之前的帧会被丢弃。如果被丢弃的帧尚未发送到后端，则会调用丢弃的帧回调。如果当前缓冲区持续时间大于 max\$1latency，则将调用流延迟压力回调。收到片段持久 ACK 时，缓冲区将修剪到下一个片段开始位置。这指示内容已持久保留到云中，因此不再需要在本地设备上存储内容。 | 120 | 
| replay\$1duration | duration<uint64\$1t> | 如果启用了重新启动，则在出错期间向后滚动当前读取器进行重播的持续时间（以秒为单位）。回滚操作将在缓冲开始位置停止（在刚启动流式传输时，或者出现持久 ACK 时）。回滚将尝试停留在指示片段开始的关键帧上。如果 “导致重启” 的错误并不表示主机已失效（主机仍处于活动状态且其内部缓冲区中包含帧数据），则回滚将在最后收到的 ACK 帧处停止。然后，它滚动到下一个关键帧，因为整个片段已经存储在主机内存中。 | 40 | 
| connection\$1staleness | duration<uint64\$1t> | 如果 SDK 未收到缓冲 ACK，则调用直播陈旧回调的时间（以秒为单位）。它表示帧是从设备发送的，但后端没有确认它们。这表明在中间跳转时或者负载均衡器上出现了断开的连接。 | 30 | 
| codec\$1id | string | MKV 音轨的编解码器 ID。 | V\$1MPEG4/ISO/AVC | 
| track\$1name | string | MKV 音轨名称。 | kinesis\$1video | 
| codecPrivateData | unsigned char\$1  | 编解码器私有数据 (CPD) 缓冲区。如果媒体管道在流启动之前具有 CPD 的相关信息，则可以在 StreamDefinition.codecPrivateData 中发送。此时将复制位，在创建流的调用之后可以重用或释放缓冲区。但是，如果创建流时数据不可用，则可以在KinesisVideoStream.start(cpd)函数的其中一个重载中对其进行设置。 | null | 
| codecPrivateDataSize | uint32\$1t  | 编解码器私有数据缓冲区大小。 | 0 | 

## ClientMetrics
<a name="producer-reference-structures-stream-clientmetrics"></a>

通过调用来填充**ClientMetrics**对象`getKinesisVideoMetrics`。

### 成员字段
<a name="producer-reference-structures-stream-clientmetrics-fields"></a>


****  

| 字段 | 数据类型 | 说明 | 
| --- | --- | --- | 
| 版本 | UINT32 | 结构的版本，在 CLIENT\$1METRICS\$1CURRENT\$1VERSION 宏中定义。 | 
| contentStoreSize  | UINT64 | 整体内容存储大小，以字节为单位。这是在 DeviceInfo.StorageInfo.storageSize 中指定的值。 | 
| contentStoreAvailable大小 | UINT64 | 当前可用存储大小（以字节为单位）。 | 
| contentStoreAllocated大小 | UINT64 | 当前分配的大小。由于内部记账和内存存储的实施，分配大小 \$1 可用大小应略小于总存储大小。 | 
| totalContentViews大小 | UINT64 | 所有流的所有内容视图的已分配内存大小。这不计入存储大小。此内存使用 MEMALLOC 宏分配，可以覆盖该值以提供自定义分配器。 | 
| totalFrameRate | UINT64 | 在所有流上观察到的总帧率。 | 
| totalTransferRate | UINT64 | 在所有流上观察到的总流速率，以每秒字节数为单位。 | 

## StreamMetrics
<a name="producer-reference-structures-stream-streammetrics"></a>

通过调用来填充**StreamMetrics**对象`getKinesisVideoMetrics`。

### 成员字段
<a name="producer-reference-structures-stream-clientmetrics-fields"></a>


****  

| 字段 | 数据类型 | 说明 | 
| --- | --- | --- | 
| 版本 | UINT32 | 结构的版本，在 STREAM\$1METRICS\$1CURRENT\$1VERSION 宏中定义。 | 
| currentViewDuration  | UINT64 | 累积帧的时间长度。在快速联网的情况下，此持续时间要么为零，要么为帧持续时间（在传输帧时）。如果持续时间长于中max\$1latency指定的时间StreamDefinition，则会调用直播延迟回调（如果已指定）。持续时间以 100 纳秒为单位指定，这是 PIC 层的默认时间单位。 | 
| overallViewDuration  | UINT64 | 整体查看持续时间。如果将直播配置为 “否” ACKs 或 “持久性”，则该值会随着帧放入 Kinesis 视频流而增长，并变为等于buffer\$1duration中的。StreamDefinition启用并收到持久 ACKs 的 ACK 后，缓冲区会被修剪到下一个关键帧。这是因为 ACK 时间戳表示整个片段的开头。持续时间以 100 纳秒为单位指定，这是 PIC 层的默认时间单位。 | 
| currentViewSize  | UINT64 | 当前缓冲区的大小，以字节为单位。 | 
| overallViewSize  | UINT64 | 整体视图大小，以字节为单位。 | 
| currentFrameRate  | UINT64 | 当前流观察到的帧率。 | 
| currentTransferRate | UINT64 | 当前流观察到的传输速率，以每秒字节数为单位。 | 

# 制作人 SDK 回调
<a name="producer-reference-callbacks"></a>

亚马逊 Kinesis Video Streams Video Streams Producer SDK 中的类和方法不维护自己的流程。相反，它们使用传入的函数调用和事件来安排用于与应用程序通信的回调。

应用程序可以使用两种回调模式来与开发工具包交互：
+ `CallbackProvider`— 此对象公开了从独立于平台的代码 (PIC) 组件到应用程序的所有回调。此模式允许使用全部功能，但这也意味着实施必须处理 C\$1\$1 层中的所有公有 API 方法和签名。
+ [StreamCallbackProvider](#producer-reference-callbacks-streamcallbackprovider)an [ClientCallbackProvider](#producer-reference-callbacks-clientcallbackprovider) d — 这些对象公开了特定于流和客户端特定的回调，SDK 的 C\$1\$1 层公开了其余的回调。这是用于与创建者开发工具包交互的首选回调模式。

下图说明了回调对象的对象模型：

![\[该图显示了 Kinesis Video Streams 中制作人和消费者的互动。\]](http://docs.aws.amazon.com/zh_cn/kinesisvideostreams/latest/dg/images/callbacks-10.png)


在上图中，`DefaultCallbackProvider` 派生自 `CallbackProvider`（后者公开 PIC 中的所有回调）并包含 `StreamCallbackProvider` 和 `ClientCallbackProvider`。

**Topics**
+ [ClientCallbackProvider](#producer-reference-callbacks-clientcallbackprovider)
+ [StreamCallbackProvider](#producer-reference-callbacks-streamcallbackprovider)
+ [ClientCallbacks 结构](#producer-reference-callbacks-clientcallbacks)
+ [用于重试直播的回调实现](#producer-reference-callbacks-retry)

## ClientCallbackProvider
<a name="producer-reference-callbacks-clientcallbackprovider"></a>

`ClientCallbackProvider` 对象可公开客户端级别的回调函数。[ClientCallbacks 结构](#producer-reference-callbacks-clientcallbacks)中介绍了这些函数的详细信息。

**回调方法：**
+ `getClientReadyCallback`— 报告客户端的就绪状态。
+ `getStorageOverflowPressureCallback`— 报告存储溢出或压力。当存储利用率下降到 `STORAGE_PRESSURE_NOTIFICATION_THRESHOLD` 值（该值为总体存储大小的 5%）以下时，将调用此回调。有关更多信息，请参阅 [StorageInfo](producer-reference-structures-producer.md#producer-reference-structures-producer-storageinfo)。

## StreamCallbackProvider
<a name="producer-reference-callbacks-streamcallbackprovider"></a>

`StreamCallbackProvider` 对象可公开流级别的回调函数。

**回调方法：**
+ `getDroppedFragmentReportCallback`：报告已丢弃片段。
+ `getDroppedFrameReportCallback`— 报告丢帧。
+ `getFragmentAckReceivedCallback`— 报告已收到该流的片段 ACK。
+ `getStreamClosedCallback`— 报告直播关闭情况。
+ `getStreamConnectionStaleCallback`— 报告过时的连接状况。在这种情况下，生产者正在向服务发送数据，但没有收到确认。
+ `getStreamDataAvailableCallback`— 报告数据流中可用。
+ `getStreamErrorReportCallback`— 报告直播错误情况。
+ `getStreamLatencyPressureCallback`— 报告流延迟情况，即累积的缓冲区大小大于该`max_latency`值。有关更多信息，请参阅 [StreamDefinition/StreamInfo](producer-reference-structures-stream.md#producer-reference-structures-stream-streaminfo)。
+ `getStreamReadyCallback`: —报告直播就绪状态。
+ `getStreamUnderflowReportCallback`— 报告直播下溢情况。此函数目前未使用，保留供将来使用。

有关源代码`StreamCallbackProvider`，请参阅 [StreamCallbackProvider.h.](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp/blob/d1684599a141785752582c16264e3123866f3cf8/kinesis-video-producer/src/StreamCallbackProvider.h)

## ClientCallbacks 结构
<a name="producer-reference-callbacks-clientcallbacks"></a>

该 `ClientCallbacks` 结构包含 PIC 在发生特定事件时调用的回调函数入口点。此结构还在 `CALLBACKS_CURRENT_VERSION` 字段中包含版本信息，还有一个 `customData` 字段用于提供各个回调函数返回的用户定义数据。

客户端应用程序可将 `this` 指针用于 `custom_data` 字段，以在运行时将成员函数映射到静态 `ClientCallback` 函数，如以下代码示例所示：

```
STATUS TestStreamCallbackProvider::streamClosedHandler(UINT64 custom_data, STREAM_HANDLE stream_handle, UINT64 stream_upload_handle) {
    LOG_INFO("Reporting stream stopped.");

TestStreamCallbackProvider* streamCallbackProvider = reinterpret_cast<TestStreamCallbackProvider*> (custom_data);
streamCallbackProvider->streamClosedHandler(...);
```


**Events**  

| 函数 | 说明 | Type | 
| --- | --- | --- | 
| CreateDeviceFunc | 目前未在后端实施。在从 Java 或 C\$1\$1 调用时，此调用将失败。其他客户端执行特定于平台的初始化。 | 后端 API | 
| CreateStreamFunc | 在创建流时调用。 | 后端 API | 
| DescribeStreamFunc | 在调用 DescribeStream 时调用。 | 后端 API | 
| GetStreamingEndpointFunc | 在调用 GetStreamingEndpoint 时调用。 | 后端 API | 
| GetStreamingTokenFunc | 在调用 GetStreamingToken 时调用。 | 后端 API | 
| PutStreamFunc | 在调用 PutStream 时调用。 | 后端 API | 
| TagResourceFunc | 在调用 TagResource 时调用。 | 后端 API | 
|   |   |   | 
| CreateMutexFunc | 创建同步互斥锁。 | 同步 | 
| FreeMutexFunc | 释放互斥锁。 | 同步 | 
| LockMutexFunc | 锁定同步互斥锁。 | 同步 | 
| TryLockMutexFunc | 尝试锁定互斥锁。当前未实施。 | 同步 | 
| UnlockMutexFunc | 解锁互斥锁。 | 同步 | 
|   |   |   | 
| ClientReadyFunc | 在客户端进入就绪状态时调用。 | 通知 | 
| DroppedFrameReportFunc | 在丢弃帧时报告。 | 通知 | 
| DroppedFragmentReportFunc | 在丢弃片段时报告。此函数目前未使用，保留供将来使用。 | 通知 | 
| FragmentAckReceivedFunc | 在收到片段 ACK（缓冲、接收、持久存在和错误）时调用。 | 通知 | 
| StorageOverflowPressureFunc | 在存储利用率下降到 STORAGE\$1PRESSURE\$1NOTIFICATION\$1THRESHOLD 值（该值定义为总体存储大小的 5%）以下时调用。 | 通知 | 
| StreamClosedFunc | 在流式处理其余帧的最后几个比特时调用。 | 通知 | 
| StreamConnectionStaleFunc | 在流进入过时连接状态时调用。在这种情况下，创建者会向服务发送数据，但收不到确认。 | 通知 | 
| StreamDataAvailableFunc | 在流数据可用时调用。 | 通知 | 
| StreamErrorReportFunc | 在出现流错误时调用。在这种情况下，PIC 会自动关闭流。 | 通知 | 
| StreamLatencyPressureFunc | 在流进入延迟状况（即累积缓冲区大小大于 max\$1latency 值时）调用。有关更多信息，请参阅 [StreamDefinition/StreamInfo](producer-reference-structures-stream.md#producer-reference-structures-stream-streaminfo)。 | 通知 | 
| StreamReadyFunc | 在流进入就绪状态时调用。 | 通知 | 
| StreamUnderflowReportFunc | 此函数目前未使用，保留供将来使用。 | 通知 | 
|   |   |   | 
| DeviceCertToTokenFunc | 以令牌形式返回连接证书。 | 平台集成 | 
| GetCurrentTimeFunc | 返回当前时间。 | 平台集成 | 
| GetDeviceCertificateFunc | 返回设备证书。此函数目前未使用，保留供将来使用。 | 平台集成 | 
| GetDeviceFingerprintFunc | 返回设备指纹。此函数目前未使用，保留供将来使用。 | 平台集成 | 
| GetRandomNumberFunc | 返回 0 和 RAND\$1MAX 之间的随机数。 | 平台集成 | 
| GetSecurityTokenFunc | 返回传递给与后端 API 通信的函数的安全令牌。该实施可以指定序列化的 AccessKeyId、SecretKeyId 和会话令牌。 | 平台集成 | 
| LogPrintFunc | 记录带有标签和日志级别的一行文本。有关更多信息，请参阅 PlatformUtils.h。 | 平台集成 | 

对于上表中的平台集成函数，最后一个参数是 `ServiceCallContext` 结构，该结构具有以下字段：
+ `version`：结构的版本。
+ `callAfter`：调用函数等待的绝对时间。
+ `timeout`：操作超时，以 100 纳秒为单位。
+ `customData`：要传递回客户端的用户定义的值。
+ `pAuthInfo`：调用的凭证。有关更多信息，请参阅下面的 (`__AuthInfo`) 结构。

使用 `__AuthInfo` 结构提供授权信息，该信息可以是序列化凭证或特定于提供商的身份验证令牌。此结构具有以下字段：
+ `version`：`__AuthInfo` 结构的版本。
+ `type`：用于定义凭证类型（证书或安全令牌）的 `AUTH_INFO_TYPE` 值。
+ `data`：包含身份验证信息的字节数组。
+ `size`：`data` 参数的大小。
+ `expiration`：凭证的过期时间（以 100 纳秒为单位）。

## 用于重试直播的回调实现
<a name="producer-reference-callbacks-retry"></a>

Kinesis Video Producer 开发工具包通过回调函数提供流式处理的状态。我们建议您实现以下回调机制，以从直播期间遇到的任何短暂网络问题中恢复过来。
+ **直播延迟压力回调**-此回调机制在 SDK 遇到直播延迟情况时启动。这在累计缓冲区大小大于 MAX\$1LATENCY 值时发生。在创建流后，流式处理应用程序会将 MAX\$1LATENCY 设置为 60 秒（默认值）。此回调的典型实施是重置连接。您可以根据需要使用 [https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp/blob/master/kinesis-video-c-producer/src/source/StreamLatencyStateMachine.c](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c/blob/master/src/source/StreamLatencyStateMachine.c) 中的示例实现。请注意，无法将由于网络中断而未交付的帧存储到辅助存储器中进行回填。
+ **直播失效回调** ——当创建者可以向 Amazon Kinesis Data Streams 服务（上行链路）发送数据，但无法及时获取确认（缓冲后的 ACK）（默认为 60 秒）时，就会启动此回调。根据网络设置，可以启动直播延迟压力回调或直播陈旧回调，或者两者兼而有之。与流延迟压力回调重试实施相似，典型实施是重置连接并启动新的连接以进行流式处理。您可以根据需要使用-pro [c/blob/master/src/source/ConnectionStaleStateMachineducer https://github.com/awslabs/ amazon-kinesis-video-streams-.c](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c/blob/master/src/source/ConnectionStaleStateMachine.c) 上的示例实现。
+ **直播错误回调**-当 SDK 在调用 KVS API 服务时遇到网络连接超时或其他错误时，将启动此回调。
+ **丢帧回调**-当由于网络速度慢或直播错误导致存储空间已满时，会启动此回调。如果网络速度导致丢帧，则可以增加存储大小、减小视频帧大小或帧速率以匹配网络速度。

# 在 Kinesis Video Streams 中使用直播元数据
<a name="how-meta"></a>

你可以使用 Amazon Kinesis Video Streams 制作器 SDK 在 Kinesis 视频流中嵌入单个片段级别的元数据。Kinesis Video Streams 中的元数据是一个可变的键值对。您可以使用它来描述片段的内容，嵌入必须与实际片段一起传输的相关传感器读数，或者满足其他自定义需求。元数据作为 [GetMedia](API_dataplane_GetMedia.md) 或 [GetMediaForFragmentList](API_reader_GetMediaForFragmentList.md) API 操作的一部分提供。它与片段一起存储在直播的整个保留期内。您的消费应用程序可以使用基于元数据进行读取、处理和响应[使用解析器库观看摄像机的输出](parser-library.md)。

可通过以下两种模式在数据流片段中嵌入元数据：
+ **非持续** — 您可以根据已出现的业务特定标准，一次性或临时将元数据附加到流中的片段。例如，智能相机可以检测动作，并在将片段发送到其 Kinesis 视频流之前，向包含动作的相应片段添加元数据。您可以采用以下格式将元数据应用于片段：`Motion = true`。
+ **持续-您可以根据持续**需要将元数据附加到流中连续的片段。例如，智能相机将与其发送的所有片段关联的当前纬度和经度坐标发送到其 Kinesis 视频流。您可以采用以下格式将元数据应用于所有片段：`Lat = 47.608013N , Long = -122.335167W`。

您可以根据应用程序的需求，将这两种模式的元数据同时附加到同一个片段中。嵌入的元数据可能包括检测到的对象、跟踪的活动、GPS 坐标或者要与数据流中的片段关联的任何其他自定义数据。元数据编码为键值字符串对。

## 向 Kinesis 视频流添加元数据
<a name="how-meta-add"></a>

您添加到 Kinesis 视频流中的元数据将建模为 MKV 标签，这些标签以键值对的形式实现。

元数据可以是*临时的*，如用于标记数据流内的事件，也可以是*持久的*，如用于识别发生给定事件的片段。永久性元数据项将保留，并应用于每个连续的片段，直到它被取消。

**注意**  
使用添加的元数据项不同[上传到 Kinesis Video Streams](producer-sdk.md)于使用[TagStream](API_TagStream.md)[UntagStream](API_UntagStream.md)、和 APIs 实现的流级标记。[ListTagsForStream](API_ListTagsForStream.md)

### 流式传输元数据 API
<a name="how-meta-api"></a>

您可以在制作器 SDK 中使用以下操作来实现流式传输元数据。

**Topics**
+ [PIC](#how-meta-api-pic)
+ [C\$1\$1 制作器 SD](#how-meta-api-cpp)
+ [Java 制作器 SD](#how-meta-api-java)
+ [永久和非持久元数据](#how-meta-api-persistence)

#### PIC
<a name="how-meta-api-pic"></a>

```
PUBLIC_API STATUS putKinesisVideoFragmentMetadata(STREAM_HANDLE streamHandle, 
    PCHAR name, 
    PCHAR value, 
    BOOL persistent);
```

#### C\$1\$1 制作器 SD
<a name="how-meta-api-cpp"></a>

```
/**
 * Appends a "tag" or metadata - a key/value string pair into the stream.
 */
bool putFragmentMetadata(const std::string& name, const std::string& value, bool persistent = true);
```

#### Java 制作器 SD
<a name="how-meta-api-java"></a>

您可以使用 Java 制作器 SDK `MediaSource` 通过以下方式向添加元数据`MediaSourceSink.onCodecPrivateData`：

```
void onFragmentMetadata(final @Nonnull String metadataName, final @Nonnull String metadataValue, final boolean persistent)
throws KinesisVideoException;
```

#### 永久和非持久元数据
<a name="how-meta-api-persistence"></a>

对于非持久元数据，您可以添加多个具有相同*名称* 的元数据项目。Producer SDK 会收集元数据队列中的元数据项，直到它们被添加到下一个片段之前。在将元数据项目应用到数据流时，将清除元数据队列。要重复元数据，请再次调用 `putKinesisVideoFragmentMetadata` 或 `putFragmentMetadata`。

对于永久性元数据，Producer SDK 收集元数据队列中的元数据项的方式与非永久性元数据相同。但是，当元数据项被添加到下一个片段之前时，它们不会从队列中删除。

在将 `persistent` 设置为 `true` 时调用 `putKinesisVideoFragmentMetadata` 或 `putFragmentMetadata` 会出现以下行为：
+ 调用 API 会将元数据项目置于队列中。当项目位于队列中时，会将元数据作为 MKV 标签添加到每个片段中。
+ 使用与以前添加的元数据项目相同的*名称* 和不同的*值* 调用 API 将覆盖该项目。
+ 使用空*值* 调用 API 将从元数据队列中删除（取消）元数据项目。



# IPv6 与 Kinesis Video Streams 配合使用
<a name="ipv6-support"></a>

您可以将 Kinesis Video Streams 配置为 IPv6 用于控制平面和数据平面操作。这使您的应用程序能够 IPv6 使用通过双栈端点的地址与 Kinesis Video Streams 服务进行通信。

**注意**  
IPv6 支持需要特定的 SDK 版本和配置设置。确保你的 Kinesis Video Streams SDK AWS 和 SDK 版本 IPv6 支持双栈端点。双栈终端节点同时支持 IPv4 和 IPv6 流量，并且适用于某些地区的某些服务。

Kinesis Video Streams 通过双栈端点 IPv6 支持生产者和消费者应用程序。您可以将应用程序配置 IPv6 为用于控制平面 API 调用和数据平面流式传输操作。

## 将 AWS SDK 配置为 IPv6
<a name="configure-aws-sdk-ipv6"></a>

如果你在制作设置中使用 AWS 软件开发工具包调用 Kinesis Video Streams 控制 APIs 平面，则可以通过配置双栈端点来 IPv6 启用。S AWS DK 提供了几种标准化方法来启用双堆栈端点。

**重要**  
启用双堆栈终端节点后，SDK 会尝试使用双堆栈终端节点发出网络请求。如果服务或区域不存在双堆栈终端节点，则请求将失败。

### 使用环境变量
<a name="ipv6-environment-variables"></a>

设置以下环境变量以启用 IPv6 双栈端点：

```
export AWS_USE_DUALSTACK_ENDPOINT=true
```

### 使用 AWS 配置文件
<a name="ipv6-config-file"></a>

将以下设置添加到您的 AWS 配置文件 (`~/.aws/config`)：

```
[default]
use_dualstack_endpoint = true
```

### 使用 JVM 系统属性（仅限 Java 和 Kotlin SDKs ）
<a name="ipv6-jvm-properties"></a>

对于 Java 和 Kotlin 应用程序，请设置以下 JVM 系统属性：

```
-Daws.useDualstackEndpoint=true
```

或者在你的 Java 代码中以编程方式：

```
System.setProperty("aws.useDualstackEndpoint", "true");
```

### SDK 支持
<a name="sdk-support-table"></a>

以下 AWS SDKs 支持双栈端点配置：


| SDK | 支持 | 配置方法 | 
| --- | --- | --- | 
| AWS CLI v2 | 是 | 环境变量，配置文件 | 
| 适用于 C\$1\$1 的 SDK | 是 | 环境变量，配置文件 | 
| 适用于 Go V2 (1.x) 的 SDK | 是 | 环境变量，配置文件 | 
| 适用于 Java 2.x 的 SDK | 是 | 环境变量、配置文件、JVM 属性 | 
| 适用于 Java 1.x 的 SDK | 否 | 不支持 | 
| 适用于 JavaScript 3.x 的软件开发工具包 | 是 | 环境变量，配置文件 | 
| 适用于 Python (Boto3) 的 SDK | 是 | 环境变量，配置文件 | 

配置双栈终端节点后， AWS SDK 在调用 Kinesis Video Streams 控制平面时会自动使用 IPv6 终端节点。 APIs

## 将 Kinesis Video Streams Producer SDK 配置为 IPv6
<a name="configure-producer-sdk-ipv6"></a>

Kinesis Video Streams Producer SDK 为控制平面和数据平面操作 IPv6 提供了配置选项。这些设置 AWS 适用于 SDK 双栈端点配置。

### 配置 C/C\$1\$1 制作器开发工具包
<a name="configure-c-cpp-producer-sdk"></a>

默认端点和 DNS 解析链由 KVS Producer-C SDK 版本 1.6.0 实现。它会按顺序检查每个可以为这些参数设置配置的地方，然后选择你设置的第一个位置。预定义顺序如下：

有关制作器的更多信息 SDKs，请参阅适用于 C 的制作[人 SDK、适用于 C](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c) [\$1\$1 的制作人 SDK](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp) 和[制作人 SDK 相关主题](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/producer-sdk.html#producer-sdk-related-topics)。

#### 端点配置
<a name="endpoint-configuration"></a>

1. 的`controlPlaneUrl`参数`createAbstractDefaultCallbacksProvider`。

1. 端点配置 CMake 参数：(`-DAWS_KVS_USE_LEGACY_ENDPOINT_ONLY=TRUE`,`-DAWS_KVS_USE_DUAL_STACK_ENDPOINT_ONLY=TRUE`)

1. 环境变量:(`export AWS_USE_DUALSTACK_ENDPOINT=TRUE`)
   + 如果`AWS_USE_DUALSTACK_ENDPOINT`是`TRUE`（不区分大小写），则将使用双栈端点。

1. 否则，将构造和使用传统端点。

对于 2、3 和 4，将根据提供给的区域来构造端点`createAbstractDefaultCallbacksProvider`。

#### DNS 过滤
<a name="dns-filtering"></a>

KVS Producer SDK 将根据配置设置相应的`CURLOPT_IPRESOLVE`参数：

1. DNS 解析 CMake 参数：(`-DAWS_KVS_IPV4_ONLY=TRUE`、`-DAWS_KVS_IPV6_ONLY=TRUE`、`-DAWS_KVS_IPV4_AND_IPV6_ONLY=TRUE`)

1. 环境变量 (`export AWS_KVS_USE_IPV4=TRUE`,`export AWS_KVS_USE_IPV6=TRUE`)

1. 否则，将不会进行过滤。如果由 DNS 返回，则可以同时 IPv4 使用 IPv6 IP 地址。

**注意**  
如果 DNS 筛选器设置设置为筛选 IPV6 IP 地址，但 SDK 配置为使用传统终端节点（ IPV4仅返回地址），则请求将失败。

C\$1\$1 Producer SDK 版本 3.5.0 使用 Producer-C SDK 1.6.0 进行 KVS API 调用。

### 配置 GStreamer 插件
<a name="configure-gstreamer-plugin"></a>

该 GStreamer 插件使用底层 C Producer SDK，因此 IPv6 在按照前面所述配置 C SDK 时 IPv6 ，会自动处理配置。

无需修改代码，只需使用 CMake 参数构建 SDK 或按照上一节所述设置相应的环境变量即可。

### 数据平面端点分辨率
<a name="data-plane-endpoint-resolution"></a>

对于数据平面操作，请使用 `GetDataEndpoint` API 检索相应的双堆栈数据平面端点。该服务根据请求网址返回相应的端点。

示例：
+ 如果向以结尾的旧版终端节点发出 `GetDataEndpoint` API 请求`.amazonaws.com`，Kinesis Video Streams 将返回以结尾`.amazonaws.com`的传统数据平面端点。
+ 如果向结尾为的双栈终端节点发出 `GetDataEndpoint` API 请求`.api.aws`，Kinesis Video Streams 将返回结尾为的双栈数据平面终端节点。`.api.aws`

## 配置 fo AWS CLI r IPv6
<a name="configure-aws-cli-ipv6"></a>

如果您使用用 AWS CLI 于 Kinesis Video Streams 操作（通常 proof-of-concept用于工作），则可以通过配置双栈端点来 IPv6 启用。

### 使用环境变量
<a name="cli-environment-variable"></a>

```
export AWS_USE_DUALSTACK_ENDPOINT=true
```

### 使用 AWS 配置文件
<a name="cli-config-file"></a>

将以下内容添加到您的 AWS CLI 配置文件 (`~/.aws/config`)：

```
[default]
use_dualstack_endpoint = true
```

## 配置示例
<a name="configuration-examples"></a>

### C 软件开发工具包示例
<a name="c-sdk-example"></a>

要在 IPV6仅限模式下构建 KVS Producer-C SDK 并忽略环境变量配置，请使用以下命令构建 SDK：

```
cmake .. -DAWS_KVS_USE_DUAL_STACK_ENDPOINT_ONLY=TRUE -DAWS_KVS_IPV6_ONLY=TRUE
make -j
```

**注意**  
如果您已经构建了 SDK，则需要执行干净的构建。在运行构建命令之前，请删除现有的构建、开源和依赖文件夹。

## 注意事项
<a name="ipv6-considerations"></a>

### 网络要求
<a name="network-requirements"></a>
+ 确保您的网络基础设施支持 IPv6 连接
+ 确认您的安全组和网络 ACLs 允许 IPv6 流量
+ 测试部署环境中与 AWS IPv6 终端节点的连接
+ 某些地区的某些服务可以使用双栈终端节点，请验证目标区域的可用性

### SDK 兼容性
<a name="sdk-compatibility"></a>
+ 确保您使用的是受支持的 AWS SDK 版本
+  AWS 适用于 Java 的 SDK 1.x 不支持双栈端点配置
+ 对于 SDK for Go 1.x (V1)，必须启用从配置文件加载才能使用共享配置文件设置

### 测试和验证
<a name="testing-validation"></a>

在将 IPv6启用了 Kinesis Video Streams 应用程序部署到生产环境之前，请执行以下操作：
+ 测试控制平面操作（直播创建、删除、上线）
+ 验证数据平面操作（视频摄取和消费）
+ 验证您的网络环境中的性能和连通性
+ 运行 canary 测试以确保 IPv6 功能一致
+ 在双栈端点不可用时测试故障转移行为

## 受升级影响的客户包括 IPv6
<a name="customers-impacted-ipv6"></a>

启 IPv6 用 Kinesis Video Streams 后，可能需要在多个区域更新现有配置和策略，以确保持续运行。

### IAM 策略和 IP 地址筛选
<a name="iam-policies-ip-filtering"></a>

如果您在 IAM 用户策略、角色策略或基于资源的策略中使用源 IP 地址筛选，则需要更新这些策略以包含 IPv6 地址范围。

**重要**  
在`IpAddress`或`NotIpAddress`条件中使用 IPv4 CIDR 块的现有 IAM 策略不会自动适用于 IPv6 地址。您必须明确添加 IPv6 范围以维护访问控制。

以下内容的 IAM 政策更新示例 IPv6：

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "kinesisvideo:*",
      "Resource": "*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [
            "192.0.2.0/24",
            "203.0.113.0/24",
            "2001:db8::/32"
          ]
        }
      }
    }
  ]
}
```

### 日志记录和监控
<a name="logging-monitoring-ipv6"></a>

IPv6 地址的格式与 IPv4 地址不同，这可能会影响您的日志、监控和分析系统。

#### logs
<a name="cloudtrail-logs"></a>

 当发出请求时，日志将包含`sourceIPAddress`字段中的 IPv6 地址 IPv6。更新您的日志解析工具和脚本以处理 IPv6 地址格式。

日志中的 IPv6 地址示例：

```
{
  "sourceIPAddress": "2001:db8::1",
  "eventName": "CreateStream",
  "eventSource": "kinesisvideo.amazonaws.com"
}
```

## 问题排查
<a name="troubleshooting-ipv6"></a>

### 常见问题
<a name="common-issues"></a>
+ 连接失败-验证 IPv6 网络连接和 DNS 解析
+ SDK 错误 — 确保您使用的是支持双栈端点的兼容 SDK 版本
+ 身份验证问题 — 确认 IAM 策略和证书适用于 IPv6 终端节点
+ 终端节点不可用-如果服务或区域不存在双栈终端节点，则请求将失败

### 验证步骤
<a name="verification-steps"></a>
+ 检查您的配置文件中`use_dualstack_endpoint = true`是否已设置或已设置 `AWS_USE_DUALSTACK_ENDPOINT=true`
+ 验证 Kinesis Video Streams IPv6 SDK 配置标志是否设置正确
+ 测试与 AWS IPv6 端点的网络连接
+ 查看应用程序日志，了解 IPv6特定于具体的错误消息
+ 确认您所在的地区支持 Kinesis Video Streams 的双栈终端节点

### 配置验证
<a name="configuration-validation"></a>

您可以通过检查以下内容来验证您的双栈终端节点配置：
+ 环境变量：`echo $AWS_USE_DUALSTACK_ENDPOINT`
+ AWS 配置文件：`cat ~/.aws/config | grep use_dualstack_endpoint`
+ JVM 属性 (Java)：检查应用程序日志中的系统属性