开发者

基于Qt+opencv开发的视频播放器示例详解

目录
  • 1、开发环境
  • 2、效果展示
  • 3、代码功能解析
    • 3.1 opencv库加载
    • 3.2 重写horizontalSlider点击事件
    • 3.3 opencv采集线程
  • 总结

    1、开发环境

    Qt:Qt5.14

    opencv:4.5.5

    2、效果展示

    基于Qt+opencv开发的视频播放器示例详解

    可以实现播放、暂停、快进、后退、重新播放、停www.devze.com止、拖动进度条等功能;

    3、代码功能解析

    3.1 opencv库加载

    因为使用了opencv的VideoCapture来加载视频,这里需要添加opencv的库,右键项目工程添加外部库,填入opencv的库和头文件路径,或者直接在皮肉文件下添加库的文件路径。

    win32:CONFIG(release, debug|release): LIBS += -LD:/opencv/build/x64/vc15/lib/ -lopencv_world455
    else:win32:CONFIG(debug, debug|release): LIBS += -LD:/opencv/build/x64/vc15/lib/ -lopencv_world455d
    
    INCLUDEPATH += D:/opencv/build/include
    DEPENDPATH += D:/opencv/build/include

    这里我的opencv路径在D盘对应路径下。

    3.2 重写horizontalSlider点击事件

    这里需要点击进度条实现视频跳转到当前进度的功能,这里需要对horizontalSlider的点击事件函数进行重写。实现点击后获取点击处的进度值并更新进度条。

    #include "newqslider.h"
    newqslider::newqslider(QWidget *parent) : QSlider(parent)
    {
    }
    /*****************************************************************
    * 函数名称:mousePressEvent(QMouseEvent *ev)
    * 功能描述:重写鼠标点击事件,实现进度条点击哪跳到哪
    * 参数说明: 无
    * 返回值:   无
    ******************************************************************/
    void newqslider::mousePressEvent(QMouseEvent *ev)
    {
        //先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况
        QSlider::mousePressEvent(ev);
        //获取鼠标的位置,这里并不能直接从ev中取值(因为如果是拖动的话,鼠标开始点击的位置没有意义了)
        double pos = ev->pos().x() / (double)width();
        setValue(pos * (maximum() - minimum()) + minimum());
        //发送自定义的鼠标单击信号
        emit costomSliderClicked();
    }

    3.3 opencv采集线程

    videothread.h
    #include <QObject>
    #include <QThread>
    #include <opencv2/opencv.hpp>
    #include <IOStream>
    #include <QDebug>
    #include <QDateTime>
    using namespace  std;
    using namespace  cv;
    class videothread : public QThread
    {
        Q_OBJECT
    public:
        videothread(const char* filename);
        void run();
        //释放视频采集对象
        void releaseCap();
        //获取视频总帧数
        int getVideoAllFramecount();
        //设置当前进度条
     编程客栈   void setCurrentFrame(int value);
        bool getStop() const;
        //设置视频结束标识
        void setStop(bool value);
        bool getIsrun() const;
        void setIsrun(bool value);
        //暂停
        void pauseThread();
        //继续
        void resumeThread();
        //停止
        void stopThread();
    signals:
        //发送当前帧和 帧数
        void sendFrame(int currentFrame,Mat frame);
    private:
        //视频对象
        VideoCapture cap;
        Mat frame;
        //视频当前帧数
        int currentFramecount;
        //总帧数
        int allFramecount;
        //视频帧率
        int fps;
        //录制视频帧
        int videoWriterFrame;
        //线程结束标识位
        bool stop;
        //视频暂停标识位
        bool isrun;
    };

    采集线程中设zZUXJAkwRx置了暂停、继续播放、停止,并可以获取帧率和帧率数量;

    videothread.cpp
    #include "videothread.h"
    videothread::videothread(const char* filename)
    {
        this->stop = false;
        this->isrun =false;
        this->currentFramecount=0;
        this->videoWriterFrame=0;
        if(cap.open(filename));//创建视频对象
        {
            this->allFramecount=cap.get(CAP_PROP_FRAME_COUNT);//获取视频文件中的总帧数
            this->fps=int(round(cap.get(CAP_PROP_FPS)));//获取视频帧率
        }
    }
    void videothread::run()
    {
        whi编程客栈le(stop==false)//线程运行和停止  卡住线程 暂停时不退出线程
        {
            while(isrun==true)//视频运行和暂停
            {
                if(cap.read(frame))//捕获视频帧
                {
                    this->currentFramecount++;
                    cvtColor(frame, frame, COLOR_BGR2RGB);//opencvbGR格式转成Image用到的RGB
                    emit sendFrame(currentFramecount,frame);//发送帧数据
                }
                msleep(40);//延时
            }
        }
        cap.phprelease();//释放打开的视频
    }
    int videothread::getVideoAllFramecount()
    {
        return allFramecount;
    }
    void videothread::setStop(bool value)
    {
        stop = value;
    }
    void videothread::setCurrentFrame(int value)
    {
        this->currentFramecount=value;//当前帧数
        cap.set(CAP_PROP_POS_FRAMES,currentFramecount);//进度条跳转对应帧
    }
    bool videothread::getIsrun() const
    {
        return isrun;
    }
    void videothread::setIsrun(bool value)
    {
        isrun = value;
    }
    void videothread::pauseThread()//这两个函数用于确保是在运行情况下才能切换状态
    {
        if(this->isRunning()&&this->isrun==true)//当前线程运行且视频运行
        {
            this->isrun=false;
        }
    }
    void videothread::resumeThread()
    {
        if(this->isRunning()&&this->isrun==false)//当前线程运行且视频暂停
        {
            this->isrun=true;
        }
    }
    void videothread::stopThread()
    {
        if(this->isRunning())//当前线程运行
        {
            this->stop=true;//结束线程
            //msleep(10);
            releaseCap();
            this->terminate();
        }
    }
    bool videothread::getStop() const
    {
        return stop;
    }
    void videothread::releaseCap()
    {
        if(cap.isOpened()){
            cap.release();
        }
    }

    总结

    此视频播放器只涉及到opencv加载视频和对视频帧的处理,以及进度条管理等部分功能,包括加载视频后线程发送视频帧图像和帧数,再使用中需要注意线程指针的创建和释放、opencv采图对象的新建和释放,不然频繁停止和加载会出现野指针和内存泄漏的bug。

    基于Qt+opencv开发的视频播放器示例详解

    基于Qt+opencv开发的视频播放器示例详解

    源码学习

    最后附上源码大家交流学习,可以在仓库按需自取,仓库中代码仅供学习使用。如果对自己有帮助,麻烦点个星支持一下。

    videoPlay视频播放器源码

    以上就是基于Qt+opencv开发的视频播放器示例详解的详细内容,更多关于Qt opencv视频播放器的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜