wince下用DirectShow播放音频和视频_第1页
wince下用DirectShow播放音频和视频_第2页
wince下用DirectShow播放音频和视频_第3页
wince下用DirectShow播放音频和视频_第4页
wince下用DirectShow播放音频和视频_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、wince下用DirectShow播放音频和视频wince下用DirectShow播放音频和视频         虽然网上关于wince下如何使用DirectShow播放多媒体文件的资料不多,但WinCE毕竟还属于windows,而桌面系统的DirectShow例子网上信手拈来,并且其中DirectShow的功能方法与之WinCE下差别不大,又本人实在没有信心比他们的轮子造得更为华丽,所以这篇文章就直接切入正题,不介绍DirectShow的结构功能,直接来看看怎么用吧.(其实还是自己懒惰的原因大一些,恩,不过这个和本文的主题

2、没多大关系:-).               为了方便代码的移植,所以我将DirectShow的操作封装成CMedia类,只要直接调用该类,就可以相当简便地调用DirectShow来播放多媒体文件了                好,闲话至此,我们以具体代码看看是如何:     

3、;    /获取CMedia的实例        CMedia *m_pMedia = CMedia:GetInstance();                /设置播放的窗口        m_pMedia->SetVideoWindow(hWnd);  &#

4、160;             /打开媒体文件        m_pMedia->Open(TEXT("A.AVI");                /播放        m_pM

5、edia->Play();                .                /播放结束后,调用Close释放资源        m_pMedia->Open();     

6、   没错,就是六行代码,就这么简单,可以顺利播放媒体文件.在这里要说一下的是,因为我们播放的是视频,需要有一个窗口显示,所以需要调用SetVideoWindow()函数来设置播放窗口.这个播放视频的窗口,可以是普通的窗口,也可以是Picture控件.当然咯,如果是播放音频文件,那么则完全可以无视这个函数.                还有一个最值得注意的地方,当调用Open()成功之后,一定要调用Close()来释放资源,然后才能打

7、开另一个媒体文件.否则,不释放的资源可能会导致很多莫名其妙的后果哦.                        等等,代码似乎还不完美,比如说,我想在文件播放之后再接着播放另外一个文件,那么我如何知道什么时候文件已经播放完毕了呢?这时候我们就需要请出SetNotifyWindow().        &#

8、160;       该函数的作用是设置一个接受消息的窗口,当DirectShow有事件变更时,就会发送指定的消息到指定的窗口,原型如下:                SetNotifyWindow(HWND hWnd, UINT wMsg,long lInstanceData)          

9、0;     hWnd:接收消息的窗口句柄.                wMsg:指定的自定义消息                lInstanceData:消息的参数.         

10、0;              那么,现在以接收一个视频播放结束事件的代码片段为例子:         /自定义一个消息        #define WM_GRAPHNOTIFY        (WM_USER + 13)   

11、             /设置接收消息窗口和消息        m_pMedia->SetVideoWindow(hWnd,WM_GRAPHNOTIFY,NULL);                .      

12、          /这个是消息循环函数        LRESULT CMainWnd:WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)        .            switch(wMs

13、g)            .                            .            

14、0;               case WM_GRAPHNOTIFY:                .                 

15、;   LONG evCode,evParam1,evParam2;                                        /获取此时的DirectShow事件 &#

16、160;                  if(m_pMedia->GetEvent(&evCode,&evParam1,&evParam2) = TRUE)                    .

17、0;                       if(evCode = EC_COMPLETE)                        .&

18、#160;                           MessageBox(NULL,TEXT("播放完毕"),TEXT(""),MB_OK);            &

19、#160;                                                   retu

20、rn 0;                                                    .&#

21、160;                                   好了,知道播放完毕,就这么简单.恩,还很复杂.?呵呵,我觉得已经很简单了.            &#

22、160;   文章的最后,让我们再来看看CMedia的其它几个有用的函数吧:                CheckVisibility()        描述:判断文件的种类        当返回值为TRUE时,为视频文件;反之为只是音频文件.    &#

23、160;                   SetVolume(LONG lVolume, LONG lBalance)        描述:设置音量.        lVolume:设置音量的大小,范围为10,000 到 0.      

24、;  lBalance:设置左右音量的均衡,范围是10,000 到 10,000,默认是0.                        SetDisplayMode(DISPLAYMODE mode)        描述:设置播放模式.      

25、;  DISP_FIT:按比例拉伸至视屏窗口.        DISP_STRETCH:不按比例拉伸至视屏窗口.        DISP_NATIVE:如果视频原本尺寸小于屏幕,则以原视频文件大小播放.否则,将和DISP_FIT相同        DISP_FULLSCREEN:全屏/*/        /M

26、edia.h: interface for the CMedia class./Version:/    1.2.0/Date:/    2007.05.08/*/#ifndef MEDIA_H#define    MEDIA_H#include <mmsystem.h>#include <streams.h>/-/Macro define/The volume value#define MAX_VOLUME      &

27、#160;             0#define MIN_VOLUME                    -10000/The balance value#define MAX_BALANCE       

28、60;            10000#define MIN_BALANCE                    -10000/-/Enum valueenum DISPLAYMODE.        /Fit to the play

29、window size. How wide (height) the window is, how     /is the move. Keep aspect ratio.    DISP_FIT,    /Stretch to the play window size. Don't keep the aspect ratio.    DISP_STRETCH,    /Full screen play.   

30、; DISP_FULLSCREEN,    /When the size of video is smaller than the play window, it displayes    /as the video size. If it's bigger , it just like the DISP_FIT mode.    DISP_NATIVE;/-/The media file propertytypedef struct.    /The volume

31、range is 10,000 to 0.    /Divide by 100 to get equivalent decibel value (for example 10,000 = 100 dB).     LONG lVolume;    /The value from 10,000 to 10,000 indicating the stereo balance    /As with the Volume property, units correspond to

32、.01 decibels (multiplied by 1 when plBalance is a positive value).    /For example, a value of 1000 indicates 10 dB on the right channel and 90 dB on the left channel.     LONG lBalance;    /Width of the video      LONG lWidth; &#

33、160;  /Height of the video    LONG lHeight;    /Approximate bit rate    LONG lBitRate;MEDIAPROPERTY,*PMEDIAPROPERTY;/-class CMedia  .public:    BOOL GetEvent(LONG *plEvCode, LONG *plParam1, LONG *plParam2);    BOOL

34、SetNotifyWindow(HWND hWnd, UINT wMsg,long lInstanceData);    BOOL SetVolume(LONG lVolume, LONG lBalance = 0);    BOOL SetDisplayMode(DISPLAYMODE mode);    BOOL GetMediaProperty(PMEDIAPROPERTY pOutProperty);    static CMedia * GetInstance();

35、    void Close();    BOOL CheckVisibility();    void SetVideoWindow(HWND hWndVideo);    BOOL Open(TCHAR * pszFileName);    BOOL Stop();    BOOL Pause();    BOOL Play();    virtual

36、CMedia();protected:    CMedia();        / Collection of interfaces    IGraphBuilder *m_pGB;    IMediaControl *m_pMC;    IMediaEventEx *m_pME;    IVideoWindow  *m_pVW;    IBasi

37、cAudio   *m_pBA;    IBasicVideo   *m_pBV;    IMediaSeeking *m_pMS;    TCHAR m_szFileNameMAX_PATH;    HWND m_hWndVideo; /The window play video    HWND m_hWndNotify; /The window notify    BOOL

38、 m_bExitThrd;    BOOL m_bThrdRunning;    static CMedia * m_pInstance;    DISPLAYMODE m_DispMode;#endif /#ifndef MEDIA_H  /*/ Media.cpp: implementation of the CMedia class./*/#include "stdafx.h"#include "Media.h"/-/Macro defin

39、e/Default play mode#define DEFAULT_DISPLAY_MODE        DISP_NATIVE/-/InitializeCMedia *CMedia:m_pInstance = NULL;/-/*/ Construction/Destruction/*/CMedia:CMedia():m_pGB(NULL),m_pMC(NULL),m_pME(NULL),m_pVW(NULL),m_pBA(NULL),m_pBV(NULL),m_pMS(NULL),m_hWndVideo(NULL),m

40、_bExitThrd(TRUE),m_bThrdRunning(FALSE),m_DispMode(DEFAULT_DISPLAY_MODE),m_hWndNotify(NULL).    memset(m_szFileName,0,sizeof(m_szFileName);CMedia:CMedia().    if(m_pInstance != NULL)    .        delete m_pInstance; &

41、#160;      m_pInstance = NULL;     /-/Description:/    Play the media file/    When you call the function,you should call Open() before./-BOOL CMedia:Play().        / Run the graph to play the me

42、dia file    if(m_pMC = NULL)    .        return FALSE;                m_pMC->Run();    return TRUE; /-/Description:/    Pause. /

43、0;   When you call the function,you should call Open() before./-BOOL CMedia:Pause().    if(m_pMC = NULL)    .        return FALSE;            m_pMC->Pause();    r

44、eturn TRUE; /-/Description:/    Stop./    When you call the function,you should call Open() before./-BOOL CMedia:Stop().    if(m_pMC = NULL | m_pMS = NULL)    .        return FALSE;   

45、        m_pMC->Stop();        m_pMS->SetPositions(0, AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning);           return TRUE; /-/Description:/    Open the media

46、file. When succeed in calling the function ,/you should call the Close() to release the resource/-BOOL CMedia:Open(TCHAR *pszFileName).    BOOL bResult = FALSE;        if(_tcslen(pszFileName) >= MAX_PATH)    .    

47、0;   goto END;        else    .        _tcscpy(m_szFileName,pszFileName);        /Check the file existing        HANDLE hdFile = CreateFile(

48、m_szFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);        if(hdFile = INVALID_HANDLE_VALUE)        .            /The file doesn't exist  &#

49、160;         goto END;                else        .            CloseHandle(hdFile);   

50、;                  / Initialize COM     if(CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK)    .        goto END;        / Get the i

51、nterface for DirectShow's GraphBuilder    if(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void *)&m_pGB) != S_OK)    .        goto END;        / Have the grap

52、h construct its the appropriate graph automatically    if(m_pGB->RenderFile(m_szFileName, NULL) != NOERROR)    .        goto END;            / QueryInterface for DirectShow interfaces

53、0;   if(m_pGB->QueryInterface(IID_IMediaControl, (void *)&m_pMC) != NOERROR)    .        goto END;        if(m_pGB->QueryInterface(IID_IMediaEventEx, (void *)&m_pME) != NOERROR)   

54、.        goto END;        if(m_pGB->QueryInterface(IID_IMediaSeeking, (void *)&m_pMS) != NOERROR)    .        goto END;            /

55、Query for video interfaces, which may not be relevant for audio files    if(m_pGB->QueryInterface(IID_IVideoWindow, (void *)&m_pVW) != NOERROR)    .        goto END;        if(m_pGB->QueryInterfa

56、ce(IID_IBasicVideo, (void *)&m_pBV) != NOERROR)    .        goto END;            / Query for audio interfaces, which may not be relevant for video-only files    if(m_pGB->QueryInterfa

57、ce(IID_IBasicAudio, (void *)&m_pBA) != NOERROR)    .        goto END;            / Is this an audio-only file (no video component)?    if (CheckVisibility() = TRUE)    .&#

58、160;       if(m_pVW->put_Owner(OAHWND)m_hWndVideo) != NOERROR)        .            goto END;                

59、;    if(m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN) != NOERROR)        .            goto END;              

60、      /Set play mode    SetDisplayMode(m_DispMode);            bResult = TRUE;END:        if(bResult = FALSE)    .        /Release the resou

61、rce        Close();        return bResult; /-/Description:/    This method sets an owning parent for the video window. /Parameters:/    hWnd : in Handle of new owner window. /-void CMedia:SetVideoWind

62、ow(HWND hWndVideo).    m_hWndVideo = hWndVideo; /-/Description:/    Check the file visibility/    When you call the function,you should call Open() before./Parameters:/    TRUE: Video/    FALSE: It's not the video /-

63、BOOL CMedia:CheckVisibility().            if (!m_pVW)    .        /No VideoWindow interface.  Assuming audio/MIDI file or unsupported video codec        return FALSE

64、;            if (!m_pBV)    .        /No BasicVideo interface.  Assuming audio/MIDI file or unsupported video codec.        return FALSE;     

65、60;          / If this is an audio-only clip, get_Visible() won't work.    /    / Also, if this video is encoded with an unsupported codec,    / we won't see any video, although the audio will work if it is 

66、   / of a supported format.    long lVisible;    if(m_pVW->get_Visible(&lVisible) != NOERROR)    .        return FALSE;                return T

67、RUE; /-/Description:/    Release the resource which opened in the Open()    /-void CMedia:Close().    / Relinquish ownership (IMPORTANT!) after hiding    if(m_pVW)    .        m_pVW->

68、;put_Visible(OAFALSE);        m_pVW->put_Owner(NULL);        if(m_pMC != NULL)    .        m_pMC->Release();        m_pMC = NULL;  

69、60;     if(m_pME != NULL)    .        m_pME->SetNotifyWindow(NULL,NULL,NULL);        m_pME->Release();        m_pME = NULL;       

70、; if(m_pMS != NULL)    .        m_pMS->Release();        m_pMS = NULL;        if(m_pBV != NULL)    .        m_pBV->Release();

71、0;       m_pBV = NULL;            if(m_pBA != NULL)    .        m_pBA->Release();        m_pBA = NULL;      

72、0;     if(m_pVW != NULL)    .        m_pVW->Release();        m_pVW = NULL;        if(m_pGB != NULL)    .        m_pG

73、B->Release();        m_pGB = NULL;        / Finished with COM    memset(m_szFileName,0,sizeof(m_szFileName);    CoUninitialize();/-/Description:/    Get the instance of object/-CMedia * C

74、Media:GetInstance().    if(m_pInstance = NULL)    .        m_pInstance = new CMedia();        return m_pInstance; /-/Description:/    Get the media file property./    Whe

75、n you call the function,you should call Open() before./-BOOL CMedia:GetMediaProperty(PMEDIAPROPERTY pOutProperty).    MEDIAPROPERTY prop = .0;    if(m_pBA = NULL | m_pBV = NULL)    .        return FALSE;   

76、;     /Get the audio property    m_pBA->get_Volume(&prop.lVolume);    m_pBA->get_Balance(&prop.lBalance);    /Get the video property    if(CheckVisibility() = TRUE)    .    

77、60;   m_pBV->get_BitRate(&prop.lBitRate);        m_pBV->GetVideoSize(&prop.lWidth,&prop.lHeight);        *pOutProperty = prop;    return TRUE;/-/Description:/    Set the display

78、 mode./    When you call the function,you should call Open() before./-BOOL CMedia:SetDisplayMode(DISPLAYMODE mode).    if(m_pVW = NULL)    .        return FALSE;        m_DispMode = mode;

79、60;   if(mode = DISP_FULLSCREEN)    .        m_pVW->put_FullScreenMode(OATRUE);        else    .        /Restore to the normal mode    &#

80、160;   m_pVW->put_FullScreenMode(OAFALSE);                RECT rcWnd = .0;        GetClientRect(m_hWndVideo,&rcWnd);        LONG lWndWidth = rc

81、Wnd.right - rcWnd.left;        LONG lWndHeight = rcWnd.bottom - rcWnd.top;        MEDIAPROPERTY prop = .0;        GetMediaProperty(&prop);        if(mode =

82、DISP_FIT | mode = DISP_NATIVE)        .            LONG lDispLeft,lDispTop,lDispWidth,lDispHeight;            if(mode = DISP_NATIVE && lWndWidth &g

83、t;= prop.lWidth && lWndHeight >= prop.lHeight)            .                lDispLeft = (lWndWidth - prop.lWidth) / 2;       

84、         lDispTop = (lWndHeight - prop.lHeight) / 2;                lDispWidth = prop.lWidth;                l

85、DispHeight = prop.lHeight;                        else            .           &#

86、160;    if(prop.lWidth * lWndHeight > lWndWidth * prop.lHeight)                .                    lDispWidth =

87、 lWndWidth;                                    lDispHeight = (LONG)(float)lDispWidth / (float)prop.lWidth * prop.lHeight); &#

88、160;                  lDispLeft = 0;                    lDispTop = (lWndHeight - lDispHeight) / 2;   

89、0;                                    else if(prop.lWidth * lWndHeight < lWndWidth * prop.lHeight)     

90、0;          .                    lDispHeight = lWndHeight;                 

91、   lDispWidth = (LONG)(float)lDispHeight / (float)prop.lHeight * prop.lWidth);                    lDispLeft = (lWndWidth - lDispWidth) / 2;         &#

92、160;          lDispTop = 0;                                else       

93、         .                    lDispWidth = lWndWidth;                   

94、60;                lDispHeight = lWndHeight;                    lDispLeft = 0;                    lDispTop = 0;   &#

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论