

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

# 编写并检查代码
<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 以创建基于静态 Amazon 凭证的默认回调提供程序。

  ```
  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));
  ```