實現了在MFC中顯示圖片,再要顯示一個視訊就是輕而易舉的事了,本篇介紹使用Opencv製作一個簡易的播放器,實現開啟檔案、暫停、繼續播放、再次播放和總當前幀數顯示功能。

首先還是先看一下介面效果:

基於OpenCV從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!

 

嗯,是不是很有MFC的感覺,簡潔大方、樸素典雅又實用~~,如果用一個字來概括的話那就是——醜!(按下不表~~)

1. 定義變數

控制元件之間有一些標誌位等變數需要傳遞,這裡用了一個偷懶的方法,在檔案內直接定義一個類Vardefine,用來儲存和傳遞變數:

基於OpenCV從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!

 

2.開啟視訊檔案

加入一個按鈕控制元件BUTTON1,雙擊控制元件新增事件處理程式:

基於OpenCV從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!

 

裡邊playVideo(CString &str)是播放視訊的實現模組。

3. 暫停&繼續播放&再次播放

同樣加入第二個按鈕控制元件BUTTON2,雙擊新增事件處理程式,涉及每次點選控制元件都會改變控制元件的顯示文字,你一定玩過這個小把戲

進群:548377875  即可獲取大量的學習資料以及從零開始到專案的實戰的PDF數十本呢!

基於OpenCV從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!

 

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從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!

 

點選暫停之後介面:

基於OpenCV從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!

 

點選繼續播放後介面:

基於OpenCV從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!

 

播放完成:

基於OpenCV從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!

 

再次播放:

基於OpenCV從零開始的視訊播放器!聘美騰訊,優酷等軟體的神器!