简易视频播放器2 (基于Qt、opencv)

因项目需要,需要实现一个对以保存的监测视频快速查看功能。
查询网上一些资料,初步简易的实现了一下。
实际效果图:

该程序基于Qt5.4,opencv248,开发环境为win8.1
结构为:

  • videoplayer.ui
  • videoplayer.h
  • videoplayer.cpp

由类 class VideoPlayer : public QWidget
实现 播放、暂停、进度条、播放速度等功能

代码
首先是界面:

即 ui_videoplayer.h

/********************************************************************************
** Form generated from reading UI file 'videoplayer.ui'
**
** Created by: Qt User Interface Compiler version 5.4.1
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_VIDEOPLAYER_H
#define UI_VIDEOPLAYER_H

#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSlider>
#include <QtWidgets/QSpacerItem>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_VideoPlayer
{
public:
    QWidget *verticalLayoutWidget;
    QVBoxLayout *verticalLayout;
    QSlider *horizontalSlider;
    QHBoxLayout *horizontalLayout;
    QPushButton *pushButton;
    QPushButton *pushButton_2;
    QLabel *label;
    QLabel *label_2;
    QSpacerItem *horizontalSpacer;
    QLabel *label_3;
    QComboBox *comboBox;

    void setupUi(QWidget *VideoPlayer)
    {
        if (VideoPlayer->objectName().isEmpty())
            VideoPlayer->setObjectName(QStringLiteral("VideoPlayer"));
        VideoPlayer->resize(640, 560);
        verticalLayoutWidget = new QWidget(VideoPlayer);
        verticalLayoutWidget->setObjectName(QStringLiteral("verticalLayoutWidget"));
        verticalLayoutWidget->setGeometry(QRect(10, 490, 621, 65));
        verticalLayout = new QVBoxLayout(verticalLayoutWidget);
        verticalLayout->setSpacing(6);
        verticalLayout->setContentsMargins(11, 11, 11, 11);
        verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
        verticalLayout->setContentsMargins(0, 0, 0, 0);
        horizontalSlider = new QSlider(verticalLayoutWidget);
        horizontalSlider->setObjectName(QStringLiteral("horizontalSlider"));
        horizontalSlider->setOrientation(Qt::Horizontal);
        horizontalSlider->setInvertedControls(false);
        horizontalSlider->setTickPosition(QSlider::NoTicks);

        verticalLayout->addWidget(horizontalSlider);

        horizontalLayout = new QHBoxLayout();
        horizontalLayout->setSpacing(6);
        horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
        pushButton = new QPushButton(verticalLayoutWidget);
        pushButton->setObjectName(QStringLiteral("pushButton"));

        horizontalLayout->addWidget(pushButton);

        pushButton_2 = new QPushButton(verticalLayoutWidget);
        pushButton_2->setObjectName(QStringLiteral("pushButton_2"));

        horizontalLayout->addWidget(pushButton_2);

        label = new QLabel(verticalLayoutWidget);
        label->setObjectName(QStringLiteral("label"));

        horizontalLayout->addWidget(label);

        label_2 = new QLabel(verticalLayoutWidget);
        label_2->setObjectName(QStringLiteral("label_2"));

        horizontalLayout->addWidget(label_2);

        horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);

        horizontalLayout->addItem(horizontalSpacer);

        label_3 = new QLabel(verticalLayoutWidget);
        label_3->setObjectName(QStringLiteral("label_3"));

        horizontalLayout->addWidget(label_3);

        comboBox = new QComboBox(verticalLayoutWidget);
        comboBox->setObjectName(QStringLiteral("comboBox"));

        horizontalLayout->addWidget(comboBox);

        verticalLayout->addLayout(horizontalLayout);

        retranslateUi(VideoPlayer);

        QMetaObject::connectSlotsByName(VideoPlayer);
    } // setupUi

    void retranslateUi(QWidget *VideoPlayer)
    {
        VideoPlayer->setWindowTitle(QApplication::translate("VideoPlayer", "VideoPlayer", 0));
        pushButton->setText(QApplication::translate("VideoPlayer", "play", 0));
        pushButton_2->setText(QApplication::translate("VideoPlayer", "stop", 0));
        label->setText(QApplication::translate("VideoPlayer", "00:00:00", 0));
        label_2->setText(QApplication::translate("VideoPlayer", "/ 00:00:00", 0));
        label_3->setText(QApplication::translate("VideoPlayer", "346222255346224276351200237345272246", 0));
        comboBox->clear();
        comboBox->insertItems(0, QStringList()
         << QApplication::translate("VideoPlayer", "1", 0)
         << QApplication::translate("VideoPlayer", "2", 0)
         << QApplication::translate("VideoPlayer", "3", 0)
         << QApplication::translate("VideoPlayer", "4", 0)
        );
    } // retranslateUi

};

namespace Ui {
    class VideoPlayer: public Ui_VideoPlayer {};
} // namespace Ui

QT_END_NAMESPACE
#endif // UI_VIDEOPLAYER_H

videoplayer.h

#ifndef VIDEOPLAYER_H
#define VIDEOPLAYER_H

#include <QWidget>
#include <QTimer>
#include <QMessageBox>

#include <cv.h>
#include <highgui.h>

namespace Ui {
class VideoPlayer;
}

class VideoPlayer : public QWidget
{
    Q_OBJECT

public:
    explicit VideoPlayer(QWidget *parent = 0);
    ~VideoPlayer();

private:
    Ui::VideoPlayer *ui;

private:
    QString _file_name;
    QTimer *_timer;

    CvCapture *_capture;
    IplImage  *_iplImg;
    IplImage  *_frame;

    QImage *_qImg;

    bool _flag;      //标志视频播放或暂停
    int _Position;   //视频帧位置
    int _totalFrames;//视频所有帧数

public:
    void Open_File(QString filename);
    void paintEvent(QPaintEvent *);

public slots:
    void nextFrame();
    void CallBackTrackBarSlide(int i);

    void playStart();
    void playStop();
    void play_speed_change(const QString &);
};
#endif // VIDEOPLAYER_H

videoplayer.cpp

#include "videoplayer.h"
#include "ui_videoplayer.h"
#include <QPainter>
#include <qdebug.h>

VideoPlayer::VideoPlayer(QWidget *parent) : QWidget(parent),ui(new Ui::VideoPlayer)
{
    ui->setupUi(this);
    this->setFixedSize(640,560);//这里将窗口固定,只能适合显示640*480大小的视频,如有其他需要,得改进

    _Position=0;
    _flag=false;

    _timer = new QTimer(this);
    _timer->setInterval(66);

    Open_File({"C://Users/xxx/Videos/6fish.AVI"});//这里可以扩展成打开指定的文件

    connect(_timer,&QTimer::timeout,this,&VideoPlayer::nextFrame);
    connect(ui->pushButton,&QPushButton::clicked,this,&VideoPlayer::playStart);
    connect(ui->pushButton_2,&QPushButton::clicked,this,&VideoPlayer::playStop);
    connect(ui->comboBox, &QComboBox::currentTextChanged,this,&VideoPlayer::play_speed_change);
}

VideoPlayer::~VideoPlayer()
{
    delete ui;
}


void VideoPlayer::paintEvent(QPaintEvent *){
    QPainter painter(this);
    painter.drawImage(QPoint(0,0),*_qImg);
}


void VideoPlayer::Open_File(QString filename){
    _file_name=filename;
    char*  ch;
    QByteArray ba = _file_name.toLatin1();
    ch = ba.data();

    this->setWindowTitle(_file_name);

    _capture = cvCaptureFromFile(ch);

    if(_capture){

        _totalFrames =  (int)cvGetCaptureProperty(_capture,CV_CAP_PROP_FRAME_COUNT);
        ui->horizontalSlider->setRange(0,_totalFrames);
        //时间不知道如何处理,用痕原始的方式
        int sec=_totalFrames/15;
        int min=sec/60;sec=sec%60;
        int h=min/60;min=min%60;
        if(sec<10&&min<10){
            ui->label_2->setText(tr("/ %0:0%1:0%2").arg(h).arg(min).arg(sec));
        }
        else if(sec<10){
            ui->label_2->setText(tr("/ %0:%1:0%2").arg(h).arg(min).arg(sec));
        }
        else if(min<10){
            ui->label_2->setText(tr("/ %0:0%1:%2").arg(h).arg(min).arg(sec));
        }
        else{
            ui->label_2->setText(tr("/ %0:%1:%2").arg(h).arg(min).arg(sec));
        }

        _frame = cvQueryFrame(_capture);

        _qImg = new QImage(QSize(_frame->width,_frame->height), QImage::Format_RGB888);
        _iplImg = cvCreateImageHeader(cvSize(_frame->width,_frame->height), 8,3);
        _iplImg->imageData = (char*)_qImg->bits();

        connect(ui->horizontalSlider, &QSlider::valueChanged,this, &VideoPlayer::CallBackTrackBarSlide);
        _timer->start();
        _flag=true;
    }
}

void VideoPlayer::nextFrame(){
    _frame = cvQueryFrame(_capture);

    if(_frame){
        cvCopy(_frame,_iplImg,0);
        cvCvtColor(_iplImg,_iplImg,CV_BGR2RGB);

        this->update();

        _Position++;
        if(_Position%15 == 0)
        {
            ui->horizontalSlider->setValue(_Position);
        }
    }
    else{ //video end
            _timer->stop();
            QMessageBox::information(this, tr("提示"), tr("视频结束!"));
            exit(1);
        }
}

void VideoPlayer::CallBackTrackBarSlide(int i){
    cvSetCaptureProperty(_capture,CV_CAP_PROP_POS_FRAMES,i);
    _Position =i;
   //时间不知道如何处理,用痕原始的方式
    int sec=_Position/15;
    int min=sec/60;sec=sec%60;
    int h=min/60;min=min%60;
    if(sec<10&&min<10){
        ui->label->setText(tr("%0:0%1:0%2").arg(h).arg(min).arg(sec));
    }
    else if(sec<10){
        ui->label->setText(tr("%0:%1:0%2").arg(h).arg(min).arg(sec));
    }
    else if(min<10){
        ui->label->setText(tr("%0:0%1:%2").arg(h).arg(min).arg(sec));
    }
    else{
        ui->label->setText(tr("%0:%1:%2").arg(h).arg(min).arg(sec));
    }
}


void VideoPlayer::playStart(){
    _timer->start();
    _flag=true;
}
void VideoPlayer::playStop(){
    _timer->stop();
    _flag=false;
}

void VideoPlayer::play_speed_change(const QString &){
    int play_speed=ui->comboBox->currentText().toInt();

    if(_flag){
        _timer->stop();
        _timer->start(66/play_speed);
    }
    else{
        _timer->start(66/play_speed);
        _timer->stop();
    }
}

原文地址:https://www.cnblogs.com/iois/p/4432836.html