如何用C++结合OpenCV将摄像头视频推流至RTSP服务器
解决方案:C++ + OpenCV 摄像头推流至RTSP服务器
第一步:搭建本地RTSP服务器
推荐使用rtsp-simple-server,轻量易操作,适合新手:
- 下载对应系统的版本(Windows/Linux/macOS)
- 解压后直接运行可执行文件,默认会在
rtsp://localhost:8554启动服务 - 可提前用VLC播放器测试地址
rtsp://localhost:8554/stream,后续推流成功即可看到画面
第二步:OpenCV推流配置(两种后端方案)
注意:你的OpenCV必须在编译时启用对应后端(FFMPEG/GSTREAMER),否则cv::CAP_FFMPEG或cv::CAP_GSTREAMER会失效。Windows用户可直接下载预编译的带FFMPEG的OpenCV包
方案1:FFMPEG后端推流
直接使用FFMPEG的命令行管道模式,兼容性更强,无需依赖OpenCV的FFMPEG编译选项(只要系统环境能调用ffmpeg):
cv::VideoWriter rtsp_writer; // 构造FFMPEG推流命令,将OpenCV的raw帧转码为H264并推送到RTSP服务器 std::string ffmpeg_cmd = "ffmpeg -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -s " + std::to_string(camera_frame_width) + "x" + std::to_string(camera_frame_height) + " -r " + std::to_string(camera_frame_rate) + " -i - -c:v libx264 -preset ultrafast -f rtsp rtsp://localhost:8554/stream"; // 初始化推流对象,第二个参数传0表示使用FFMPEG管道模式 bool success = rtsp_writer.open( ffmpeg_cmd, 0, camera_frame_rate, cv::Size(static_cast<int>(camera_frame_width), static_cast<int>(camera_frame_height)), true ); if (!success) { std::cerr << "Failed to open RTSP stream via FFMPEG\n"; return 1; }
如果系统没有全局ffmpeg,可指定ffmpeg可执行文件的绝对路径(如"C:/ffmpeg/bin/ffmpeg.exe ...")。
方案2:GSTREAMER后端推流
若OpenCV编译时启用了GSTREAMER,可使用GSTREAMER管道推流:
cv::VideoWriter rtsp_writer; // 构造GSTREAMER推流管道:将OpenCV输出的帧转码为H264,通过UDP发送到服务器 std::string gst_pipeline = "appsrc ! videoconvert ! x264enc tune=zerolatency ! rtph264pay ! udpsink host=localhost port=5000"; bool success = rtsp_writer.open( gst_pipeline, cv::CAP_GSTREAMER, 0, camera_frame_rate, cv::Size(static_cast<int>(camera_frame_width), static_cast<int>(camera_frame_height)), true ); if (!success) { std::cerr << "Failed to open GSTREAMER pipeline\n"; return 1; }
此时需要修改rtsp-simple-server的配置文件(rtsp-simple-server.yml),添加UDP源监听:
paths: stream: source: udp://localhost:5000
修改后重启rtsp-simple-server即可接收推流。
第三步:完整摄像头捕获+推流代码
#include <opencv2/opencv.hpp> #include <iostream> #include <string> int main() { // 初始化本地摄像头 cv::VideoCapture cap(0); // 0为默认摄像头,多个摄像头可尝试1、2等 if (!cap.isOpened()) { std::cerr << "Failed to open camera\n"; return 1; } // 获取摄像头参数 double camera_frame_rate = cap.get(cv::CAP_PROP_FPS); int camera_frame_width = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH)); int camera_frame_height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT)); // 初始化RTSP推流(选上述任一方案) cv::VideoWriter rtsp_writer; std::string ffmpeg_cmd = "ffmpeg -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -s " + std::to_string(camera_frame_width) + "x" + std::to_string(camera_frame_height) + " -r " + std::to_string(camera_frame_rate) + " -i - -c:v libx264 -preset ultrafast -f rtsp rtsp://localhost:8554/stream"; rtsp_writer.open(ffmpeg_cmd, 0, camera_frame_rate, cv::Size(camera_frame_width, camera_frame_height), true); if (!rtsp_writer.isOpened()) { std::cerr << "Failed to initialize RTSP stream\n"; return 1; } // 循环捕获并推流 cv::Mat frame; while (true) { cap >> frame; if (frame.empty()) { std::cerr << "Empty frame captured\n"; break; } // 写入推流对象 rtsp_writer.write(frame); // 可选:显示本地预览画面 cv::imshow("Camera Stream", frame); if (cv::waitKey(1) == 27) { // ESC键退出 break; } } // 释放资源 cap.release(); rtsp_writer.release(); cv::destroyAllWindows(); return 0; }
常见问题排查
- OpenCV后端未启用:编译OpenCV时需确保
WITH_FFMPEG或WITH_GSTREAMER选项为ON,Windows用户优先选择带FFMPEG的预编译包 - RTSP服务器未配置:检查rtsp-simple-server是否在运行,流路径与代码中一致
- 编码兼容性:优先使用H264编码(
fourcc('H','2','6','4')),比MJPG更通用 - 端口被拦截:确保本地8554(RTSP)、5000(UDP)端口未被防火墙或其他程序占用
内容的提问来源于stack exchange,提问作者Aitreya Verma
相关产品推荐
相关产品推荐

