游戏中的dshow媒体播放-即学即会-详细注释 

2007-03-20 22:17 发布

3831 4 0


1。简单地播放文件
#include <dshow.h>
#pragma comment (lib,"Ole32.lib")
#pragma comment (lib,"Strmiids.lib")
#define FILENAME L"C:\\Documents and Settings\\vs6\\桌面\\temp\\FL5007822001-500-2.avi"
bool g_bExit=false; //this APP will be exited when g_bExit=TURE
#define ture (bool)-1
int main()
{
IGraphBuilder *pGraphBuilder; //这是directshow的核心
IMediaControl *pMediaControl; //帮我们连接filter(媒体文件,解码器等)          //简单的说,它帮我们简单地打开和播放文件.
IVideoWindow *pVideoWindow; //用这个来控制directshow的视频窗口
//COM初始化
CoInitialize(NULL);

//建立FilterGraph
CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,
(LPVOID*)&pGraphBuilder);

// 向directshow询问MediaControl接口:
pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID*)&pMediaControl);

//建立 Graph:
pMediaControl->RenderFile(FILENAME);

           //向directshow询问VideoWindow接口:
pGraphBuilder->QueryInterface(IID_IVideoWindow,(LPVOID*)&pVideoWindow);

// 全屏:
pVideoWindow->put_Visible(OATRUE);
pVideoWindow->put_FullScreenMode(OATRUE);

           //开始播放:
pMediaControl->Run();

// 等待:
MessageBox(NULL,"Block Execution","Block",MB_OK);
          
          //停止:
pMediaControl->Stop();
// release resource:
pVideoWindow->Release();
pMediaControl->Release();
pGraphBuilder->Release();

// COM 销毁:
CoUninitialize();

return 0;
}

B Color Smilies

全部评论4

  • 前腐后继
    前腐后继 2007-3-20 22:17:00
    2。在自己的window中循环播放。
    接收到“播放结束”消息的时候,重新播放文件即可实现循环。
    请建立Win32 App!

    #include <dshow.h>
    #include <windows.h>
    #pragma comment (lib,"Ole32.lib")
    #pragma comment (lib,"Strmiids.lib")

    #define ture (bool)-1
    //你应该替换这个文件名:
    #define FILENAME L"C:\\Documents and Settings\\vs6\\桌面\\temp\\FL5007822001-500-2.avi"
    #define WM_GRAPH_NOTIFY (WM_APP + 1) //g_pMediaEventEx的消息

    bool g_bExit=false; //当g_bExit=TURE 时,程序结束
    HWND g_hwnd=0; //我们的播放器的主窗口
    IMediaEventEx *g_pMediaEventEx; //可以从directshow接受事件消息
    //当媒体播放结束后,它会通知我们
    IMediaControl *g_pMediaControl; //帮我们连接过滤器(文件,解码器。。。)             //简单地说,它帮我们简单的打开和播放文件
    IMediaPosition *g_pMediaPosition; //用这个来取得/设置媒体播放的位置等。

    void OnGraphNotify(); //当g_pMediaEventEx发消息通知我们时,我们就调用这个函数
    LRESULT WINAPI WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);

    int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR CmdLine,int nShowCmd)
    {
    IGraphBuilder *pGraphBuilder; //directshow的核心
    IVideoWindow *pVideoWindow; //用这个来控制directshow的视频窗口

    //COM初始化:
    CoInitialize(NULL);

    //建立FilterGraph:
    CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,
    (LPVOID*)&pGraphBuilder);

    //向directshow询问MediaControl接口:
    pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID*)&g_pMediaControl);

    //向directshow询问MediaPosition接口:
    pGraphBuilder->QueryInterface(IID_IMediaPosition,(LPVOID*)&g_pMediaPosition);

    //向directshow询问MediaEventsEx接口:
    pGraphBuilder->QueryInterface(IID_IMediaEventEx,(LPVOID*)&g_pMediaEventEx);

    //这段代码是建立一个播放器主窗口并显示之:
    WNDCLASSEX wc={sizeof(WNDCLASSEX),CS_CLASSDC,WinProc,0L,0L,
    GetModuleHandle(0),0,0,0,0,"instemast",0};
    RegisterClassEx(&wc);
    //我们窗口的客户区坐标:
    RECT rect={100,100,640+100-1,480+100-1};//width=right-left+1 , right=left+width-1
    //按照窗口客户区的坐标来计算窗口的实际坐标:
    ::AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,false);
    //注意,现在,rect的值更新了!
    g_hwnd=CreateWindow("instemast","dshow",WS_OVERLAPPEDWINDOW,rect.left,rect.top,
    rect.right-rect.left,rect.bottom-rect.top,0,0,wc.hInstance,0);
    ::ShowWindow(g_hwnd,nShowCmd);
    //结束建立播放器主窗口

    //我们将使用g_hwnd来接受directshow的消息:
    g_pMediaEventEx->SetNotifyWindow((OAHWND)g_hwnd,WM_GRAPH_NOTIFY, NULL);

    //建立Graph:
    g_pMediaControl->RenderFile(FILENAME);

    //向 directshow 询问 VideoWindow 接口:
    pGraphBuilder->QueryInterface(IID_IVideoWindow,(LPVOID*)&pVideoWindow);

    pVideoWindow->put_Owner((OAHWND)g_hwnd); //视频窗口是我们g_phwnd的子窗口!
    pVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS);
    pVideoWindow->SetWindowPosition(0,0,rect.right-rect.left+1,rect.bottom-rect.top+1);
    pVideoWindow->put_Visible(OATRUE);

    //start playing media:
    g_pMediaControl->Run();

    MSG msg;
    do
    {
    GetMessage(&msg,0,0,0);
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
    if(msg.message==WM_GRAPH_NOTIFY)OnGraphNotify();
    }while(!g_bExit); //消息循环,直到 g_bExit=TURE 时结束

    //释放资源:
    g_pMediaEventEx->Release();
    pVideoWindow->Release();
    g_pMediaControl->Release();
    pGraphBuilder->Release();

    //COM 终止:
    CoUninitialize();

    return 0;
    }

    void OnGraphNotify()
    {
    long evCode;
    LONG param1, param2;
    while(SUCCEEDED(g_pMediaEventEx->GetEvent(&evCode,&param1, &param2, 0)))
    {
    g_pMediaEventEx->FreeEventParams(evCode, param1, param2);
    switch (evCode)
    {
    case EC_COMPLETE: //我们的媒体播放结束了
    g_pMediaPosition->put_CurrentPosition(0); //重设播放位置为0,就是倒回的意思
    g_pMediaControl->Run();//重新播放
                                    //以上这样,就是循环播放!
    break;  
    };
    };
    }

    LRESULT WINAPI WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
    {
    switch(msg)
    {
    case WM_DESTROY:
    g_pMediaControl->Stop(); //停止播放
    g_bExit=ture; //我们的g_hwnd被关闭了,所以我们想退出程序
    break;
    };
    return DefWindowProc(hwnd,msg,wparam,lparam);

    }

  • 前腐后继
    前腐后继 2007-3-20 22:19:00
    3。进一步实现游戏中的一些需要(播放暂停,循环,Esc跳过动画播放等)
    使用另一种方式循环播放:
    用一个定时器,每1000ms检查一下当前播放位置,如果播放到结束,就重放一遍。

    #include <dshow.h>
    #include <windows.h>
    #pragma comment (lib,"Ole32.lib")
    #pragma comment (lib,"Strmiids.lib")

    #define ture (bool)-1
    //you should REPLACE the media file path
    #define FILENAME L"C:\\Documents and Settings\\vs6\\桌面\\temp\\FL5007822001-500-2.avi"
    #define WM_GRAPH_NOTIFY (WM_APP + 1) //the msg of g_pMediaEventEx

    bool g_bExit=false; //this APP will be exited when g_bExit=TURE
    HWND g_hwnd=0; //our player's main window
    IMediaEventEx *g_pMediaEventEx; //recieve event msgs from directshow
    //it notifies us when the media's playing is COMPLETE 
    IMediaControl *g_pMediaControl; //help us to link the filters(media file,codec...),
    //in short,it helps us open and play a file EASILY.
    IMediaPosition *g_pMediaPosition; //we use this to get/set the POSITION of a media's playing
    double g_Len;
    bool g_bIsPlaying=false;

    LRESULT WINAPI WinProc(HWND,UINT,WPARAM,LPARAM);
    void WINAPI OnTimer(HWND, UINT, UINT, DWORD);

    int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR CmdLine,int nShowCmd)
    {
    IGraphBuilder *pGraphBuilder; //this is the kernel of directshow
    IVideoWindow *pVideoWindow; //use this to control the video window of directshow

    //init COM
    CoInitialize(NULL);

    //create FilterGraph:
    CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,
    (LPVOID*)&pGraphBuilder);

    //ask directshow for the MediaControl:
    pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID*)&g_pMediaControl);

    //ask directshow for the MediaPosition:
    pGraphBuilder->QueryInterface(IID_IMediaPosition,(LPVOID*)&g_pMediaPosition);

    //ask directshow for the MediaEventEx:
    pGraphBuilder->QueryInterface(IID_IMediaEventEx,(LPVOID*)&g_pMediaEventEx);

    //start to create a window and show it
    WNDCLASSEX wc={sizeof(WNDCLASSEX),CS_CLASSDC,WinProc,0L,0L,
    GetModuleHandle(0),0,0,0,0,"instemast",0};
    RegisterClassEx(&wc);
    //our window's CLIENT positions:
    RECT rect={100,100,640+100-1,480+100-1};//width=right-left+1 , right=left+width-1
    //calculate our window's REAL positions from client positions:
    ::AdjustWindowRect(&rect,WS_OVERLAPPEDWINDOW,false);
    //NOW, rect's values are updated
    g_hwnd=CreateWindow("instemast","Esc=stop  Space=pause/play  F1=speed+  F2=speed-  F3=normal",WS_OVERLAPPEDWINDOW,rect.left,rect.top,
    rect.right-rect.left,rect.bottom-rect.top,0,0,wc.hInstance,0);
    ::ShowWindow(g_hwnd,nShowCmd);
    //end of creating window

    //we will recieve directshow's msg by g_hwnd:
    g_pMediaEventEx->SetNotifyWindow((OAHWND)g_hwnd,WM_GRAPH_NOTIFY, NULL);

    //create Graph:
    g_pMediaControl->RenderFile(FILENAME);

    //get our media's length:
    g_pMediaPosition->get_Duration(&g_Len);

    //ask directshow for the VideoWindow interface:
    pGraphBuilder->QueryInterface(IID_IVideoWindow,(LPVOID*)&pVideoWindow);

    pVideoWindow->put_Owner((OAHWND)g_hwnd); //VIDEOwindow is the child of OUR g_hwnd
    pVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS);
    pVideoWindow->SetWindowPosition(0,0,rect.right-rect.left+1,rect.bottom-rect.top+1);
    pVideoWindow->put_Visible(OATRUE);

    //start playing media:
    g_pMediaControl->Run();
    g_bIsPlaying=ture;

    ::SetTimer(g_hwnd,0,1000,&OnTimer);
    MSG msg;
    do
    {
    GetMessage(&msg,0,0,0);
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
    }while(!g_bExit); //do msg loop,until g_bExit=TURE

    //release the resource:
    g_pMediaEventEx->Release();
    pVideoWindow->Release();
    g_pMediaControl->Release();
    pGraphBuilder->Release();

    //COM destroy:
    CoUninitialize();

    return 0;
    }

    LRESULT WINAPI WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
    {
    double rate;
    switch(msg)
    {
    case WM_KEYDOWN:
    switch(wparam)
    {
    case 27: //[Esc] key--Stop media
    g_pMediaControl->Stop(); //stop media
    g_bIsPlaying=false;

    //show FIRST frame:
    g_pMediaPosition->put_CurrentPosition(0);
    g_pMediaControl->Run();
    ::Sleep(2);
    g_pMediaControl->Pause();

    //stop media:
    g_pMediaPosition->put_CurrentPosition(0);
    g_pMediaControl->Stop();
    break;
    case ' ': //pause or resume or play
    if(g_bIsPlaying)
    {
    g_pMediaControl->Pause();
    g_bIsPlaying=false;
    }
    else
    {
    g_pMediaControl->Run();
    g_bIsPlaying=ture;
    };
    break;
    case VK_F1: //rate(speed): 1.0=normal
    g_pMediaPosition->get_Rate(&rate);
    g_pMediaPosition->put_Rate(rate*1.25);
    break;
    case VK_F2:
    g_pMediaPosition->get_Rate(&rate);
    g_pMediaPosition->put_Rate(rate*0.8);
    break;
    case VK_F3:
    g_pMediaPosition->put_Rate(1.0);
    };
    break;
    case WM_DESTROY:
    g_pMediaControl->Stop(); //stop our media
    g_bIsPlaying=false;
    g_bExit=ture; //our g_hwnd has been closed,so we want to exit the app
    break;
    };
    return DefWindowProc(hwnd,msg,wparam,lparam);
    }

    void WINAPI OnTimer(HWND hwnd, UINT, UINT, DWORD)
    {
    double pos;
    g_pMediaPosition->get_CurrentPosition(&pos);
    if(pos>=g_Len)
    {
    g_pMediaPosition->put_CurrentPosition(0);
    g_pMediaControl->Run();
    };
    }

  • zhigu
    zhigu 2007-3-31 12:53:00
    ding !
  • aaaaaaaa
    aaaaaaaa 2007-4-29 09:39:00
    [em01]

你可能喜欢

游戏中的dshow媒体播放-即学即会-详细注释 
联系
我们
快速回复 返回顶部 返回列表