DirectShow应用:只用API调用实现网络播放

来源:互联网 发布:网络招生哪家强 编辑:程序博客网 时间:2024/04/30 10:10

                 DirectShow应用:只用API调用实现网络播放

 

本文只用一个main.cpp文件就实现了简单的网络媒体播放。代码如下:

一.       预定义

#define NO_SHLWAPI_STRFCNS

#include <DShow.h>

#include <atlcomcli.h>

 

#pragma comment(lib,"strmiids.lib")

 

LPCTSTR lpAppName = TEXT("An Example of Playing Internet File\(http:\\\\www.entrigle.com\\movie\\Megamind.avi) By Simply Using WindowsAPI!");

LPCTSTR lpClassName= TEXT("MY Class");

 

LRESULT CALLBACKWndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );

 

void play( HWND hwnd );

头文件dshow.h中包含DirectShow常用的内容,altcomcli.h包含智能指针等相关内容。接下来,引用需要的库,定义回调函数及播放函数原型。

二.       入口函数

int APIENTRY WinMain( HINSTANCE hinstance, HINSTANCEhPreviousInsance,

                                                 LPTSTR lpCmdLine,intnCmdShow )

{

         // to setupthe properties of the window

         MSG msg;

         HWND hwnd;

 

         WNDCLASS wc;

         wc.style = CS_HREDRAW | CS_VREDRAW;

         wc.lpfnWndProc = (WNDPROC)WndProc;  // 为窗体指定回调函数

         wc.cbClsExtra = 0;

         wc.cbWndExtra = 0;

         wc.hInstance = hinstance;

         wc.hIcon = LoadIcon( hinstance,IDI_APPLICATION );

         wc.hCursor = LoadCursor( hinstance,IDC_ARROW );

         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

         wc.lpszMenuName = lpAppName;

         wc.lpszClassName = lpClassName;

 

         // toregister and create the window

         if(!RegisterClass( &wc ) )

         {

                   returnFALSE;

         }

 

         hwnd = CreateWindow( lpClassName,lpAppName, WS_OVERLAPPEDWINDOW,

                                                         CW_USEDEFAULT,0,

                                                         CW_USEDEFAULT,0,

                                                         NULL,

                                                         NULL,

                                                         hinstance,

                                                         NULL

                                                  );

         if(!hwnd )

         {

                   returnFALSE;

         }

         ShowWindow(hwnd, nCmdShow);

         UpdateWindow(hwnd);

 

         // to playthe network file

         play( hwnd );

 

         // 进入消息循环

         while(GetMessage(&msg, NULL, 0, 0 ))

         {

                   TranslateMessage( &msg );

                   DispatchMessage( &msg );

         }

         returnmsg.wParam;

}

如上,定义Windows入口函数WinMain,首先定义窗体结构WNDCLASS变量,并通过调用RegisterClass进行注册,调用CreateWindow创建一个窗体,并激活之。然后,调用函数play播放一个网络文件。

函数play的实现代码如下:

void play( HWND hwnd )

{

         // initializethe com library

         HRESULT hr = CoInitializeEx( NULL,COINIT_APARTMENTTHREADED );

         if(FAILED(hr) )

         {

                   MessageBox( NULL, TEXT("Initialize error!"), NULL, 0 );

                   return;

         }

 

         // to get thepointer for Graph Builder

         CComPtr<IGraphBuilder> pGraph;

         hr = CoCreateInstance(CLSID_FilterGraph, NULL,

                                               CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph );

         if(FAILED(hr) )

         {

                   MessageBox( NULL, TEXT("Create Graph builder error!"), NULL, 0);

                   CoUninitialize();

                   return;

         }

 

         // to makeintelligent connection

         hr = pGraph->RenderFile( L"http:\\\\\www.entrigle.com\\movie\\Megamind.avi",NULL );

         if(FAILED(hr) )

         {

                   MessageBox( NULL, TEXT("Renderer file error!"), NULL, 0 );

                   pGraph = NULL;

                   CoUninitialize();

                  return;

         }

 

         // to get thepointer for media controlling

         CComPtr<IMediaControl> pControl;

         hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl );

         if(FAILED(hr) )

         {

                   MessageBox( NULL, TEXT("Create Control error!"), NULL, 0 );

                   pGraph = NULL;

                   CoUninitialize();

                   return;

         }

 

         // to get thepointer for media events

         CComPtr<IMediaEventEx> pEvent;

         hr = pGraph->QueryInterface(IID_IMediaEventEx, (void **)&pEvent );

         if(FAILED(hr) )

         {

                   MessageBox( NULL, TEXT("Create Event error!"), NULL, 0 );

                   pGraph = NULL;

                   pControl = NULL;

                   CoUninitialize();

                   return;

         }

 

         // to get thepointer for video window

         CComPtr<IVideoWindow> pVideo;

         hr = pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVideo );

         if(FAILED(hr) )

         {

                   MessageBox( NULL, TEXT("Create Video Window error!"), NULL, 0);

                   pGraph = NULL;

                   pControl = NULL;

                   CoUninitialize();

         }

 

         // to bind itto the window created before

         pVideo->put_Owner( (OAHWND)hwnd );

         RECT rect;

         GetClientRect( hwnd, &rect );

         pVideo->put_Left( 0 );

         pVideo->put_Top( 0 );

         pVideo->put_Width( rect.right -rect.left );

         pVideo->put_Height( rect.bottom -rect.top );

 

         // to playand wait

         pControl->Run();

         longcvCode;

         pEvent->WaitForCompletion( INFINITE,&cvCode );

 

         // to stopand release

         pControl->Stop();

         pVideo = NULL;

         pEvent = NULL;

         pControl = NULL;

         pGraph = NULL;

         CoUninitialize();

}

三.       回调函数

回调函数只进行简单的处理,当窗口关闭时发送应用程序终止消息,当按下任意键时可重复播放。代码如下:

LRESULT CALLBACKWndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )

{

         switch(message)

         {

                   caseWM_DESTROY :

                            PostQuitMessage(0);

                            break;

                   caseWM_KEYDOWN :

                            play( hwnd );

                            break;

                   default:

                            return DefWindowProc( hwnd, message, wparam, lparam);

                            break;

         }

         return0L;

}

本文旨在探索只用调用API的方式运用directshow技术,使代码量尽可能的减少,这对于Windows Api的学习和运用无疑是一个有益的尝试。

原创粉丝点击