#include "ffmpegvideodlg.h" #include "ui_ffmpegvideodlg.h" #include 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->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(); }