The simplest example based on DirectShow: Video Player GUI version and directshow Gui
========================================================== ==================
The simplest list of DirectShow-based example articles:
The simplest example based on DirectShow: Video Player
The simplest example based on DirectShow: graphic interface for video players
The simplest example based on DirectShow: Video Player custom edition
The simplest example based on DirectShow: Getting Filter information
========================================================== ==================
This document records a simple Video Player Based on the DirectShow GUI. There are still many examples of players based on the DirectShow GUI, but most of them are examples of "layer-by-layer encapsulation. The examples of "layer-by-layer encapsulation" are relatively more stable, but not easy to understand. Because DirectShow has a large number of interface functions, if you add the function that encapsulates DirectShow, the total number of functions is very large, it is easy to figure out which are the true DirectShow interface functions. This player removes the "layer-by-layer encapsulation" in the DirectShow example and directly calls the DirectShow interface to play the video, which is more suitable for getting started with DirectShow.
The implementation mechanism of several functions has a lot of code in the whole project and is not recorded in detail. Here we will briefly record several key points in the code.
The source code of the video "play" is as follows. In short, the initialization of the following video playback is completed:
(1) convert the input URL to Unicode encoding (the RenderFile () function supports Unicode strings ).
(2) Call RenderFile () "smart" to create the Filter Graph.
(3) Call the Run () method of IMediaControl to start playing the video.
(4) Enable the timer to update the video playback progress (detailed later)
void CplayerGUIDlg::OnBnClickedStart(){CStringA cstr_urla;CStringW cstr_urlw;HRESULT hr;//Render#ifdef _UNICODEm_url.GetWindowText(cstr_urlw);#elseUSES_CONVERSION;m_url.GetWindowText(cstr_urla);cstr_urlw.Format(L"%s",A2W(cstr_urla));#endifif(cstr_urlw.IsEmpty()){AfxMessageBox(_T("Input URL is NULL!"));return;}hr = pGraph->RenderFile(cstr_urlw, NULL);if(FAILED(hr)){AfxMessageBox(_T("Can't open input file!"));return;}//Set WindowHWND screen_hwnd=NULL;RECT windowRect;screen_hwnd = this->GetDlgItem(IDC_SCREEN)->GetSafeHwnd(); ::GetClientRect(screen_hwnd, &windowRect);pWindow->put_Visible(OAFALSE);pWindow->put_Owner((OAHWND)screen_hwnd);pWindow->put_Left(0);pWindow->put_Top(0);pWindow->put_Width(windowRect.right - windowRect.left);pWindow->put_Height(windowRect.bottom - windowRect.top);pWindow->put_WindowStyle(WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_THICKFRAME);pWindow->put_MessageDrain((OAHWND) screen_hwnd);//Receive MessagepWindow->put_Visible(OATRUE);pEvent->SetNotifyWindow((OAHWND)screen_hwnd, WM_GRAPHNOTIFY, 0);// Runhr = pControl->Run();playerstate=STATE_PLAY;SetBtn(STATE_PLAY);SetTimer(1,1000,NULL);}
The source code for pausing/resuming a video is as follows. Pause () and Run () of IMediaControl are called to set "Pause" or "continue ".
void CplayerGUIDlg::OnBnClickedPause(){HRESULT hr;if(playerstate==STATE_PLAY){hr=pControl->Pause();playerstate=STATE_PAUSE;GetDlgItem(ID_PAUSE)->SetWindowText(_T("Resume"));}else if(playerstate==STATE_PAUSE){hr=pControl->Run();playerstate=STATE_PLAY;GetDlgItem(ID_PAUSE)->SetWindowText(_T("Pause"));}}
The source code for stopping a video is as follows. The Code completes the following tasks:
(1) Adjust the playback position to 0 again.
(2) Call Pause () of IMediaControl ()
(3) disable the timer
(4) Delete the Filter in the Filter Graph.
void CplayerGUIDlg::OnBnClickedStop(){long long position = 0;HRESULT hr;hr = pSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 0, AM_SEEKING_NoPositioning);KillTimer(1);hr=pControl->Stop();// Enumerate the filters And remove themIEnumFilters *pEnum = NULL;hr = pGraph->EnumFilters(&pEnum);if (SUCCEEDED(hr)){IBaseFilter *pFilter = NULL;while (S_OK == pEnum->Next(1, &pFilter, NULL)){// Remove the filter.pGraph->RemoveFilter(pFilter);// Reset the enumerator.pEnum->Reset();pFilter->Release();}pEnum->Release();}SystemClear();}
The video playback progress is displayed on the timeline. As the video is played, you must update the playback progress information on the timeline of the video playback progress. A timer is used in the program to complete this function.
When the video starts playing, call SetTimer () to enable the timer. The interval is set to 1000 ms.
SetTimer(1,1000,NULL);
Call KillTimer () to end the timer when the video is stopped.
KillTimer(1);
In the message response function of the timer, the GetCurrentPosition () of IMediaSeeking is called to obtain the current playback time of the video, and the GetDuration () of IMediaSeeking is called to obtain the video duration. Based on the value obtained by the above function, the result is calculated and set to the corresponding control. The code for this part is as follows.
void CplayerGUIDlg::OnTimer(UINT_PTR nIDEvent){if (nIDEvent == 1){CString curtimestr,durationstr;long long curtime;long long duration;int tns, thh, tmm, tss;int progress;//mspSeeking->GetCurrentPosition(&curtime);if(curtime!=0){//change to secondtns = curtime/10000000;thh = tns / 3600;tmm = (tns % 3600) / 60;tss = (tns % 60);curtimestr.Format(_T("%02d:%02d:%02d"),thh,tmm,tss);m_curtime.SetWindowText(curtimestr);}pSeeking->GetDuration(&duration);if(duration!=0){tns = duration/10000000;thh = tns / 3600;tmm = (tns % 3600) / 60;tss = (tns % 60);durationstr.Format(_T("%02d:%02d:%02d"),thh,tmm,tss);m_duration.SetWindowText(durationstr);progress=curtime*100/duration;m_progress.SetPos(progress);}}CDialogEx::OnTimer(nIDEvent);}
Adjust the video playback point. When you drag the Slider on the Slider Control, you need to set the video playback progress based on the drag position. Call SetPositions () of IMediaSeeking to set the video playback progress. The code in the message response function is as follows.
void CplayerGUIDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar){if (pScrollBar->GetSafeHwnd() == m_progress.GetSafeHwnd()){float pos_bar=0.0;long long duration=0.0;long long pos_time=0.0;if(nSBCode==SB_THUMBPOSITION){pos_bar=(float)nPos/100.0;pSeeking->GetDuration(&duration);pos_time=pos_bar*duration;long long position = (long long)(pos_time);HRESULT hr = pSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 0, AM_SEEKING_NoPositioning);}}CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);}
Full Screen playback of problematic videos is implemented through put_FullScreenMode () of IVideoWindow. The Code is as follows.
void CplayerGUIDlg::OnBnClickedFullscreen(){pWindow->put_FullScreenMode(OATRUE);}
At the same time, after "Full Screen mode" is enabled, if you press the "ESC" key, you can disable "Full Screen mode ". This part of code is implemented in PreTranslateMessage (), as shown below.
//Exit Full Screen mode when push "ESC"BOOL CplayerGUIDlg::PreTranslateMessage(MSG* pMsg){if (pMsg->message == WM_KEYDOWN){if (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE){// Restore form fullscreen modepWindow->put_FullScreenMode(OAFALSE);return 1;}}return CDialogEx::PreTranslateMessage(pMsg);}
Note that the put_FullScreenMode () of IVideoWindow is faulty in Win7. You can use WS_THICKFRAME only when you specify a window style. For example, the following code.
pWindow->put_WindowStyle(WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_THICKFRAME);
If the WS_THICKFRAME style is not specified, the video will not be displayed after the "full screen" mode is exited. Instead, the video will be black.
However, after the WS_THICKFRAME style is set, there will be a "white edge" on the periphery of the video window, which will affect the video display. Therefore, if we want to use full screen normally, we may need to find a better method. I have not studied it in depth here.
Running result
This is an example player developed based on MFC using DirectShow. The basic functions of a player are as follows: Play, pause/continue, stop, display the playback timeline, and play media from any point. You can also drag a media file to the player for playback. Input the media file path to the URL bar before playing the video, and click Start to Start playing the video. Under the software, buttons such as "start", "Pause", and "Stop" are included to control media playback.
The following figure shows the effect during playback.
Click "Full Screen" to play the video in Full Screen. Click "Info" to display information about the playing media, including the following two types of information:
(1) related information of the video
(2) Filter in the Filter Graph that plays the video.
Download
Simplest DirectShow Example
SourceForge project home: https://sourceforge.net/projects/simplestdirectshowexample/
CDSN: http://download.csdn.net/detail/leixiaohua1020/8348163
This program contains the example program developed by DirectShow. Suitable for beginners of DirectShow.
It contains the following subprograms:
Simplest_directshow_player: the simplest Video Player Based on DirectShow.
Simplest_directshow_player_custom: the simplest Video Player Based on DirectShow (Custom ).
PlayerGUI: the simplest player-Gui version based on DirectShow.
Simplest_directshow_info: the simplest Directshow information display example.
Simplest_directshow_filter: not completed yet.