

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

# 将视频流式传输到你的 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`中键入。