通过上两篇博客:Qt+FFmpeg播放RTSP H264视频流(1)- 在Qt项目加入FFmpeg库 和Qt+FFmpeg播放RTSP H264视频流(2)- FFmpeg自定义类封装已经大概了解了FFmpeg的工作过程,本编接上两篇完成一个简单的RTSP播放器。大致界面如下,代码下载地址:Qt工程完整代码下载
播放逻辑如下:
RTSP_Player.h
#ifndef RTSP_PLAYER_H
#define RTSP_PLAYER_H
#include “MyFFmpeg.h”
#include
class RTSP_Player : public QObject
{
Q_OBJECT
public:
enum PlayerState {
FFmpegInitFail = 0,
FFmpegInitSucc,
FFmpegStoped
};
explicit RTSP_Player(MyFFmpeg *ffmpeg = nullptr, QObject *parent = nullptr);
void SetPlayerUrl(QString playerUrl);
signals:
void SigOpenUrlResult(int result);
public slots:
void PlayerStart();
void PlayerStop();
private:
volatile bool m_stopped; // 停止播放标识,为true时停止播放,退出播放循环
QString m_playerUrl; // 播放url
MyFFmpeg *m_ffmpeg; // MyFFmepg指针
};
#endif // RTSP_PLAYER_H
RTSP_Player.cpp
#include "RTSP_Player.h"
#include
}
void RTSP_Player::SetPlayerUrl(QString playerUrl)
{
this->m_playerUrl = playerUrl;
}
void RTSP_Player::PlayerStart()
{
if (m_ffmpeg == NULL){
emit SigOpenUrlResult(RTSP_Player::FFmpegInitFail);
return;
}
m_ffmpeg->MyFFmpegSetUrl(this->m_playerUrl);
if (m_ffmpeg->MyFFmpegInit() != 0) {
emit SigOpenUrlResult(RTSP_Player::FFmpegInitFail);
return;
}
emit SigOpenUrlResult(RTSP_Player::FFmpegInitSucc);
m_stopped = false;
while (1) {
if (m_stopped){
qDebug("--------------- stop ----------------");
break;
}
if (!m_ffmpeg) {
break;
}
if (m_ffmpeg->MyFFmpepReadFrame() < 0) {
qDebug("--------------- get frame fail, stop -----------");
break;
}
QThread::msleep(0.02);
}
m_ffmpeg->MyFFmpegDestroy();
emit SigOpenUrlResult(RTSP_Player::FFmpegStoped);
qDebug("---------------- quit -----------------");
return;
}
void RTSP_Player::PlayerStop()
{
m_stopped = true;
}
FFmpegLibTestFrm.h
#ifndef FFMPEGLIBTESTFRM_H
#define FFMPEGLIBTESTFRM_H
#include
#include
#include
#include “RTSP_Player.h”
namespace Ui {
class FFmpegLibTestFrm;
}
class FFmpegLibTestFrm : public QMainWindow
{
Q_OBJECT
public:
explicit FFmpegLibTestFrm(QWidget *parent = 0);
~FFmpegLibTestFrm();
void MyFFmpegTest();
void PlayStart();
void PlayStop();
void PlayProcess();
protected:
void paintEvent(QPaintEvent *e);
void closeEvent(QCloseEvent *e);
private slots:
void SlotGetOneFrame(QImage img);
void SlotOpenUrlResult(int result);
void on_btnPlayer_clicked();
signals:
void SigPlayStart();
private:
QString m_playUrl;
MyFFmpeg *m_ffmpeg = nullptr;
RTSP_Player *m_player = nullptr;
QImage m_image;
QThread *m_playThread = nullptr;
private:
Ui::FFmpegLibTestFrm *ui;
};
#endif // FFMPEGLIBTESTFRM_H
#include "FFmpegLibTestFrm.h" #include "ui_FFmpegLibTestFrm.h" #include "MyHelper.h" #include
extern "C" { #include #include #include #include #include #include #include } FFmpegLibTestFrm::FFmpegLibTestFrm(QWidget *parent) : QMainWindow(parent), ui(new Ui::FFmpegLibTestFrm) { ui->setupUi(this); m_ffmpeg = new MyFFmpeg; connect(m_ffmpeg, SIGNAL(MyFFmpegSigGetOneFrame(QImage)), this, SLOT(SlotGetOneFrame(QImage))); ui->labVideo->setStyleSheet("QLabel{border:2px solid green}"); ui->labVideo->installEventFilter(this); ui->btnPlayer->setEnabled(true); } FFmpegLibTestFrm::~FFmpegLibTestFrm() { delete ui; } void FFmpegLibTestFrm::MyFFmpegTest() { MyFFmpeg *ffmpeg = new MyFFmpeg(); QString rtspUrl = "rtsp://192.168.88.168:554/0"; ffmpeg->MyFFmpegSetUrl(rtspUrl); if (ffmpeg->MyFFmpegInit() == 0) { int i; for (i = 0; i < 5; i++) { ffmpeg->MyFFmpepReadFrame(); } } else { qDebug("MyFFmpegInit fail!\n"); } delete ffmpeg; } void FFmpegLibTestFrm::PlayStop() { if (m_player) { m_player->PlayerStop(); } if (m_playThread) { m_playThread->quit(); m_playThread->wait(1000); delete m_playThread; m_playThread = nullptr; } if (m_player) { delete m_player; m_player = nullptr; } } void FFmpegLibTestFrm::PlayStart() { this->PlayStop(); m_playThread = new QThread(); m_player = new RTSP_Player(m_ffmpeg); m_player->SetPlayerUrl(m_playUrl); connect(this, SIGNAL(SigPlayStart()), m_player, SLOT(PlayerStart())); connect(m_player, SIGNAL(SigOpenUrlResult(int)), this, SLOT(SlotOpenUrlResult(int))); m_player->moveToThread(m_playThread); m_playThread->start(); } void FFmpegLibTestFrm::PlayProcess() { this->PlayStart(); emit SigPlayStart(); } void FFmpegLibTestFrm::SlotOpenUrlResult(int result) { if (result == RTSP_Player::FFmpegInitFail) { this->PlayStop(); QString rtspUrl = ui->txtRTSPURL->text().trimmed(); QString errMsg = "打开" + rtspUrl + "失败"; MyHelper::ShowMessageBoxError(errMsg); ui->btnPlayer->setText("start"); } else if (result == RTSP_Player::FFmpegInitSucc) { ui->btnPlayer->setText("stop"); } else if (result == RTSP_Player::FFmpegStoped) { ui->btnPlayer->setText("start"); } ui->btnPlayer->setEnabled(true); } void FFmpegLibTestFrm::SlotGetOneFrame(QImage image) { m_image = image; this->update(); } void FFmpegLibTestFrm::closeEvent(QCloseEvent *event) { this->PlayStop(); } void FFmpegLibTestFrm::paintEvent(QPaintEvent *event) { QPainter painter(this); if (m_image.size().width() <= 0) return; QImage img = m_image.scaled(ui->labVideo->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); int x = ui->labVideo->geometry().x(); int y = ui->labVideo->geometry().y(); painter.drawImage(QPoint(x, y), img); } void FFmpegLibTestFrm::on_btnPlayer_clicked() { if (ui->btnPlayer->text().compare("start") == 0) { m_playUrl = ui->txtRTSPURL->text().trimmed(); if (m_playUrl.length() <= (int)strlen("rtsp://")) { MyHelper::ShowMessageBoxError("请输入rtsp播放地址!"); return; } ui->btnPlayer->setEnabled(false); this->PlayProcess(); } else if (ui->btnPlayer->text().compare("stop") == 0) { ui->btnPlayer->setEnabled(false); this->PlayStop(); } } 播放效果