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

 更新时间:2023年08月24日 09:55:07   作者:coder_Alaric  
这篇文章主要为大家介绍了基于Qt+opencv开发的视频播放器示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

1、开发环境

Qt:Qt5.14

opencv:4.5.5

2、效果展示

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

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;
};

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

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()
{
    while(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.release();//释放打开的视频
}
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。

源码学习

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

videoPlay视频播放器源码

以上就是基于Qt+opencv开发的视频播放器示例详解的详细内容,更多关于Qt opencv视频播放器的资料请关注脚本之家其它相关文章!

相关文章

  • 基于C++实现的哈夫曼编码解码操作示例

    基于C++实现的哈夫曼编码解码操作示例

    这篇文章主要介绍了基于C++实现的哈夫曼编码解码操作,结合实例形式分析了C++实现的哈夫曼编码解码相关定义与使用技巧,需要的朋友可以参考下
    2018-04-04
  • C语言结构体指针引用详解

    C语言结构体指针引用详解

    C语言中结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针。本文将详细为大家介绍一下这两种结构体指针如何引用,需要的小伙伴可以参考一下
    2021-12-12
  • C语言使用DP动态规划思想解最大K乘积与乘积最大问题

    C语言使用DP动态规划思想解最大K乘积与乘积最大问题

    Dynamic Programming动态规划方法采用最优原则来建立用于计算最优解的递归式,并且考察每个最优决策序列中是否包含一个最优子序列,这里我们就来展示C语言使用DP动态规划思想解最大K乘积与乘积最大问题
    2016-06-06
  • C语言修炼之路数据类型悟正法 解析存储定风魔上篇

    C语言修炼之路数据类型悟正法 解析存储定风魔上篇

    使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。您可能需要存储各种数据类型的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么
    2022-02-02
  • C++中allocator类使用示例

    C++中allocator类使用示例

    大家好,本篇文章主要讲的是C++中allocator类使用示例,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • C++20中的结构化绑定类型示例详解

    C++20中的结构化绑定类型示例详解

    这篇文章主要为大家介绍了C++20中的结构化绑定类型示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • C++实现矩阵原地转置算法

    C++实现矩阵原地转置算法

    这篇文章主要介绍了C++实现矩阵原地转置算法,非常经典的算法,需要的朋友可以参考下
    2014-08-08
  • windows下在vim中搭建c语言开发环境的详细过程

    windows下在vim中搭建c语言开发环境的详细过程

    这篇文章主要介绍了windows下在vim中搭建c语言开发环境,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • Qt拖放操作和打印操作的实现

    Qt拖放操作和打印操作的实现

    本文主要介绍了Qt拖放操作和打印操作的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • C/C++ 中memset() 函数详解及其作用介绍

    C/C++ 中memset() 函数详解及其作用介绍

    这篇文章主要介绍了C/C++ 中memset() 函数详解及其作用介绍,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论