You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Conception/mjpg_streamer/最小路径.txt

138 lines
4.0 KiB

2 years ago
下面是一个简单的使用Qt Creator和OpenCV搭建可以播放RTSP视频的界面的示例。本例中为了展示更多读者可能需要的部分比例较为详细
首先在Qt Creator中创建一个新的Qt Widgets应用程序。
添加QLabel作为显示视频图像的容器并将该标签放置在MainWindow的UI界面上。
使用信号/槽机制连接QPushButton控件以提供“Play”和“Stop”按钮的功能。
在窗口的构造函数中初始化OpenCV中的VideoCapture对象。此处调用set函数配置FrameRingBuffer的长度从而满足读取较慢反应不够其余只调用isOpened方法判断是否可正常读入即可。
稍后你可以编写一个槽函数来读取视频流并将帧显示在QLabel中。
mainwindow.h文件
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <opencv2/core/mat.hpp>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_playButton_clicked();
void on_stopButton_clicked();
void readFrame();
private:
Ui::MainWindow *ui;
cv::VideoCapture mCapture; // Video capture object for reading RTSP stream
cv::Mat mFrame; // Mat object to store the video frame
bool mPlaying; // Flag to indicate if video playback is in progress
};
#endif // MAINWINDOW_H
mainwindow.cpp文件
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QTimer>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Set up VideoCapture object for reading RTSP stream
//调节参数 取决于对视频流带宽要求以及本机性能 适点即可
mCapture.set(cv::CAP_PROP_BUFFERSIZE,5);
mCapture.open("rtsp://localhost:8554/unicast"); //修改RTSP地址
if (!mCapture.isOpened())
{
qCritical() << "Failed to open RTSP stream.";
return;
}
//初始化mFrame和mPlaying标记
mPlaying = false;
//设置Paly按钮为不可用状态
ui->playButton->setEnabled(true);
ui->stopButton->setEnabled(false);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_playButton_clicked()
{
if (!mPlaying)
{
mPlaying = true;
// 每20毫秒读取一帧并在QLabel显示该帧图像
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::readFrame);
timer->start(20);
//设置控件状态
ui->playButton->setEnabled(false);
ui->stopButton->setEnabled(true);
}
}
void MainWindow::readFrame()
{
if (mCapture.read(mFrame))
{
QImage frameImage((uchar*)mFrame.data, mFrame.cols, mFrame.rows, QImage::Format_RGB888);
QPixmap framePixmap = QPixmap::fromImage(frameImage.rgbSwapped());
// .rgbSwapped()因为OpenCV默认使用BGR而Qt使用RGB必须交换颜色通道才能正确地显示
ui->videoLabel->setPixmap(framePixmap.scaled(ui->videoLabel->size(), Qt::KeepAspectRatio));
}
}
void MainWindow::on_stopButton_clicked()
{
if (mPlaying)
{
mPlaying = false;
//停止计时器,断开信号/槽连接
QObject::disconnect(this, &MainWindow::readFrame, nullptr, nullptr);
//设置控件状态
ui->playButton->setEnabled(true);
ui->stopButton->setEnabled(false);
//清除QLabel
ui->videoLabel->clear();
}
}
注意上述代码中的RTSP地址需要根据实际情况进行修改。在这里只是将RTSP的地址写为本机地址从而获得源不被限制的可播放视频。
此示例仅演示了如何从RTSP流读取一帧并在QLabel中显示该帧图像。你可以使用QSpinBox或QSlider等Qt控件来添加FPS和播放进度条的功能。以及像界面美化异常处理带宽控制和多线程优化等其余实现可能 Related Post 中可能会涉及。