OpenCV开发专栏(点击传送门)
需求
使用OpenCV库的视频播放器(支持播放器操作,如暂停、恢复、停止、时间、进度条拽托等)。
原理
使用OpenCV打开视频文件,获取总帧数,根据当前帧数,刷新当前时间戳与预期的时间间隔,调用槽函数动态刷新播放内容。
注意
当前只测试了avi文件。
相关博客
《OpenCV开发笔记(四):OpenCV图片和视频数据的读取与存储》
《项目实战:Qt+OpenCV操作摄像头拍照、调节参数和视频录制》
《项目实战:Qt+OpenCV视频播放器(支持播放器操作,如暂停、恢复、停止、时间、进度条拽托等)》
《Qt实用技巧:使用QMediaPlayer和Windows自带组件播放swf、rmvb、mpg、mp4等视频文件》
《Qt实用技巧:使用QMediaPlayer播放mp4文件》
Demo:OpenCVPlayer v1.0.0
运行效果
下载地址
CSDN:openCVPlayerv1.0.0.rar_qt中OpenCV中视频播放、暂停-QT其他资源-CSDN下载
核心类代码
OpenCVPlayerManager.h
#ifndef OPENCVPLAYERMANAGER_H #define OPENCVPLAYERMANAGER_H /************************************************************\ * 控件名称: OpenCVPlayerManager,OpenCV管理类 * 控件描述: * 1.OpenCV打开视频文件 * 2.播放器操作:播放、暂停、停止 * 3.播放时显示:当前时间、总时间 * 4.设置当前播放的时间点 * * 作者:红模仿 联系方式:QQ21497936 * 博客地址:https://blog.csdn.net/qq21497936 * 日期 版本 描述 * 2019年11月25日 v1.0.0 opencv打开文件 \************************************************************/ #include <QObject> #include <QImage> #include <QTimer> #include <QElapsedTimer> // opencv #include "opencv/highgui.h" #include "opencv/cxcore.h" #include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/opencv.hpp" class OpenCVPlayerManager : public QObject { Q_OBJECT public: enum PLAY_STATE { PLAY_STATE_PLAYING, PLAY_STATE_PAUSE, PLAY_STATE_STOP }; public: explicit OpenCVPlayerManager(QObject *parent = 0); ~OpenCVPlayerManager(); public: QString getWindowTitle() const; public: void setWindowTitle(const QString &windowTitle); signals: void signal_captureOneFrame(cv::Mat mat); // 接收图像后抛出信号 void signal_playStateChanged(OpenCVPlayerManager::PLAY_STATE playState); // 播放器状态 void signal_durationChanged(qint64 duration); // 视频总长度 void signal_positionChanged(qint64 position); // 当前位置 public: bool startPlay(QString filePath, int width = 480, int height = 320); void pause(); // 暂停 void resume(); // 恢复播放 void stopPlay(); // 停止播放 void setPosition(qint64 position); // 切换到播放位置 public slots: bool slot_start(); // 开启线程 bool stop(); // 关闭线程 protected slots: void slot_captrueFrame(); // 消息循环获取图像 void slot_stopPlay(); // 停止播放 void slot_setPosition(qint64 position); public: static QImage cvMat2QImage(const cv::Mat &mat); private: cv::VideoCapture *_pVideoCapture; // 播放文件实例 QString _filePath; // 播放文件路径 bool _running; // 线程是否运行 int _totalFrames; // 总帧数 int _fps; // 每秒帧数 int _currentFrame; // 当前帧数 int _width; // 高度 int _height; // 宽度 QElapsedTimer _elapsedTimer; // 计时器 qint64 _pauseMs; // 暂停的毫秒 qint64 _duration; // 视频总长度(毫秒) PLAY_STATE _playState; // 播放器状态 int _position; // 改变到的播放位置 bool _setPostion; // 播放位置修改标志 private: QString _windowTitle; }; #endif // OPENCVPLAYERMANAGER_
入坑
入坑一:调整播放位置时,宕机
原因:
直接主线程操作设置当前帧的位置,同时子线程也却在读取,OpenCV内部没有错异步处理。
解决方法:
先调用设置位置,然后槽调用,将设置位置放置到子线程当中去。