📄 mediaplayer.cpp
字号:
// MediaPlayer.cpp: implementation of the CMediaPlayer class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MediaPlayer.h"
#include "Commdlg.h"
#include <math.h>
BEGIN_MESSAGE_MAP(CMediaPlayer, CNDialog)
ON_BN_CLICKED(IDC_OPEN,OnOpen)
ON_BN_CLICKED(IDC_PLAY,OnPlay)
ON_BN_CLICKED(IDC_PREVIOUS,OnPrevious)
ON_BN_CLICKED(IDC_NEXT,OnNext)
ON_BN_CLICKED(IDC_STOP,OnStop)
ON_BN_CLICKED(IDC_MUTE,OnMute)
END_MESSAGE_MAP()
#define MAKEVOLUMETOPOS(l) ((l+10000)/100)
#define MAKEPOSTOVOLUME(p) ((p-100)*100)
BOOL CMediaPlayer::m_bMute = FALSE;
long CMediaPlayer::m_lVolume = 0; // its value range from -10000 to 0;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMediaPlayer::CMediaPlayer(CNWnd* pParent, UINT uID)
:CNDialog(pParent, uID)
{
m_pMultimedia = NULL;
m_hRgnMP = NULL;
m_bFrozen = FALSE;
}
CMediaPlayer::~CMediaPlayer()
{
DestroyMultimedia();
}
BOOL CMediaPlayer::OnInitDialog()
{
CNDialog::OnInitDialog();
// subclassing dialog item
m_btnOpen.SubclassDlgItem(IDC_OPEN,this);
m_btnOpen.SetIcon(IDI_MP_OPEN);
m_btnPlay.SubclassDlgItem(IDC_PLAY,this);
m_btnPlay.SetIcon(IDI_MP_PLAY);
m_btnStop.SubclassDlgItem(IDC_STOP,this);
m_btnStop.SetIcon(IDI_MP_STOP);
m_btnPrevious.SubclassDlgItem(IDC_PREVIOUS,this);
m_btnPrevious.SetIcon(IDI_MP_PREVIOUS);
m_btnNext.SubclassDlgItem(IDC_NEXT,this);
m_btnNext.SetIcon(IDI_MP_NEXT);
m_btnMute.SubclassDlgItem(IDC_MUTE,this);
m_btnMute.SetIcon(m_bMute ? IDI_MP_MUTE_OFF : IDI_MP_MUTE_ON);
m_sliderProgress.SubclassDlgItem(IDC_SLIDER, this);
m_sliderProgress.SetSkin(IDB_BMP_TRACK_BACK2, IDB_BMP_TRACK_BACK, IDB_BMP_TRACK_TICK);
m_sliderProgress.SetRange(0, 100);
m_sliderProgress.SetCallback(cbProgressSlider, (void*)this);
m_sliderVolume.SubclassDlgItem(IDC_SLIDER_VOLUME, this);
m_sliderVolume.SetSkin(IDB_BMP_TRACK_BACK2, IDB_BMP_TRACK_BACK, IDB_BMP_TRACK_TICK);
m_sliderVolume.SetRange(0, 100);
m_sliderVolume.SetPos(MAKEVOLUMETOPOS(m_lVolume));
m_sliderVolume.SetCallback(cbVolumSlider, (void*)this);
// timer for auto fullscreen. if user didn't op any mouse or key in a
// specified time, play it in fullscreen automatically.
SetTimer(ID_TIMER_FULLSCREEN, FULLSCREEN_TIME_ELAPSED, NULL);
// set a timer to refresh ProgressSlider every 1 seconds when playing video.
SetTimer(ID_TIMER_PROGRESS, 300, NULL);
return TRUE;
}
BOOL CMediaPlayer::OnEraseBkgnd(HDC hdc)
{
RECT rc;
SetRect(&rc, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
FillSolidRect(hdc, &rc, RGB(0,0,0));
SetRect(&rc, 0,SCREEN_HEIGHT - MP_BAR_HEIGHT,
SCREEN_WIDTH, SCREEN_HEIGHT);
FillSolidRect(hdc, &rc, MP_BAR_COLOR);
return TRUE;
}
HBRUSH CMediaPlayer::OnCtlColor(HDC hdc,HWND hwnd, UINT nCtlColor)
{
// if neccessary, call base class to set DC attributes
//CNDialog::OnCtlColor(hdc,hwnd, nCtlColor);
static BOOL s_bInit = FALSE;
static HBRUSH s_hbrMenuBar;
if( !s_bInit )
{
s_hbrMenuBar = CreateSolidBrush(MP_BAR_COLOR);
s_bInit = TRUE;
}
// all buttons and route info static control.
if(nCtlColor == WM_CTLCOLORBTN )
{
return s_hbrMenuBar;
}
return CNDialog::OnCtlColor(hdc,hwnd, nCtlColor);
}
/////////////////////////////////////////////////////////////////////////////
// 创建Filter Graph
void CMediaPlayer::CreateMultimedia(void)
{
DestroyMultimedia();
m_pMultimedia = new CMultimedia();
if( m_pMultimedia->Create() )
{
// Render the source clip
m_pMultimedia->RenderFile(m_strFileName);
// Set video window and notification window
m_pMultimedia->SetDisplayWindow(this->GetSafeHwnd());
RECT rcWindow;
GetClientRect(&rcWindow);
m_pMultimedia->ResizeVideoWindow(0,0,
rcWindow.right - rcWindow.left,
rcWindow.bottom - rcWindow.top-MP_BAR_HEIGHT);
m_pMultimedia->SetNotifyWindow(this->GetSafeHwnd());
// set volume.
m_pMultimedia->SetAudioVolume(m_bMute ? -10000:m_lVolume);
// Show the first frame
m_pMultimedia->Run();
m_btnPlay.SetIcon(IDI_MP_PAUSE);
}
else
{
TRACE(_T("Multimedia Creating fail.\n"));
}
}
/////////////////////////////////////////////////////////////////////////////
// 析构Filter Graph
void CMediaPlayer::DestroyMultimedia(void)
{
if(m_pMultimedia)
{
// Stop the filter graph first
m_pMultimedia->Stop();
m_pMultimedia->SetNotifyWindow(NULL);
delete m_pMultimedia;
m_pMultimedia = NULL;
}
// delete it since multimedia play stoped.
if(m_hRgnMP != NULL)
{
DeleteObject(m_hRgnMP);
m_hRgnMP = NULL;
}
}
void CMediaPlayer::OnOpen()
{
TCHAR strFilter[255] = _T("媒体文件(所有类型)\0*.avi;*.mpg;*.mpeg;*.mp3;*.wma;*.wav;*.mid;*.rmi;*.wmv;*.asf\0");
//MIDI 文件(midi)(*.mid;*.rmi;*.midi)\0*.mid;*.rmi;*.midi\0");
/*strFilter += L"Windows Media 文件(asf)(*.asf;*.wm;*.wmv)\0*.asf;*.wm;*.wmv\0";
strFilter += L"视频文件(avi)(*.avi;*.wmv)\0*.avi;*.wmv\0";
strFilter += L"音频文件(wav)(*.wav)\0*.wav\0";
strFilter += L"电影文件(mpeg)(*.mpg;*.mpeg)\0*.mpg;*.mpeg\0";
strFilter += L"mp3 文件 (*.mp3)\0*.mp3\0";
strFilter += L"wma 文件 (*.wma)\0*.wma\0";
strFilter += L"All Files (*.*)\0*.*\0";
*/
TCHAR szFileFullName[MAX_PATH+1];
TCHAR szTitle[] = _T("Open file");
OPENFILENAME ofn; // common dialog box structure
memset(szFileFullName, 0, sizeof(szFileFullName));
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.hwndOwner = NGetMainWnd()->GetSafeHwnd();
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.lpstrFile = szFileFullName;
ofn.nMaxFile = sizeof(szFileFullName)/sizeof(TCHAR);
ofn.lpstrFilter =
L"媒体文件(所有类型)\0*.avi;*.mpg;*.mpeg;*.mp3;*.wma;*.wav;*.mid;*.rmi;*.wmv;*.asf\0"
L"MIDI 文件(midi)(*.mid;*.rmi;*.midi)\0*.mid;*.rmi;*.midi\0"
L"Windows Media 文件(asf)(*.asf;*.wm;*.wmv)\0*.asf;*.wm;*.wmv\0"
L"视频文件(avi)(*.avi;*.wmv)\0*.avi;*.wmv\0"
L"音频文件(wav)(*.wav)\0*.wav\0"
L"电影文件(mpeg)(*.mpg;*.mpeg)\0*.mpg;*.mpeg\0"
L"mp3 文件 (*.mp3)\0*.mp3\0"
L"wma 文件 (*.wma)\0*.wma\0"
L"All Files (*.*)\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = 0;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
ofn.lpstrTitle = szTitle;
m_bFrozen = TRUE;
// Display the Open dialog box.
if ( GetOpenFileName(&ofn) )
{
m_bFrozen = FALSE;
// help to refresh window quickly.
InvalidateRect(NULL);
UpdateWindow();
m_strFileName = szFileFullName;
TRACE(_T("%s"),m_strFileName.GetString());
// Rebuild the file playback filter graph
CreateMultimedia();
}
m_bFrozen = FALSE;
}
void CMediaPlayer::OnPlay()
{
if(m_pMultimedia)
{
if( m_pMultimedia->IsRunning() )
{
m_pMultimedia->Pause();
m_btnPlay.SetIcon(IDI_MP_PLAY);
}
else
{
m_pMultimedia->Run();
m_btnPlay.SetIcon(IDI_MP_PAUSE);
}
m_btnPlay.InvalidateRect(NULL);
}
}
void CMediaPlayer::OnPrevious()
{
if(m_pMultimedia)
{
double dCurrPos = 0;
double dDuration = 0;
m_pMultimedia->GetDuration(&dDuration);
m_pMultimedia->Pause();
m_pMultimedia->GetCurrentPosition(&dCurrPos);
dCurrPos -= dDuration/20; // 1/20
dCurrPos = (dCurrPos < 0) ? 0 : dCurrPos;
m_pMultimedia->SetCurrentPosition(dCurrPos);
m_pMultimedia->Run();
/*if(m_nProgressTimer == 0)
{
m_nProgressTimer = SetTimer(PROGRESS_TIMER, 100, NULL);
}*/
}
}
// forward
void CMediaPlayer::OnNext()
{
if(m_pMultimedia)
{
double dCurrPos = 0;
double dDuration = 0;
m_pMultimedia->GetDuration(&dDuration);
m_pMultimedia->Pause();
m_pMultimedia->GetCurrentPosition(&dCurrPos);
dCurrPos += dDuration/20; // 1/20
dCurrPos = (dCurrPos > dDuration) ? dDuration : dCurrPos;
m_pMultimedia->SetCurrentPosition(dCurrPos);
m_pMultimedia->Run();
/*if(m_nProgressTimer == 0)
{
m_nProgressTimer = SetTimer(PROGRESS_TIMER, 100, NULL);
}*/
}
}
void CMediaPlayer::OnStop()
{
if(m_pMultimedia)
{
m_pMultimedia->SetCurrentPosition(0);
m_pMultimedia->Stop();
m_btnPlay.SetIcon(IDI_MP_PLAY);
m_btnPlay.InvalidateRect(NULL);
/*if(m_nProgressTimer)
{
KillTimer(m_nProgressTimer);
m_nProgressTimer = 0;
}*/
}
}
void CMediaPlayer::OnMute()
{
m_bMute = !m_bMute;
if(m_pMultimedia)
{
m_pMultimedia->SetAudioVolume(m_bMute ? -10000 : m_lVolume);
}
m_btnMute.SetIcon(m_bMute ? IDI_MP_MUTE_OFF : IDI_MP_MUTE_ON);
m_btnMute.InvalidateRect(NULL);
}
void CMediaPlayer::OnIdle()
{
if( m_bFrozen || (m_pMultimedia && m_pMultimedia->GetFullScreen() ))
return;
// if we have opened a multimedia, create the clip region for video window.
if( m_hRgnMP==NULL && m_pMultimedia )
{
long lWidth = 0;
long lHeight = 0;
m_pMultimedia->GetVideoSize(lWidth, lHeight);
// set clip region for the dshow. avoid GDI write to the region for playing.
if( lWidth >0 && lHeight >0 ) // it's a video file.
{
RECT rect;
GetClientRect(&rect);
m_hRgnMP = CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
HRGN hrgn = CreateRectRgn(rect.left,rect.top,
rect.right,rect.bottom - MP_BAR_HEIGHT);
CombineRgn(m_hRgnMP,m_hRgnMP,hrgn,RGN_DIFF);
DeleteObject(hrgn);
}
}
#ifdef PC_VERSION
HDC hdc = GetWindowDC();
#else // for CE
HDC hdc = GetDCEx(m_hWnd, NULL, DCX_WINDOW | DCX_CACHE );
#endif
HRGN hOldRgn = (HRGN)SelectObject(hdc, m_hRgnMP);
BitBlt(hdc,0,0,SCREEN_WIDTH, SCREEN_HEIGHT, g_hdcUI,0,0,SRCCOPY);
SelectObject(hdc, hOldRgn);
ReleaseDC(hdc);
}
void CMediaPlayer::OnLButtonDblClk(UINT nFlags, POINT point)
{
if(m_pMultimedia)
{
m_pMultimedia->SetFullScreen(! m_pMultimedia->GetFullScreen());
}
}
void CMediaPlayer::OnTimer(UINT nIDEvent)
{
if( nIDEvent == ID_TIMER_FULLSCREEN
&& m_pMultimedia
&& m_pMultimedia->IsRunning()
&& !m_pMultimedia->GetFullScreen()
&& GetForegroundWindow() == GetSafeHwnd())
{
m_pMultimedia->SetFullScreen(TRUE);
} else if ( nIDEvent == ID_TIMER_PROGRESS && m_pMultimedia )
{
m_sliderProgress.GetPos();
int min, max;
m_sliderProgress.GetRange(&min, &max);
double outDuration, curDuration;
if( !m_pMultimedia->GetDuration(&outDuration) )
return;
if( !m_pMultimedia->GetCurrentPosition(&curDuration) )
return;
int pos = (int) (curDuration * (max - min) / outDuration);
m_sliderProgress.SetPos(pos);
// check if it finishes playback, if so, back to very first frame.
if( fabs(curDuration-outDuration) < 0.0001 )
{
m_btnStop.PostMessage(BM_CLICK,0,0);
PostMessage(WM_TIMER,(WPARAM)ID_TIMER_PROGRESS, 0);
}
}
}
LRESULT CMediaPlayer::WndProc(HWND hDlg,
UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if( uMsg == WM_LBUTTONDOWN
|| uMsg == WM_LBUTTONUP
|| uMsg == WM_RBUTTONDOWN
|| uMsg == WM_RBUTTONUP
|| uMsg == WM_MOUSEMOVE )
SetTimer(ID_TIMER_FULLSCREEN, FULLSCREEN_TIME_ELAPSED, NULL);
return CNDialog::WndProc(hDlg, uMsg, wParam, lParam);
}
void CMediaPlayer::cbVolumSlider(void *pObject)
{
CMediaPlayer* pMP = static_cast<CMediaPlayer*>(pObject);
pMP->OnVolumeSlider();
}
void CMediaPlayer::OnVolumeSlider()
{
int pos = m_sliderVolume.GetPos();
int min, max;
m_sliderVolume.GetRange(&min, &max);
// let it range from -3333 ~ 0
m_lVolume = MAKEPOSTOVOLUME( (pos-min)*100/(max-min) ) / 3;
if( m_pMultimedia )
m_pMultimedia->SetAudioVolume(m_bMute ? -10000:m_lVolume);
}
void CMediaPlayer::cbProgressSlider(void *pObject)
{
CMediaPlayer* pMP = static_cast<CMediaPlayer*>(pObject);
pMP->OnProgressSlider();
}
void CMediaPlayer::OnProgressSlider()
{
int pos = m_sliderProgress.GetPos();
int min, max;
m_sliderProgress.GetRange(&min, &max);
if ( m_pMultimedia )
{
double outDuration;
if( !m_pMultimedia->GetDuration(&outDuration) )
return;
outDuration = (pos-min+1.5)*outDuration / (max - min);
m_pMultimedia->SetCurrentPosition(outDuration);
}
else
{
m_sliderProgress.SetPos(min);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -