如何在两个窗口中播放相同的视频(父和子对话框)。 [英] How to play the same video in two windows (Parent and child dialog box).

查看:83
本文介绍了如何在两个窗口中播放相同的视频(父和子对话框)。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

播放视频是通过在MFC中使用directshow创建过滤器图表。如果我按下父对话框中的控件,我需要在父对话框和子对话框中播放视频。视频在父对话框中播放,在子窗口中播放我必须做的事情。



这是我的代码:



  //   playbackControls1Dlg.cpp:实施文件 
// CplaybackControls1Dlg对话框
CplaybackControls1Dlg :: CplaybackControls1Dlg(CWnd * pParent / * = NULL * /
:CDialog(CplaybackControls1Dlg :: IDD,pParent )
{
m_hIcon = AfxGetApp() - > LoadIcon(IDR_MAINFRAME);
z = CZoom;
}
// CplaybackControls1Dlg消息处理程序
BOOL CplaybackControls1Dlg :: OnInitDialog()
{
CDialog :: OnInitDialog();
// 将关于...菜单项添加到系统菜单。
// IDM_ABOUTBOX必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX& 0xFFF0)== IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX< 0xF000);
CMenu * pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu!= NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu-> AppendMenu(MF_SEPARATOR);
pSysMenu-> AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序的主窗口不是对话框时,框架会自动执行此操作
// span>
SetIcon(m_hIcon,TRUE); // 设置大图标
SetIcon(m_hIcon,FALSE); // 设置小图标
// TODO:在此处添加额外的初始化
// 创建过滤器图形管理器并查询接口。
hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,( void **)& pGraph);
if (FAILED(hr))
{
MessageBox(L 错误 - 无法创建过滤器图管理器。);
return FALSE;
}
hr = pGraph-> QueryInterface(IID_IMediaControl,( void **)& pControl);
hr = pGraph-> QueryInterface(IID_IMediaEvent,( void **)& pEvent);
IMediaEventEx * g_pEvent = NULL;
pGraph-> QueryInterface(IID_IMediaEventEx,( void **)& pEvent);
hr = InitWindowlessVMR(AfxGetMainWnd() - > m_hWnd,pGraph,& pWc);
hr = pGraph-> RenderFile(L C:\\Documents and Settings \\\ \\ BTC \\Desktop\\hai.mp4,NULL);
VideoSize();
return TRUE; // 除非将焦点设置为控件,否则返回TRUE
}
< span class =code-keyword> void
CplaybackControls1Dlg :: OnBnClickedPlayButton()
{
// TODO:在此处添加您的控制通知处理程序代码

hr = pEvent-> SetNotifyWindow((OAHWND)AfxGetMainWnd() - > m_hWnd,WM_GRAPHNOTIFY, 0 );

if (SUCCEEDED(hr))
{
// 运行图表。
hr = pControl-> Run();
z-> ShowWindow(SW_SHOW);
}
}
HRESULT CplaybackControls1Dlg :: InitWindowlessVMR(
HWND hwndApp, // 用于保存视频的窗口。
IGraphBuilder * pGraph, // 指向过滤图管理器。
IVMRWindowlessControl ** ppWc // 接收指向VMR的指针。

{
if (!pGraph ||!ppWc)
{
< span class =code-keyword> return
E_POINTER;
}
IBaseFilter * pVmr = NULL;
IVMRWindowlessControl * pWc = NULL;
// 创建VMR。
HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer,NULL,
CLSCTX_INPROC,IID_IBaseFilter,( void **)& pVmr);
if (FAILED(hr))
{
return hr ;
}
// 将VMR添加到过滤器图表中。
hr = pGraph-> AddFilter(pVmr,L Video Mixing Renderer);
if (FAILED(hr))
{
pVmr-> Release();
return hr;
}
// 设置渲染模式。
IVMRFilterConfig * pConfig;
hr = pVmr-> QueryInterface(IID_IVMRFilterConfig,( void **)& pConfig);
if (SUCCEEDED(hr))
{
hr = pConfig-> SetRenderingMode(VMRMode_Windowless);
pConfig-> Release();
}
if (SUCCEEDED(hr))
{
/ / 设置窗口。
hr = pVmr-> QueryInterface(IID_IVMRWindowlessControl,( void **)& pWc);
if (SUCCEEDED(hr))
{
hr = pWc-> SetVideoClippingWindow(hwndApp);
if (SUCCEEDED(hr))
{
* ppWc = pWc; // 将其作为AddRef'd指针返回。
}
else
{
// 发生错误,因此请释放界面。
pWc-> Release();
}
}
}
pVmr-> Release();
return hr;
}
int CplaybackControls1Dlg :: OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog :: OnCreate(lpCreateStruct)== - 1
return - 1 ;

// TODO:在此处添加专门的创作代码
z->创建(IDD_DIALOG1,);
z-> ShowWindow(FALSE);
return 0 ;
}
LRESULT CplaybackControls1Dlg :: WindowProc(UINT消息,WPARAM wParam,LPARAM lParam)
{
// < span class =code-comment> TODO:在此处添加您的专用代码和/或调用基类
switch (message)
{
case WM_GRAPHNOTIFY:
HandleGraphEvent();
break ;
case WM_CLOSE:
CleanUp();
break ;
}
return CDialog :: WindowProc(message,wParam,lParam);
}
void CplaybackControls1Dlg :: HandleGraphEvent()
{
/ / 如果我们没有IMediaEventEx指针,请忽略。
如果( pEvent == NULL)
{
return ;
}
// 获取所有活动
long evCode;
LONG_PTR param1,param2;
while (SUCCEEDED(pEvent-> GetEvent(& evCode,¶m1,¶m2, 0 )))
{
pEvent-> FreeEventParams(evCode,param1,param2);
switch (evCode)
{
case EC_COMPLETE: // 堕落。
案例 EC_USERABORT: // 通过。
case EC_ERRORABORT:
pControl-> Stop();
pEvent-> SetNotifyWindow(NULL, 0 0 );
return ;
}
}
}
void CplaybackControls1Dlg :: CleanUp()
{
pWc - >推出();
pControl-> Release();
pGraph-> Release();
pEvent-> Release();
}
void CplaybackControls1Dlg :: VideoSize()
{
long lWidth,lHeight;
hr = pWc-> GetNativeVideoSize(& lWidth,& lHeight,NULL,NULL);
if (SUCCEEDED(hr))
{
RECT rcSrc,rcDest;
// 设置源矩形。
SetRect(& rcSrc,< span class =code-digit> 0 , 0 ,lWidth,lHeight);
// 获取窗口客户区。
GetClientRect(& rcDest) ;
// 设置目标矩形。
SetRect(& rcDest,< span class =code-digit> 0 , 40 ,rcDest.right,rcDest.bottom);
// 设置视频位置。
hr = pWc-> SetVideoPosition (& rcSrc,& rcDest);
}

}





CZoom是儿童窗口。

此代码用于在父窗口中播放视频。我必须做些什么来改变孩子的视频。



提前谢谢你,

解决方案

< blockquote>通过制作类似播放的方法并在窗口(父级和子级)中添加axwindowsmediaplayer控件,并在加载时调用播放该视频的方法..


我假设您需要窗口要同步?你不能只在一个线程中开始播放,然后在第二个线程线程的另一个窗口中播放?



我不知道该怎么做,但我会按照以下方式接近它。可能有一种更简单的方法...



1.创建一个类来描述窗口的回放特性。我将其称为CVideoPlaybackSetting。它至少包含以下成员。

a。 CWnd m_hWnd; //处理窗口,这里可能需要某种类型的上下文。

b。 CRect m_VideoRect; //在窗口中定义视频将显示的矩形。



2.创建视频播放器类以管理视频播放。现在我将其称为CVideoPlayer。它将包含一个CVideoPlaybackSetting数组。它将有一个接口挂钩,用于在播放期间捕捉每个帧并渲染到列表中的每个窗口。



3.分配您想要视频播放的任何窗口,到CVideoPlayer。



4.开始播放。



请注意,你可能需要为回放创建某种渲染表面,并在渲染帧时将其挂钩到通知中。这变得相当复杂,然后告诉DX引擎播放电影。


Am Playing the video by creating the filter graph using directshow in MFC. If i press the control which is in the parent dialog box i need to play the video in parent dialog box as well as child dialog box. The video was played in parent dialog box, to play as well as in child window what i have to do.

Here is my code:

// playbackControls1Dlg.cpp : implementation file
// CplaybackControls1Dlg dialog
CplaybackControls1Dlg::CplaybackControls1Dlg(CWnd* pParent /*=NULL*/)
	: CDialog(CplaybackControls1Dlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	z=new CZoom;
}
// CplaybackControls1Dlg message handlers
BOOL CplaybackControls1Dlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	// Add "About..." menu item to system menu.
	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	// TODO: Add extra initialization here
        // Create the filter graph manager and query for interfaces.
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&pGraph);
    if (FAILED(hr))
    {
        MessageBox(L"ERROR - Could not create the Filter Graph Manager.");
        return FALSE;
    }
    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
    IMediaEventEx *g_pEvent = NULL;
    pGraph->QueryInterface(IID_IMediaEventEx, (void **)&pEvent);
    hr = InitWindowlessVMR(AfxGetMainWnd()->m_hWnd, pGraph, &pWc);
    hr=pGraph->RenderFile(L"C:\\Documents and Settings\\BTC\\Desktop\\hai.mp4", NULL);
    VideoSize();	
    return TRUE;  // return TRUE  unless you set the focus to a control
}
void CplaybackControls1Dlg::OnBnClickedPlayButton()
{
	// TODO: Add your control notification handler code here
	
	hr = pEvent->SetNotifyWindow((OAHWND)AfxGetMainWnd()->m_hWnd, WM_GRAPHNOTIFY, 0);

	if (SUCCEEDED(hr))
    {
        // Run the graph.
        hr = pControl->Run();
	z->ShowWindow(SW_SHOW);
    }
}
HRESULT CplaybackControls1Dlg::InitWindowlessVMR( 
    HWND hwndApp,                  // Window to hold the video. 
    IGraphBuilder* pGraph,         // Pointer to the Filter Graph Manager. 
    IVMRWindowlessControl** ppWc   // Receives a pointer to the VMR.
    ) 
{ 
    if (!pGraph || !ppWc) 
    {
        return E_POINTER;
    }
    IBaseFilter* pVmr = NULL; 
    IVMRWindowlessControl* pWc = NULL; 
    // Create the VMR. 
    HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL, 
        CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr); 
    if (FAILED(hr))
    {
        return hr;
    }   
    // Add the VMR to the filter graph.
    hr = pGraph->AddFilter(pVmr, L"Video Mixing Renderer"); 
    if (FAILED(hr)) 
    {
        pVmr->Release();
        return hr;
    }
    // Set the rendering mode.  
    IVMRFilterConfig* pConfig; 
    hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig); 
    if (SUCCEEDED(hr)) 
    { 
        hr = pConfig->SetRenderingMode(VMRMode_Windowless); 
        pConfig->Release(); 
    }
    if (SUCCEEDED(hr))
    {
        // Set the window. 
        hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
        if( SUCCEEDED(hr)) 
        { 
            hr = pWc->SetVideoClippingWindow(hwndApp); 
            if (SUCCEEDED(hr))
            {
                *ppWc = pWc; // Return this as an AddRef'd pointer. 
            }
            else
            {
                // An error occurred, so release the interface.
                pWc->Release();
            }
        } 
    } 
    pVmr->Release(); 
    return hr; 
} 
int CplaybackControls1Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  Add your specialized creation code here
	z->Create(IDD_DIALOG1,this);
	z->ShowWindow(FALSE);
	return 0;
}
LRESULT CplaybackControls1Dlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	// TODO: Add your specialized code here and/or call the base class
switch(message)
{
case WM_GRAPHNOTIFY:
	HandleGraphEvent();
    break;
case WM_CLOSE:
	CleanUp();
	break;
}
	return CDialog::WindowProc(message, wParam, lParam);
}
void CplaybackControls1Dlg::HandleGraphEvent()
{
    // Disregard if we don't have an IMediaEventEx pointer.
    if (pEvent == NULL)
    {
        return;
    }
    // Get all the events
    long evCode;
    LONG_PTR param1, param2;
    while (SUCCEEDED(pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0)))
    {
        pEvent->FreeEventParams(evCode, param1, param2);
        switch (evCode)
        {
        case EC_COMPLETE:  // Fall through.
        case EC_USERABORT: // Fall through.
        case EC_ERRORABORT:
	pControl->Stop();
        pEvent->SetNotifyWindow(NULL, 0, 0);
        return;
        }
    } 
}
void CplaybackControls1Dlg::CleanUp()
{
	pWc->Release();
        pControl->Release();
        pGraph->Release();
	pEvent->Release();
}
void CplaybackControls1Dlg::VideoSize()
{
	long lWidth, lHeight; 
	hr = pWc->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL); 
	if (SUCCEEDED(hr))
	{
		RECT rcSrc, rcDest; 
		// Set the source rectangle.
		SetRect(&rcSrc, 0, 0, lWidth, lHeight);
		// Get the window client area.
		GetClientRect(&rcDest); 
		// Set the destination rectangle.
		SetRect(&rcDest, 0, 40, rcDest.right, rcDest.bottom); 
	    	// Set the video position.
		hr = pWc->SetVideoPosition(&rcSrc, &rcDest); 
	}
	
}



CZoom is the child window.
This code is for playing the video in the parent window. What changes i have to make to play the video in the child.

Thank You in advance,

解决方案

By making a method like play and add axwindowsmediaplayer control in both the window (Parent and child ) and on load call the method for playing that video..


I assume you need the windows to be synchronized? You can''t just start playback in one thread and then playback in another window in a second thread thread?

I don''t know exactly how to do it, but I would approach it in the following manner. there may be an easier way to do it...

1. Create a class to describe the playback characteristics for a window. I''ll refer to this as CVideoPlaybackSetting. It will contain at least the following members.
a. CWnd m_hWnd; // Handle for the window, you may need a context of some type here.
b. CRect m_VideoRect; // Defines the rectangle in the window that the video will be displayed in.

2. Create a video player class to manage the video playback. For now I''ll refer to this as CVideoPlayer. It will contain an array of CVideoPlaybackSetting. It will have an interface hook to catch each frame during playback and render to each window in the list.

3. Assign any window you want video play back to occur in, to CVideoPlayer.

4. Start playback.

Note that you''ll likely have to create a render surface of some kind for the playback and hook into notifications as the frames are rendered to it. This gets quite a bit more complicated, then just telling the DX engine to play the movie.


这篇关于如何在两个窗口中播放相同的视频(父和子对话框)。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆