使用 OpenCV 将笔记本摄像头推流成 RTSP
title: 使用 OpenCV 将笔记本摄像头推流成 RTSP
url: opencv-gstreamer-camera-to-rtsp
date: 2024年03月22日
category: C++
tags:
- OpenCV
RTSP
使用 OpenCV 将笔记本摄像头推流成 RTSP
使用 OpenCV 将笔记本摄像头推流成 RTSP
- 下载 Gstreamer
- 克隆 OpenCV 源码
- 使用 CMake 构建
- 代码示例
从 Gstreamer 官网下载安装包,先安装 runtime installer,再安装 development installer。
安装完成后添加环境变量
克隆 opencv 源码,使用 Git 克隆源码,这样再构建中下载是从 Gitcode 下载;如果下载了 zip,会从 GitHub 下载速度很慢。
使用 Git Bash GUI 克隆
然后切换到 4.8.0 的 tag
打开 CMake GUI,填写源码目录和安装目录;
然后点击 Configure,可以看到 Configure 过程中 gitcode 下载
Configure 完成之后搜索 gstreamer,相关的 GStreamer 库路径已经自动识别,默认勾选了 WITH_GSTREAMER
然后再次点击 Configure,查看构建信息,GStreamer 选项已打开
点击 Generate,完成后 Open Project,使用 VS2022 打开项目
生成 ALL_BUILD,再生成 INSTALL。opencv 就安装在了指定的 build 路径下的 install 目录里。目录中包含 include 和 x64\vs17\bin、x64\vs17\lib 就是我们需要的。
使用 VS2022 创建一个 CMake 项目,推流的关键代码如下:
void cvstream::read_rtsp()
{
do
{
cv::VideoCapture vid_capture(videosource);
if (!vid_capture.isOpened())
{
cout << "Error opening video stream or file" << endl;
return;
}
else
{
int fps = vid_capture.get(CAP_PROP_FPS);
cout << "Frames per second :" << fps;
}
dWidth = vid_capture.get(cv::CAP_PROP_FRAME_WIDTH);
dHeight = vid_capture.get(cv::CAP_PROP_FRAME_HEIGHT);
while (vid_capture.isOpened())
{
Mat frame;
bool isSuccess = vid_capture.read(frame);
if (isSuccess == true)
{
std::lock_guard<std::mutex> guard(mutex);
bool flag = this->frame.empty();
this->frame = frame.clone();
if (flag) {
this->streamThread = std::thread(&cvstream::stream_publish, this);
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
if (isSuccess == false)
{
cout << "video end" << endl;
isWorking = false;
break;
}
}
vid_capture.release();
return;
} while (false);
}
void cvstream::stream_publish()
{
std::string gst = "appsrc ! videoconvert ! video/x-raw, format=I420 ! x264enc speed-preset=veryfast \
bitrate=4096 key-int-max=40 ! rtspclientsink location=rtsp://127.0.0.1:8554/"+stream_url;
cv::VideoWriter video(gst, cv::CAP_GSTREAMER, 0, 25, cv::Size (dWidth, dHeight), true);
if (!video.isOpened()) {
std::cerr << "Could not open the output video for write\n";
return;
}
while (isWorking)
{
cv::Mat frame;
{
std::lock_guard<std::mutex> guard(mutex);
frame = this->frame.clone();
}
video.write(frame);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
代码中的 rtsp://127.0.0.1:8554
是 RTSP 服务器的地址,这里使用 mediamtx 作为 RTSP 服务器。
完整代码下载:opencv_video_stream