📄 masterobject.cpp
字号:
HRESULT hr;
//g_szFileName[MAX_PATH]={0};
LPTSTR strDLLPath1 = new TCHAR[_MAX_PATH];
::GetModuleFileName((HINSTANCE)&__ImageBase, strDLLPath1, _MAX_PATH);
long lLength = _tcslen(strDLLPath1) - 1;
while (lLength >= 0 && strDLLPath1[lLength] != _T('\\'))
{
strDLLPath1[lLength] = _T('\0');
lLength--;
}
_tcscat( strDLLPath1, _T("media\\chimp.mpg") );
//CString strApp = (CString)strDLLPath1;
hr = StringCchCopy(g_szFileName, NUMELMS(g_szFileName), strDLLPath1);
delete [] strDLLPath1;
// Reset status variables
g_psCurrent = State_Stopped;;
//g_lVolume = VOLUME_FULL;
// Start playing the media file
//hr = PlayMovieInWindow(g_szFileName);
// If we couldn't play the clip, clean up
//if (FAILED(hr))
// CloseClip();
// Remember current play state to restart playback
int nCurrentState = g_psCurrent;
// First release any existing interfaces
ResetDirectShow();
// Clear filter/pin/event information listboxes
//m_ListFilters.ResetContent();
//m_ListPinsInput.ResetContent();
//m_ListPinsOutput.ResetContent();
//m_ListEvents.ResetContent();
// Load the selected media file
hr = PrepareMedia(g_szFileName, hTab, m_hWnd);
if (FAILED(hr))
{
// Error - disable play button and give feedback
//Say(TEXT("File failed to render!"));
//m_ButtonPlay.EnableWindow(FALSE);
FreeDirectShow();
MessageBeep(0);
return;
}
else
{
//m_ButtonPlay.EnableWindow(TRUE);
}
// Display useful information about this file
//DisplayFileInfo(szFilename);
//DisplayImageInfo();
//DisplayFileDuration();
// Set up the seeking trackbar and read capabilities
//ConfigureSeekbar();
// Enumerate and display filters in graph
//hr = EnumFilters();
// Select the first filter in the list to display pin info
//m_ListFilters.SetCurSel(0);
//OnSelchangeListFilters();
// See if the renderer supports frame stepping on this file.
// Enable/disable frame stepping button accordingly
//m_ButtonFrameStep.EnableWindow(CanStep());
// If the user has asked to mute audio then we
// need to mute this new clip before continuing.
if (g_bGlobalMute)
MuteAudio();
OnPlay();
}
void CMasterObject::OnSelectFile(HWND hTab, HWND m_hWnd)
{
HRESULT hr;
//SetForegroundWindow(ghApp);
if (!GetClipFileName(szFilename))
{
_tcscpy( szFilename, szDefaultFile );
DWORD dwDlgErr = CommDlgExtendedError();
if (dwDlgErr)
{
//Msg(TEXT("GetClipFileName Failed! Error=0x%x\r\n"), GetLastError());
}
return;
}
hr = StringCchCopy(g_szFileName, NUMELMS(g_szFileName), szFilename);
// Reset status variables
g_psCurrent = State_Stopped;;
//g_lVolume = VOLUME_FULL;
// Start playing the media file
//hr = PlayMovieInWindow(g_szFileName);
// If we couldn't play the clip, clean up
//if (FAILED(hr))
// CloseClip();
// Remember current play state to restart playback
int nCurrentState = g_psCurrent;
// First release any existing interfaces
ResetDirectShow();
// Clear filter/pin/event information listboxes
//m_ListFilters.ResetContent();
//m_ListPinsInput.ResetContent();
//m_ListPinsOutput.ResetContent();
//m_ListEvents.ResetContent();
// Load the selected media file
hr = PrepareMedia(szFilename, hTab, m_hWnd);
if (FAILED(hr))
{
// Error - disable play button and give feedback
//Say(TEXT("File failed to render!"));
//m_ButtonPlay.EnableWindow(FALSE);
FreeDirectShow();
MessageBeep(0);
return;
}
else
{
//m_ButtonPlay.EnableWindow(TRUE);
}
// Display useful information about this file
//DisplayFileInfo(szFilename);
//DisplayImageInfo();
//DisplayFileDuration();
// Set up the seeking trackbar and read capabilities
//ConfigureSeekbar();
// Enumerate and display filters in graph
//hr = EnumFilters();
// Select the first filter in the list to display pin info
//m_ListFilters.SetCurSel(0);
//OnSelchangeListFilters();
// See if the renderer supports frame stepping on this file.
// Enable/disable frame stepping button accordingly
//m_ButtonFrameStep.EnableWindow(CanStep());
// If the user has asked to mute audio then we
// need to mute this new clip before continuing.
if (g_bGlobalMute)
MuteAudio();
// If we were running when the user changed selection,
// start running the newly selected clip
if (nCurrentState == State_Running)
{
OnPlay();
}
else
{
// Cue the first video frame
OnStop();
}
}
BOOL CMasterObject::IsWindowsMediaFile(LPTSTR lpszFile)
{
TCHAR szFilename[MAX_PATH];
// Copy the file name to a local string and convert to lowercase
(void)StringCchCopy(szFilename, NUMELMS(szFilename), lpszFile);
szFilename[MAX_PATH-1] = 0;
_tcslwr(szFilename);
if (_tcsstr(szFilename, TEXT(".asf")) ||
_tcsstr(szFilename, TEXT(".wma")) ||
_tcsstr(szFilename, TEXT(".wmv")))
return TRUE;
else
return FALSE;
}
HRESULT CMasterObject::PrepareMedia(LPTSTR lpszMovie, HWND hTab, HWND m_hWnd)
{
USES_CONVERSION;
HRESULT hr = S_OK;
//Say(TEXT("Loading..."));
// Is this a Windows Media file (ASF, WMA, WMV)? If so, use the new
// ASF Reader filter, which is faster and much better at seeking than
// the default ASF Reader filter used by default with RenderFile.
if (IsWindowsMediaFile(lpszMovie))
{
#ifndef TARGET_NO_WM
hr = RenderWMFile(T2W(lpszMovie));
if (FAILED(hr)) {
RetailOutput(TEXT("*** Failed(%08lx) to Render WM File(%s)!\r\n"),
hr, lpszMovie);
return hr;
}
#else
// Native Windows Media is not supported
RetailOutput(TEXT("*** WM files are not supported on native 64-bit targets!\r\n"));
return E_NOINTERFACE;
#endif
}
else
{
// Allow DirectShow to create the FilterGraph for this media file
hr = pGB->RenderFile(T2W(lpszMovie), NULL);
if (FAILED(hr)) {
RetailOutput(TEXT("*** Failed(%08lx) in RenderFile(%s)!\r\n"),
hr, lpszMovie);
return hr;
}
}
// Set the message drain of the video window to point to our main
// application window. If this is an audio-only or MIDI file,
// then put_MessageDrain will fail.
hr = pVW->put_MessageDrain((OAHWND) m_hWnd);
if (FAILED(hr))
{
g_bAudioOnly = TRUE;
}
// Have the graph signal event via window callbacks
hr = pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
// Configure the video window
if (!g_bAudioOnly)
{
// We'll manually set the video to be visible
hr = pVW->put_Visible(OAFALSE);
hr = pVW->put_WindowStyle(WS_CHILD);
//hr = pVW->put_Owner((OAHWND) m_Screen.GetSafeHwnd());
hr = pVW->put_Owner((OAHWND) hTab);
// Place video window within the bounding rectangle
CenterVideo(hTab);
// Make the video window visible within the screen window.
// If this is an audio-only file, then there won't be a video interface.
hr = pVW->put_Visible(OATRUE);
hr = pVW->SetWindowForeground(-1);
}
//Say(TEXT("Ready"));
return hr;
}
HRESULT CMasterObject::RenderWMFile(LPCWSTR wFile)
{
HRESULT hr=S_OK;
IFileSourceFilter *pFS=NULL;
IBaseFilter *pReader=NULL;
// Load the improved ASF reader filter by CLSID
hr = CreateFilter(CLSID_WMAsfReader, &pReader);
if(FAILED(hr))
{
RetailOutput(TEXT("Failed to create WMAsfWriter filter! hr=0x%x\n"), hr);
return hr;
}
// Add the ASF reader filter to the graph. For ASF/WMV/WMA content,
// this filter is NOT the default and must be added explicitly.
hr = pGB->AddFilter(pReader, L"ASF Reader");
if(FAILED(hr))
{
RetailOutput(TEXT("Failed to add ASF reader filter to graph! hr=0x%x\n"), hr);
pReader->Release();
return hr;
}
//
// Windows Media 9 Series (code named 'Corona') no longer requires
// a stub library. If using WMF9, we don't need to provide a CKeyProvider
// implementation, and we don't need to link with the WMStub.lib library.
//
#if !defined(TARGET_WMF9) && !defined(TARGET_NO_WM)
// Create the key provider that will be used to unlock the WM SDK
//JIF(AddKeyProvider(pGB));
#endif
// Set its source filename
JIF(pReader->QueryInterface(IID_IFileSourceFilter, (void **) &pFS));
JIF(pFS->Load(wFile, NULL));
pFS->Release();
// Render the output pins of the ASF reader to build the
// remainder of the graph automatically
JIF(RenderOutputPins(pGB, pReader));
CLEANUP:
// If there was a rendering error, make sure that the reader is released
//
// Otherwise, wince the graph is built and the filters are added to
// the graph, the WM ASF reader interface can be released.
SAFE_RELEASE(pReader);
return hr;
}
void CMasterObject::ResetDirectShow(void)
{
// Destroy the current filter graph its filters.
FreeDirectShow();
// Reinitialize graph builder and query for interfaces
InitDirectShow();
}
void CMasterObject::OnPlay()
{
RunMedia();
//StartSeekTimer();
//Say(TEXT("Running"));
}
void CMasterObject::OnStop()
{
HRESULT hr;
if (!pMC || !pMS)
return;
// Stop playback immediately with IMediaControl::Stop().
//StopSeekTimer();
StopMedia();
// Wait for the stop to propagate to all filters
OAFilterState fs;
hr = pMC->GetState(500, &fs);
if (FAILED(hr))
{
//RetailOutput(TEXT("Failed to read graph state! hr=0x%x\r\n"), hr);
}
// Reset to beginning of media clip
LONGLONG pos=0;
hr = pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning ,
NULL, AM_SEEKING_NoPositioning);
if (FAILED(hr))
{
//RetailOutput(TEXT("Failed to seek to beginning of media! hr=0x%x\r\n"), hr);
}
// Display the first frame of the media clip, if it contains video.
// StopWhenReady() pauses all filters internally (which allows the video
// renderer to queue and display the first video frame), after which
// it sets the filters to the stopped state. This enables easy preview
// of the video's poster frame.
hr = pMC->StopWhenReady();
if (FAILED(hr))
{
//RetailOutput(TEXT("Failed in StopWhenReady! hr=0x%x\r\n"), hr);
}
//Say(TEXT("Stopped"));
// Reset slider bar and position label back to zero
//ReadMediaPosition();
}
void CMasterObject::CenterVideo(HWND hTab)
{
LONG width, height;
HRESULT hr;
if ((g_bAudioOnly) || (!pVW))
return;
// Read coordinates of video container window
RECT rc;
//m_Screen.GetClientRect(&rc);
::GetClientRect(hTab, &rc);
width = rc.right - rc.left;
height = rc.bottom - rc.top;
// Ignore the video's original size and stretch to fit bounding rectangle
hr = pVW->SetWindowPosition(rc.left, rc.top, width, height);
if (FAILED(hr))
{
RetailOutput(TEXT("Failed to set window position! hr=0x%x\r\n"), hr);
return;
}
}
HRESULT CMasterObject::CreateFilter(REFCLSID clsid, IBaseFilter **ppFilter)
{
HRESULT hr;
hr = CoCreateInstance(clsid,
NULL,
CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
(void **) ppFilter);
if(FAILED(hr))
{
RetailOutput(TEXT("CreateFilter: Failed to create filter! hr=0x%x\n"), hr);
*ppFilter = NULL;
return hr;
}
return S_OK;
}
HRESULT CMasterObject::RenderOutputPins(IGraphBuilder *pGB, IBaseFilter *pFilter)
{
HRESULT hr = S_OK;
IEnumPins * pEnumPin = NULL;
IPin * pConnectedPin = NULL, * pPin;
PIN_DIRECTION PinDirection;
ULONG ulFetched;
// Enumerate all pins on the filter
hr = pFilter->EnumPins( &pEnumPin );
if(SUCCEEDED(hr))
{
// Step through every pin, looking for the output pins
while (S_OK == (hr = pEnumPin->Next( 1L, &pPin, &ulFetched)))
{
// Is this pin connected? We're not interested in connected pins.
hr = pPin->ConnectedTo(&pConnectedPin);
if (pConnectedPin)
{
pConnectedPin->Release();
pConnectedPin = NULL;
}
// If this pin is not connected, render it.
if (VFW_E_NOT_CONNECTED == hr)
{
hr = pPin->QueryDirection( &PinDirection );
if ( ( S_OK == hr ) && ( PinDirection == PINDIR_OUTPUT ) )
{
hr = pGB->Render(pPin);
}
}
pPin->Release();
// If there was an error, stop enumerating
if (FAILED(hr))
break;
}
}
// Release pin enumerator
pEnumPin->Release();
return hr;
}
BOOL CMasterObject::GetClipFileName(LPTSTR szName)
{
static OPENFILENAME ofn={0};
static BOOL bSetInitialDir = FALSE;
// Reset filename
*szName = 0;
// Fill in standard structure fields
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = ghApp;
ofn.lpstrFilter = FILE_FILTER_TEXT;
ofn.lpstrCustomFilter = NULL;
ofn.nFilterIndex = 1;
ofn.lpstrFile = szName;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrTitle = TEXT("Open Media File...\0");
ofn.lpstrFileTitle = NULL;
ofn.lpstrDefExt = TEXT("*\0");
ofn.Flags = OFN_FILEMUSTEXIST | OFN_READONLY | OFN_PATHMUSTEXIST;
// Remember the path of the first selected file
if (bSetInitialDir == FALSE)
{
ofn.lpstrInitialDir = DEFAULT_MEDIA_PATH;
bSetInitialDir = TRUE;
}
else
ofn.lpstrInitialDir = NULL;
// Create the standard file open dialog and return its result
return GetOpenFileName((LPOPENFILENAME)&ofn);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -