

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

# 在树莓派上使用 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)请按照以下步骤操作，确保目标设备上已安装所有开源软件先决条件。