Apollo相机数据RTMP推流与播放指南
Apollo相机数据RTMP推流与播放指南
-
- 前言
- 一、概述
-
- 1、什么是Apollo相机数据流?
- 2、为什么需要RTMP推流?
- 3、整体工作流程
- 二、搭建RTSP流媒体服务器
-
- 1、选择EasyDarwin的原因
- 2、服务器安装步骤详解
- 三、Apollo平台设置与推流
-
- 1. 安装依赖与FFmpeg编译
- 2. 从Topic获取图像并推流
-
- 2.1、生成代码
- 2.2、编译
- 2.3、播放record
- 2.4、运行推流程序
- 四、播放视频流
-
- 1、使用FFplay播放RTSP流
- 2、其他播放选项
- 五、故障排除与常见问题
- 六、性能优化建议
- 七、结论
前言
本文旨在帮助开发者理解如何从百度Apollo自动驾驶平台获取相机数据,并将其转换为实时视频流进行远程监控。
一、概述
1、什么是Apollo相机数据流?
百度Apollo平台使用多种传感器收集环境数据,其中相机是重要的视觉传感器。Apollo系统通过Cyber RT框架发布相机数据,这些数据以特定的消息格式在系统中传输。
2、为什么需要RTMP推流?
RTMP(Real-Time Messaging Protocol)是一种专为实时数据传输设计的协议,常用于视频直播领域。将Apollo的相机数据转换为RTMP流可以实现:
- 远程实时监控自动驾驶车辆的视觉感知
- 数据记录和后期分析
- 多用户同时观看而不影响主系统性能
- 与现有流媒体生态系统集成
3、整体工作流程
- 从Apollo Cyber RT订阅相机Topic获取原始图像数据
- 使用FFmpeg将图像编码为H.264视频流
- 通过RTMP协议推流到媒体服务器
- 客户端通过RTSP/RTMP协议从服务器拉流播放
二、搭建RTSP流媒体服务器
1、选择EasyDarwin的原因
EasyDarwin是一款开源RTSP流媒体服务器,基于Go语言开发,具有:
- 轻量级且跨平台
- 支持RTSP、RTMP等多种协议
- 活跃的开源社区支持
- 易于部署和配置
2、服务器安装步骤详解
# 安装Go语言环境(如果尚未安装)
wget https://golang.google.cn/dl/go1.25.1.linux-amd64.tar.gz
rm /usr/local/go -rf
tar -xf go1.25.1.linux-amd64.tar.gz -C /usr/local/# 设置Go环境变量(建议添加到~/.bashrc或~/.zshrc)# 获取EasyDarwin源码
git clone https://github.com/EasyDarwin/EasyDarwin.git
cd EasyDarwin# 解决依赖关系
go mod tidy# 编译Linux版本
make build/linux# 进入构建目录
cd build
cd EasyDarwin-lin-"version"-"build-time" # 实际目录会根据版本和时间变化# 启动服务器
bash start.sh# 检查服务器是否正常运行
netstat -anp | grep easydarwin
三、Apollo平台设置与推流
1. 安装依赖与FFmpeg编译
Apollo平台通常运行在NVIDIA Jetson等嵌入式设备上,需要利用硬件编码器(如NVDEC/NVENC)提高编码效率。标准FFmpeg不包含这些专用硬件支持,因此需要打补丁并重新编译。
# 创建工作目录
mkdir -p /apollo_workspace/test
cd /apollo_workspace/test# 获取FFmpeg源码(使用release/7.1分支)
git clone git://source.ffmpeg.org/ffmpeg.git -b release/7.1 --depth=1# 下载Jetson-FFmpeg补丁
git clone https://github.com/Keylost/jetson-ffmpeg# 应用补丁(使FFmpeg支持NVIDIA硬件编解码)
cd jetson-ffmpeg
./ffpatch.sh ../ffmpeg# 编译安装nvmpi(NVIDIA Media Programming Interface)
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig# 配置FFmpeg启用NVMPI
cd ../../ffmpeg/
./configure --enable-nvmpi --prefix=`pwd`/_install
make -j4
sudo make install
2. 从Topic获取图像并推流
2.1、生成代码
下面的C++程序实现了从Apollo Cyber RT订阅相机Topic,并将图像数据推流到RTMP服务器:
cd /apollo_workspace/test
cat > rtmp_streamer.cpp << 'EOF'
#include <atomic>
#include <csignal>
#include <cstring>
#include <iostream>
#include <memory>
#include <string>
#include <thread>#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>
#include <libswscale/swscale.h>
}#include <opencv2/opencv.hpp>
#include "cyber/cyber.h"
#include "modules/common_msgs/sensor_msgs/sensor_image.pb.h"using apollo::cyber::Node;
using apollo::cyber::Reader;
using apollo::drivers::Image;#undef av_err2str
inline const char* av_err2str(int errnum) {thread_local char buf[AV_ERROR_MAX_STRING_SIZE];av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, errnum);return buf;
}class RtmpStreamer {
public:RtmpStreamer(int width = 1920, int height = 1080,int framerate = 10, int bitrate = 4000000);~RtmpStreamer();bool StartStreaming(const std::string& rtmp_url);bool WriteFrame(const cv::Mat& frame);void StopStreaming();bool IsStreaming() const;private:bool InitializeConverter();bool InitializeCodec(const std::string& rtmp_url);AVFormatContext* format_context_;AVCodecContext* codec_context_;AVStream* stream_;const AVCodec* codec_;SwsContext* sws_context_;AVFrame* yuv_frame_;int width_;int height_;int framerate_;int bitrate_;int64_t pts_counter_;bool is_streaming_;
};class ImageStreamer {
public:ImageStreamer() : streamer_(nullptr) {}void ImageCallback(const std::shared_ptr<Image>& image_msg);bool Initialize(const std::string& topic, const std::string& rtmp_url);private:std::unique_ptr<RtmpStreamer> streamer_;std::string rtmp_url_;std::unique_ptr<Node>