|
|
|
#include "ffmpegvideodlg.h"
|
|
|
|
#include "ui_ffmpegvideodlg.h"
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
|
|
ffmpegvideoDlg::ffmpegvideoDlg(QWidget *parent)
|
|
|
|
: QWidget(parent), ui(new Ui::ffmpegvideoDlg) {
|
|
|
|
ui->setupUi(this);
|
|
|
|
ffmpegPushStream = nullptr;
|
|
|
|
pushStreamThread = nullptr;
|
|
|
|
// iniWindow();
|
|
|
|
m_flowType = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
ffmpegvideoDlg::~ffmpegvideoDlg() {
|
|
|
|
stop();
|
|
|
|
if (!ffmpeg)
|
|
|
|
ffmpeg->deleteLater();
|
|
|
|
delete ui;
|
|
|
|
if (ffmpegPushStream != nullptr)
|
|
|
|
ffmpegPushStream->deleteLater();
|
|
|
|
if (pushStreamThread != nullptr) {
|
|
|
|
pushStreamThread->quit();
|
|
|
|
pushStreamThread->wait();
|
|
|
|
pushStreamThread->deleteLater();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ffmpegvideoDlg::setVedioSaveFileDirPath(QString saveDirPath) {
|
|
|
|
videoSaveDirPath = saveDirPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief ffmpegvideoDlg::play
|
|
|
|
* @param url 拉流地址
|
|
|
|
*/
|
|
|
|
void ffmpegvideoDlg::play(QString url) {
|
|
|
|
if (!m_PlayStatus) {
|
|
|
|
m_PlayStatus = true;
|
|
|
|
ffmpeg = new Cffmpeg_decode;
|
|
|
|
ffmpeg->setSaveFileDirPath(videoSaveDirPath);
|
|
|
|
ffmpeg->setStreamUrl(url); // 设置拉流URL
|
|
|
|
ffmpeg->IsstopPlay = false;
|
|
|
|
ffmpeg->setPlayVideo(this->m_bVideoPlayFlag); // 设置是否播放视频
|
|
|
|
|
|
|
|
ffmpeg->setFlowType(m_flowType);
|
|
|
|
ffmpeg->moveToThread(&workerThread);
|
|
|
|
|
|
|
|
connect(&workerThread, &QThread::finished, ffmpeg,
|
|
|
|
&QObject::deleteLater); // 线程发送结束标志
|
|
|
|
connect(this, &ffmpegvideoDlg::operate, ffmpeg,
|
|
|
|
&Cffmpeg_decode::run); // 线程开始处理数据
|
|
|
|
// connect(this, &ffmpegvideoDlg::setUrlSign, ffmpeg,
|
|
|
|
// &Cffmpeg_decode::setUrl); // 设置URL
|
|
|
|
connect(ffmpeg, SIGNAL(sendQImage(QImage)), this,
|
|
|
|
SLOT(receiveQImage(QImage))); // 发送解析的图片
|
|
|
|
connect(ffmpeg, SIGNAL(sendConnectFail(int)), this,
|
|
|
|
SLOT(showMessagBox(int))); // 发送错误信息提示
|
|
|
|
workerThread.start();
|
|
|
|
emit this->operate(); // 启用线程信号,开始拉流
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 停止拉流
|
|
|
|
*/
|
|
|
|
void ffmpegvideoDlg::stop() {
|
|
|
|
if (m_PlayStatus) {
|
|
|
|
ffmpeg->stopPull();
|
|
|
|
ffmpeg->stop();
|
|
|
|
m_PlayStatus = false;
|
|
|
|
ffmpeg->IsstopPlay = true; // 线程结束标志
|
|
|
|
workerThread.quit(); // 线程退出时自动delete线程里的类
|
|
|
|
workerThread.wait();
|
|
|
|
img.fill(Qt::black);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 绘图事件
|
|
|
|
void ffmpegvideoDlg::paintEvent(QPaintEvent *) {
|
|
|
|
QPainter painter(this);
|
|
|
|
// 开启抗锯齿
|
|
|
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
|
|
|
painter.drawImage(m_ax, m_ay, img);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 区域大小改变事件
|
|
|
|
void ffmpegvideoDlg::resizeEvent(QResizeEvent *event) {
|
|
|
|
// 区域1920*1080自适应
|
|
|
|
double VideoAreaHeight = this->height();
|
|
|
|
double VideoAreaWidth = this->width();
|
|
|
|
// 高度值相对比较大
|
|
|
|
if (VideoAreaHeight * 16 > VideoAreaWidth * 9) {
|
|
|
|
m_setVideoAreaWidth = VideoAreaWidth;
|
|
|
|
m_setVideoAreaHeight = VideoAreaWidth * 9 / 16;
|
|
|
|
m_ax = 0;
|
|
|
|
m_ay = 0.5 * (VideoAreaHeight - m_setVideoAreaHeight);
|
|
|
|
}
|
|
|
|
// 宽度值相对比较大
|
|
|
|
else {
|
|
|
|
m_setVideoAreaHeight = VideoAreaHeight;
|
|
|
|
m_setVideoAreaWidth = VideoAreaHeight * 16 / 9;
|
|
|
|
m_ax = 0.5 * (VideoAreaWidth - m_setVideoAreaWidth);
|
|
|
|
m_ay = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ffmpegvideoDlg::receiveQImage(const QImage &rImg) {
|
|
|
|
|
|
|
|
// img = rImg.scaled(this->size());
|
|
|
|
QSize imgsize(m_setVideoAreaWidth, m_setVideoAreaHeight);
|
|
|
|
// 使用平滑缩放模式来减少图像模糊
|
|
|
|
img = rImg.scaled(imgsize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
// 显示不同提示消息
|
|
|
|
void ffmpegvideoDlg::showMessagBox(int type) {
|
|
|
|
switch (type) {
|
|
|
|
case 1:
|
|
|
|
QMessageBox::information(NULL, tr("提示"), "获取视频失败", QMessageBox::Ok);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool ffmpegvideoDlg::Isplay(bool IsstopPlay) {
|
|
|
|
return ffmpeg->IsstopPlay = IsstopPlay;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 设置拉流地址
|
|
|
|
* @param streamURL
|
|
|
|
*/
|
|
|
|
void ffmpegvideoDlg::setStreamIP(QString streamURL) { m_streamIP = streamURL; }
|
|
|
|
|
|
|
|
// 设置推流地址
|
|
|
|
void ffmpegvideoDlg::setPushStreamIP(QString pushStreamURL) {
|
|
|
|
m_pushStreamIP = pushStreamURL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 开始推流
|
|
|
|
void ffmpegvideoDlg::setPushStream(bool bPush) {
|
|
|
|
this->m_bPushStreamFlag = bPush;
|
|
|
|
if (this->m_bPushStreamFlag) {
|
|
|
|
this->play(m_streamIP);
|
|
|
|
// QThread::msleep(500);
|
|
|
|
// 创建推流任务对象
|
|
|
|
if (ffmpegPushStream == nullptr) {
|
|
|
|
ffmpegPushStream = new FFmpegPushStream;
|
|
|
|
}
|
|
|
|
ffmpegPushStream->setRemoteIP(m_pushStreamIP); // 设置推流地址
|
|
|
|
// 推流线程开启
|
|
|
|
if (pushStreamThread == nullptr) {
|
|
|
|
pushStreamThread = new QThread;
|
|
|
|
pushStreamThread->start();
|
|
|
|
ffmpegPushStream->moveToThread(pushStreamThread);
|
|
|
|
}
|
|
|
|
if (ffmpeg) {
|
|
|
|
connect(ffmpeg, &Cffmpeg_decode::sendInitPushStream_Signal,
|
|
|
|
ffmpegPushStream, &FFmpegPushStream::openNetworkStream,
|
|
|
|
Qt::UniqueConnection);
|
|
|
|
connect(ffmpeg, &Cffmpeg_decode::sendStreamData_Signal, ffmpegPushStream,
|
|
|
|
&FFmpegPushStream::pushStream, Qt::UniqueConnection);
|
|
|
|
connect(ffmpeg, &Cffmpeg_decode::sendStopPushStream_Signal,
|
|
|
|
ffmpegPushStream, &FFmpegPushStream::stopPush,
|
|
|
|
Qt::UniqueConnection);
|
|
|
|
// ffmpeg->bPushStreamFlag = true;
|
|
|
|
}
|
|
|
|
// qDebug() << "video threadID:" << QThread::currentThreadId();
|
|
|
|
ffmpeg->setPushStream(true);
|
|
|
|
} else { // 停止推流
|
|
|
|
ffmpeg->setPushStream(false);
|
|
|
|
if (!this->m_bVideoPlayFlag && !this->m_bPushStreamFlag)
|
|
|
|
this->stop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 视频播放
|
|
|
|
* @param bPlay: 是否播放
|
|
|
|
*/
|
|
|
|
void ffmpegvideoDlg::setPlayVideo(bool bPlay) {
|
|
|
|
if (m_PlayStatus && ffmpeg) {
|
|
|
|
// emit startPlayVideoSignal(bPlay);
|
|
|
|
ffmpeg->setPlayVideo(bPlay);
|
|
|
|
}
|
|
|
|
m_bVideoPlayFlag = bPlay;
|
|
|
|
if (!m_streamIP.isEmpty())
|
|
|
|
this->play(m_streamIP);
|
|
|
|
if (!this->m_bVideoPlayFlag && !this->m_bPushStreamFlag)
|
|
|
|
this->stop();
|
|
|
|
}
|