

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 自動化即時映像產生
<a name="s3-real-time-image-create"></a>

Amazon Kinesis Video Streams 提供轉碼和交付映像的功能。Kinesis Video Streams 會自動即時從影片資料擷取影像，並將影像交付至您指定的 Amazon S3 儲存貯體。實作即時的自動化映像擷取包含下列步驟：
+ 建立 S3 儲存貯體以接收產生的映像。
+ 設定 [ImageGenerationConfiguration](API_ImageGenerationConfiguration.md) 串流屬性，該屬性會告知 Kinesis Video Streams 如何建立映像以及將映像傳送到何處。
+ 新增影像產生標籤 – Kinesis Video Streams 只會使用具有影像產生標籤的片段產生影像。使用 Kinesis Video Streams Producer SDK 以及 `putKinesisVideoEventMetadata`方法上傳影片時，會新增這些標籤。

下列程序提供完成每個步驟的說明。

如果您使用客戶受管金鑰，請確定執行`PutMedia`呼叫 （上傳程式） 的角色具有加密和解密資料以及存取 Amazon S3 儲存貯體所需的下列許可。
+ `kms:Encrypt`
+ `kms:GenerateDataKey`
+ `kms:Decrypt`
+ `s3:PutObject`

如需詳細資訊，請參閱[如何開始使用伺服器端加密？](how-kms.md#getting-started-with-sse-akvs)。

**設定產生的映像目的地**

1. 建立將傳送映像的 S3 目的地儲存貯體。

   遵循 [Amazon S3 使用者指南](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)來建立 Amazon S3 儲存貯體。

   請注意儲存貯體的 URI，在更新串流的映像產生組態時，您將在下一個步驟中需要此 URI。

1. 確認您已安裝 AWS CLI 並設定 。如需詳細資訊，請參閱[AWS Command Line Interface 《 第 2 版使用者指南](cli/latest/userguide/cli-chap-welcome.html)》。

1. 使用`update-image-generation-input.json`下列內容建立名為 的新檔案做為輸入。使用您要使用的值來更新預留位置值。如需最大和最小支援值，請參閱 [UpdateImageGenerationConfiguration](API_UpdateImageGenerationConfiguration.md) API。

   ```
   {
      "StreamName": "{{demo-stream}}",
      "ImageGenerationConfiguration": {
         "Status": "ENABLED",
         "DestinationConfig": {
            "DestinationRegion": "{{us-east-1}}",
            "Uri": "s3://{{my-bucket-name}}"
         },
         "SamplingInterval": 200,
         "ImageSelectorType": "PRODUCER_TIMESTAMP",
         "Format": "JPEG",
         "FormatConfig": {
            "JPEGQuality": "80"
         },
         "WidthPixels": 320,
         "HeightPixels": 240
      }
   }
   ```

1. 使用 [UpdateImageGenerationConfiguration](API_UpdateImageGenerationConfiguration.md) API 更新串流的影像產生組態，並將 JSON 檔案附加為輸入，如下列命令所示。請注意，檔案路徑指向目前目錄中的檔案。

   ```
   aws kinesisvideo update-image-generation-configuration \
     --cli-input-json file://./update-image-generation-input.json
   ```

1. 成功時，會傳回空白回應，而且終端機中不會列印任何內容。
**注意**  
更新映像產生組態後，至少需要 1 分鐘才能啟動映像產生工作流程。等待至少 1 分鐘，再將影片上傳至串流。

1. 驗證組態設定。使用 AWS CLI 呼叫串流的 [DescribeImageGenerationConfiguration](API_DescribeImageGenerationConfiguration.md) API。

   ```
   aws kinesisvideo describe-image-generation-configuration \
     --stream-name "{{demo-stream}}"
   ```

Kinesis Video Streams 只會為具有映像產生標籤的片段產生和交付映像。與 Amazon S3 影像產生標籤一起提供的任何其他片段中繼資料都會儲存為 Amazon S3 中繼資料。

**注意**  
影像產生標籤是指片段中繼資料標籤，而不是串流層級標籤。

**重要**  
影像產生標籤會計入片段中繼資料標籤限制。如需詳細資訊，請參閱[串流中繼資料服務配額](limits.md#limits-streaming-metadata)。

以下是使用 `mkvinfo`公用程式的片段中繼資料標籤結構範例。映像產生標籤是 MKV 簡易標籤，索引鍵為 `AWS_KINESISVIDEO_IMAGE_GENERATION`且沒有值。如需詳細資訊，請參閱 Matroska 文件中的[影片標籤範例](https://www.matroska.org/technical/tagging-video-example.html)。

```
|+ Tags
| + Tag
|  // MANDATORY: Predefined MKV tag to trigger image generation for the fragment
|  + Simple
|   + Name: AWS_KINESISVIDEO_IMAGE_GENERATION

|  // OPTIONAL: S3 prefix which will be set as prefix for generated image.
|  + Simple
|   + Name: AWS_KINESISVIDEO_IMAGE_PREFIX 
|   + String: {{image_prefix_in_s3}} // 256 bytes max

| // OPTIONAL: Key value pairs that will be persisted as S3 Image object metadata.
|  + Simple
|   + Name: {{CUSTOM_KEY_1}} // Max 128 bytes
|   + String: {{CUSTOM_VALUE_1}} // Max 256 bytes
|  + Simple
|   + Name: {{CUSTOM_KEY_2}} // Max 128 bytes
|   + String: {{CUSTOM_VALUE_2}} // Max 256 bytes
```

## 將影像產生標籤新增至片段
<a name="s3-adding-image-tags"></a>

Kinesis Video Streams 只會為具有映像產生標籤的片段產生和交付映像。Kinesis Video Streams 會辨識這些特殊 MKV 標籤，並根據串流的影像處理組態啟動影像產生工作流程。

使用 Kinesis Video Streams Producer SDK 上傳媒體時，您可以使用 `putKinesisVideoEventMetadata`方法將影像產生標籤新增至您要標記的每個片段。當 使用包含 `keyframe`旗標的影格`putFrame`呼叫 時，就會啟動新的片段。

如果您要上傳預先錄製的影片，它可能會以不同於錄製的速率上傳，取決於您的網路速度。如果您想要根據影片的原始時間戳記定期產生影像，而且不使用根據 Amazon Kinesis Video Streams 接收影片的速率產生的伺服器時間戳記，建議您使用 Producer 時間戳記來設定影像產生。

若要檢視此程式碼的完整範例，請參閱 GitHub 中的[https://github.com/awslabs/amazon-kinesis-video-streams-producer-c/blob/master/samples/KvsVideoOnlyRealtimeStreamingSample.c](https://github.com/awslabs/amazon-kinesis-video-streams-producer-c/blob/master/samples/KvsVideoOnlyRealtimeStreamingSample.c)程式碼範例。

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

Frame eofr = EOFR_FRAME_INITIALIZER;

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

    // 1. End the previous fragment
    if (frame.flags == FRAME_FLAG_KEY_FRAME && !firstFrame) {
        putKinesisVideoFrame(streamHandle, &eofr);
    }

    // 2. putFrame call
    CHK_STATUS(putKinesisVideoFrame(streamHandle, &frame));

    if (frame.flags == FRAME_FLAG_KEY_FRAME) {
        // 3. Adding the image generation tag
        CHK_STATUS(putKinesisVideoEventMetadata(streamHandle, STREAM_EVENT_TYPE_IMAGE_GENERATION, NULL);)

        // 4. Adding fragment metadata
        for (n = 1; n <= 5; n++) {
            SNPRINTF(metadataKey, METADATA_MAX_KEY_LENGTH, "SAMPLE_KEY_%d", n);
            SNPRINTF(metadataValue, METADATA_MAX_VALUE_LENGTH, "SAMPLE_VALUE_%d", frame.index + n);
            CHK_STATUS(putKinesisVideoFragmentMetadata(streamHandle, metadataKey, metadataValue, FALSE));
        }
    }
    defaultThreadSleep(frame.duration);

    frame.decodingTs += frame.duration;
    frame.presentationTs = frame.decodingTs;
    frameIndex++;
    fileIndex++;
    fileIndex = fileIndex % NUMBER_OF_FRAME_FILES;
    firstFrame = TRUE;
}

// 5. End the final fragment
putKinesisVideoFrame(streamHandle, &eofr);
```

設定範例影格的範例程式碼元素說明如下：

1. 每個片段都需要以片段結尾 (`eofr`)。此陳述式指出每當收到新的關鍵影格時，會發出下一個影格開頭的訊號，在將下一個影格新增至串流`eofr`之前，先放置 。

1. 將目前的影格放入串流。

1. 新增映像產生標籤。您可以在呼叫之後和 之前隨時`putFrame(keyFrame)`呼叫 `putKinesisVideoEventMetadata`方法`putFrame(eofr)`。每個片段最多只能呼叫一次。由於每個片段只有一個關鍵影格，因此我們為了簡單起見而呼叫它。的傳回值`putKinesisVideoEventMetadata`會檢查成功代碼 (0)。

1. 新增其他自訂片段中繼資料，Kinesis Video Streams 會將這些中繼資料轉換為 Amazon S3 物件中繼資料。

1. 結束此上傳工作階段中的最後一個片段。

### 使用範例來新增影像產生標籤
<a name="use-samples-add-image-gen-tags"></a>

如果您希望命令列選項新增影像產生標籤，則可以`kvs_gstreamer_audio_video_sample`在 C\+\+ Producer SDK 中使用 。透過新增 `-e image`或 `-e both`引數來啟用此功能，如下列範例所示。

```
./kvs_gstreamer_audio_video_sample {{stream-name}} \
  -f {{video-to-upload.mp4}} \
  -e both
```

如需此範例應用程式的詳細資訊，請參閱 GitHub 中的 [Amazon Kinesis Video Streams CPP Producer、GStreamer Plugin 和 JNI README](https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp/blob/master/README.md)。

## Amazon S3 物件路徑 （影像）
<a name="s3-object-path"></a>

S3 物件路徑說明所設定 S3 儲存貯體上將交付產生影像的位置。它使用下列格式：

```
{{ImagePrefix}}_{{AccountID}}_{{StreamName}}_{{ImageTimecode}}_{{RandomID}}.{{file-extension}}
```

物件路徑元素定義如下：
+ `ImagePrefix` - 值 ，`AWS_KINESISVIDEO_IMAGE_PREFIX`如果有的話。
+ `AccountID` - 建立串流的 AWS 帳戶 ID。
+ `StreamName` - 產生映像的串流名稱。
+ `ImageTimecode` - 產生影像的片段中的 Epoch 時間碼 （以毫秒為單位）。
+ `RandomID` - 隨機 GUID。
+ `file-extension` - 根據請求的影像格式的 JPG 或 PNG。

在此範例中，產生的映像的物件路徑如下所示：

```
111122223333_demo-stream_16907729324_f20f9add-75e7-4399-a30f-fc7aefb1bab7.jpg
```

## 擷取影像中繼資料
<a name="s3-object-metadata"></a>

您可以使用 S3 主控台或 CLI 來擷取產生映像的中繼資料。

Kinesis Video Streams 會設定片段編號、生產者和伺服器時間戳記，以及產生影像的內容類型中繼資料，全部格式化為 Amazon S3 物件中繼資料。如果存在任何其他 MKV 標籤，這些標籤也會新增為 Amazon S3 物件中繼資料。下列範例示範如何使用 Amazon S3 head-object API 命令來擷取物件中繼資料。回應包含 Kinesis Video Streams 建立的中繼資料。

```
aws s3api head-object --bucket {{my-bucket-name}} --key {{111122223333}}_{{demo-stream}}_1690707290324_f20f9add-7e57-4399-a30f-fc7aefb1bab7.jpg
{
    "AcceptRanges": "bytes",
    "LastModified": "2023-07-30T08:54:51+00:00",
    "ContentLength": 22693,
    "ETag": "\"63e03cb6d57f77e2db984c1d344b1083\"",
    "ContentType": "image/jpeg",
    "ServerSideEncryption": "AES256",
    "Metadata": {
        "aws_kinesisvideo_producer_timestamp": "1690707290324",
        "aws_kinesisvideo_server_timestamp": "1690707289209",
        "aws_kinesisvideo_fragment_number": "91343852333182036507421233921329142742245756394"
    }
}
```

如需 S3 物件中繼資料的詳細資訊，請參閱 [https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingMetadata.html](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingMetadata.html)。

## 防止限流的 Amazon S3 URI 建議
<a name="s3-uri-recommendations"></a>

如果您將數千張影像寫入 Amazon S3，會有限流風險。如需詳細資訊，請參閱 [S3 字首放置請求限制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html)。

Amazon S3 字首從每秒 3，500 個 PUT 請求的 PUT 限制開始，並會隨著時間逐漸增加唯一字首。避免使用日期和時間做為 Amazon S3 字首。時間編碼資料一次會影響一個字首，也會定期變更，使先前的字首擴展失效。

若要啟用更快速、一致的 Amazon S3 擴展，我們建議新增隨機字首，例如十六進位碼或 UUID 到 Amazon S3 目的地 URI。例如，十六進位碼字首自然會將您的請求隨機分割成 16 個不同的字首 （每個唯一十六進位字元的字首），這在 Amazon S3 自動擴展之後，允許每秒 56，000 個 PUT 請求。