实现了在MFC中显示图片,再要显示一个视频就是轻而易举的事了,本篇介绍使用Opencv制作一个简易的播放器,实现打开文件、暂停、继续播放、再次播放和总\当前帧数显示功能。

首先还是先看一下界面效果:

嗯,是不是很有MFC的感觉,简洁大方、朴素典雅又实用~~,如果用一个字来概括的话那就是——丑!(按下不表~~

1. 定义变量

控件之间有一些标志位等变量需要传递,这里用了一个偷懒的方法,在文件内直接定义一个类Vardefine,用来保存和传递变量:

class Vardefine
{
public:
static bool pause; //暂停标志位
static bool playOn; //继续播放标志位
static bool playAgain; //再次播放标志位
static double frameNum; //当前播放帧数
static CString str; //保存视频文件路径
}; //变量初始化
bool Vardefine::pause=false;
bool Vardefine::playOn=false;
bool Vardefine::playAgain=false;
double Vardefine::frameNum=1.0;
CString Vardefine::str="";

2.打开视频文件

加入一个按钮控件BUTTON1,双击控件添加事件处理程序:

void COpencvVideoDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,
NULL, this); //选择文件对话框
if(dlg.DoModal() == IDOK)
{
Vardefine::str= dlg.GetPathName(); //获取视频文件路径
}
playVideo(Vardefine::str); //自定义函数playVideo,播放视频
}

里边playVideo(CString &str)是播放视频的实现模块。

3. 暂停&继续播放&再次播放

同样加入第二个按钮控件BUTTON2,双击添加事件处理程序,涉及每次点击控件都会改变控件的显示文本,你一定玩过这个小把戏。

void COpencvVideoDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
CString button2Name;
GetDlgItemText(IDC_BUTTON2,button2Name);
if(button2Name=="暂停")
{
//设置暂停、继续播放、再次播放(再次播放本程序暂没用到)标志位
Vardefine::pause=true;
Vardefine::playAgain=false;
Vardefine::playOn=false;
//如果是暂停,置位继续播放
SetDlgItemText(IDC_BUTTON2,"继续播放");
}
if(button2Name=="继续播放")
{
//设置暂停、继续播放、再次播放(再次播放本程序暂没用到)标志位
Vardefine::pause=false;
Vardefine::playOn=true;
Vardefine::playAgain=false;
//如果是继续播放,置为暂停
SetDlgItemText(IDC_BUTTON2,"暂停");
}
if(button2Name=="再次播放")
{
//设置暂停、继续播放、再次播放(再次播放本程序暂没用到)标志位
Vardefine::pause=false;
Vardefine::playOn=false;
Vardefine::playAgain=true;
//再次播放后置为初始的暂停
SetDlgItemText(IDC_BUTTON2,"暂停");
//置当前播放帧数为1
Vardefine::frameNum=1;
//调用视频播放方法
playVideo(Vardefine::str);
}
}

4.视频播放模块

这里首先要在OpencvVideoDlg.h(你命名的工程可能不叫OpencvVideo,替换为你的命名)头文件里声明方法“playVideo(CString &str)”,为了显示方便,把整个头文件贴出来如下:

// OpencvVideoDlg.h : 头文件
// #pragma once
#include "afxwin.h" // COpencvVideoDlg 对话框
class COpencvVideoDlg : public CDialogEx
{
// 构造
public:
COpencvVideoDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据
enum { IDD = IDD_OPENCVVIDEO_DIALOG }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现
protected:
HICON m_hIcon; // 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
<span style="color:#ff0000;"><strong>afx_msg void playVideo(CString &str);</strong></span>
// CButton IDC_BUTTON2;
afx_msg void OnBnClickedCancel();
afx_msg void OnBnClickedOk();
};

加粗标红的那一行就是添加的视频显示函数声明。

playVideo函数具体实现代码:

void COpencvVideoDlg::playVideo(CString &str)
{
//CString to string 使用这个方法记得字符集选用“使用多字节字符”,不然会报错
string videopath=str.GetBuffer(0);
VideoCapture videocap(videopath); //打开视频文件
if(!videocap.isOpened()) //检查是否打开
{
MessageBox("视频文件打开失败,请检查!");
return;
}
double totalFrameNumber = videocap.get(CV_CAP_PROP_FRAME_COUNT); //获取视频帧率
CString ctotalFrameNumber;
ctotalFrameNumber.Format("%f",totalFrameNumber); //double->CString
SetDlgItemText(IDC_EDIT1,ctotalFrameNumber); //在edit1控件里显示总帧数
double videorate=videocap.get(CV_CAP_PROP_FPS); //获取帧率
double videodelay=1000/videorate; //计算视频每一帧间隔
Mat image;
Mat videoimage;
//以下操作获取图形控件尺寸并以此改变图片尺寸
CRect rect;
GetDlgItem(IDC_STATIC_Video)->GetClientRect(&rect);
Rect dst(rect.left,rect.top,rect.right,rect.bottom);
while(true)
{
videocap.read(image); //视频一帧一帧读入Mat
resize(image,videoimage,cv::Size(rect.Width(),rect.Height())); //调整以适应窗口
imshow("view",videoimage);
while(Vardefine::pause) //判断是否要求暂停
{
if(Vardefine::playOn) //若要求继续播放,则跳出
{
break;
}
waitKey(50);
}
waitKey(videodelay); //每帧之间时间间隔
Vardefine::frameNum+=1;
CString cFrameNum;
cFrameNum.Format("%f",Vardefine::frameNum-1);
SetDlgItemText(IDC_EDIT2,cFrameNum); //在edit2内显示当前帧数
if(Vardefine::frameNum>totalFrameNumber) //若播放视频完成,则跳出
{
break;
}
}
SetDlgItemText(IDC_BUTTON2,"再次播放"); //置按钮控件为“再次播放”
videocap.release(); //释放视频
}

视频总帧数以及当前帧显示已经包含在播放方法内实现了,不再赘述。

最后显示一下播放效果:

通过对话框选择视频文件后界面:

点击暂停之后界面:



点击继续播放后界面:



播放完成:

再次播放:

Opencv实现简易播放器的更多相关文章

  1. <Win32_17>集音频和视频播放功能于一身的简易播放器

    前段时间,在学习中科院杨老师的教学视频时,他说了一句话: "我很反对百八十行的教学程序,要来就来一个完整的程序" 对此,我很是赞同.所谓真刀真枪的做了,你才会发现其中的奥秘——然而 ...

  2. FFmpeg简易播放器的实现-视频播放

    本文为作者原创:https://www.cnblogs.com/leisure_chn/p/10047035.html,转载请注明出处 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  3. FFmpeg简易播放器的实现-音视频同步

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10284653.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  4. FFmpeg简易播放器的实现-音视频播放

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10235926.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  5. FFmpeg简易播放器的实现-音频播放

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10068490.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  6. FFmpeg简易播放器的实现-最简版

    本文为作者原创:https://www.cnblogs.com/leisure_chn/p/10040202.html,转载请注明出处 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...

  7. winform下的简易播放器

    编写这个播放器,遇到很多问题,比如目前只实现了wav音频文件的播放,而对于这个图中中间所标注的按钮 不能实现让其暂停的功能,同时当点击的时候,让其文本变为"▷",对于这部分功能不知 ...

  8. C#简易播放器(基于开源VLC)

    可见光通信技术(Visible Light Communication,VLC)是指利用可见光波段的光作为信息载体,不使用光纤等有线信道的传输介质,而在空气中直接传输光信号的通信方式.LED可见光通信 ...

  9. Winform Windows Media Player 简易播放器 分类: WinForm 2014-07-31 20:12 589人阅读 评论(0) 收藏

    新手上路,高手勿进! 窗体设计: 实现效果: 实现代码: using System; using System.Collections.Generic; using System.ComponentM ...

随机推荐

  1. hdu - 2667 Proving Equivalences(强连通)

    http://acm.hdu.edu.cn/showproblem.php?pid=2767 求至少添加多少条边才能变成强连通分量.统计入度为0的点和出度为0的点,取最大值即可. #include & ...

  2. 设计模式之装饰(Decorator)模式

    设计模式之装饰(Decorator)模式 (一)什么是装饰(Decorator)模式 装饰模式,又称为包装模式,它以对客户端透明的方式扩张对象的功能,是继承关系的替代方案之一. 装饰模式可以在不使用创 ...

  3. 3.JAVA语言基础部分—Class类与反射

    什么是Java反射机制? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的以及动态调用对象的方法的功能称为 ...

  4. Spring注入内部的Beans

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/injecting-inner-beans.html: 如你所知,Java内部类在其他类的范围内定义 ...

  5. ORACLE 内部原理

    http://www.ohsdba.cn/index.php?m=Article&a=index&id=46 内部原理 2016-05-04• 如何使用BBED 2016-04-16• ...

  6. NSURLConnection和NSMutableURLRequest 实现同步、异步请求

    我是走向ios的一个小书童,我有很多不懂的,新鲜的知识去学习,去掌握! 我首先要吐槽一下: 那些不负责的博友!你分享知识本来是好事!可是你直接Control+V就是你的不对了! 尼玛,直接Contro ...

  7. android项目大全,总有你所需的

    注:打开请贴网址.有些直接通过链接打开的不对.  1.相对布局实例 http://kukuqiu.iteye.com/blog/1018396 2.Log图文具体解释(Log.v,Log.d,Log. ...

  8. 向C#的选项卡中添加自定义窗体

    一.自定义窗体的搭建 这个比较简单,添加一个WinForm窗体就行了,设置一个名字EditPanel,然后在窗体上画需要的控件. 二.将自定义窗体添加到选项卡 // 新建窗体加入到选项卡中 EditP ...

  9. hadoop优质链接

    http://wiki.apache.org/hadoop/FAQ

  10. MapReduce将HDFS文本数据导入HBase中

    HBase本身提供了很多种数据导入的方式,通常有两种常用方式: 使用HBase提供的TableOutputFormat,原理是通过一个Mapreduce作业将数据导入HBase 另一种方式就是使用HB ...