wince下用DirectShow播放音频和视频

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                //========================================================================
//TITLE:
//    wince下用DirectShow播放音频和视频
//AUTHOR:
//    norains
//DATE:
//    Monday  14-May-2007
//Environment:
//        WinCE 5.0
//========================================================================

        虽然网上关于wince下如何使用DirectShow播放多媒体文件的资料不多,但WinCE毕竟还属于windows,而桌面系统的DirectShow例子网上信手拈来,并且其中DirectShow的功能方法与之WinCE下差别不大,又本人实在没有信心比他们的轮子造得更为华丽,所以这篇文章就直接切入正题,不介绍DirectShow的结构功能,直接来看看怎么用吧.(其实还是自己懒惰的原因大一些,恩,不过这个和本文的主题没多大关系:-)).
      
        为了方便代码的移植,所以我将DirectShow的操作封装成CMedia类,只要直接调用该类,就可以相当简便地调用DirectShow来播放多媒体文件了
       
        好,闲话至此,我们以具体代码看看是如何:
         // 获取CMedia的实例
        CMedia  * m_pMedia  =  CMedia::GetInstance();
        
         // 设置播放的窗口
        m_pMedia -> SetVideoWindow(hWnd);
        
         // 打开媒体文件
        m_pMedia -> Open(TEXT( " A.AVI " ));
        
         // 播放
        m_pMedia -> Play();
        
        ...
        
         // 播放结束后,调用Close释放资源
        m_pMedia -> Open();

        没错,就是六行代码,就这么简单,可以顺利播放媒体文件.在这里要说一下的是,因为我们播放的是视频,需要有一个窗口显示,所以需要调用SetVideoWindow()函数来设置播放窗口.这个播放视频的窗口,可以是普通的窗口,也可以是Picture控件.当然咯,如果是播放音频文件,那么则完全可以无视这个函数.
       
        还有一个最值得注意的地方,当调用Open()成功之后,一定要调用Close()来释放资源,然后才能打开另一个媒体文件.否则,不释放的资源可能会导致很多莫名其妙的后果哦.
               
        等等,代码似乎还不完美,比如说,我想在文件播放之后再接着播放另外一个文件,那么我如何知道什么时候文件已经播放完毕了呢?这时候我们就需要请出SetNotifyWindow().
       
        该函数的作用是设置一个接受消息的窗口,当DirectShow有事件变更时,就会发送指定的消息到指定的窗口,原型如下:
       
        SetNotifyWindow(HWND hWnd, UINT wMsg,long lInstanceData)
       
        hWnd:接收消息的窗口句柄.
       
        wMsg:指定的自定义消息
       
        lInstanceData:消息的参数.
       
       
        那么,现在以接收一个视频播放结束事件的代码片段为例子:
         // 自定义一个消息
         #define  WM_GRAPHNOTIFY        (WM_USER + 13)
        
         // 设置接收消息窗口和消息
        m_pMedia -> SetVideoWindow(hWnd,WM_GRAPHNOTIFY,NULL);
        
        ...
        
         // 这个是消息循环函数
        LRESULT CMainWnd::WndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
         ... {
            switch(wMsg)
            ...{
            
                ...
            
                case WM_GRAPHNOTIFY:
                ...{
                    LONG evCode,evParam1,evParam2;
                    
                    //获取此时的DirectShow事件
                    if(m_pMedia->GetEvent(&evCode,&evParam1,&evParam2) == TRUE)
                    ...{
                        if(evCode == EC_COMPLETE)
                        ...{
                            MessageBox(NULL,TEXT("播放完毕"),TEXT(""),MB_OK);
                        }

                    }

                    return 0;
                }

            }

            
            ...
            
        }

       
        好了,知道播放完毕,就这么简单.恩,还很复杂..?呵呵,我觉得已经很简单了.
       
        文章的最后,让我们再来看看CMedia的其它几个有用的函数吧:
       
        CheckVisibility()
        描述:判断文件的种类
        当返回值为TRUE时,为视频文件;反之为只是音频文件.
       
       
        SetVolume(LONG lVolume, LONG lBalance)
        描述:设置音量.
        lVolume:设置音量的大小,范围为–10,000 到 0.
        lBalance:设置左右音量的均衡,范围是–10,000 到 10,000,默认是0.
       
       
        SetDisplayMode(DISPLAYMODE mode)
        描述:设置播放模式.
        DISP_FIT:按比例拉伸至视屏窗口.
        DISP_STRETCH:不按比例拉伸至视屏窗口.
        DISP_NATIVE:如果视频原本尺寸小于屏幕,则以原视频文件大小播放.否则,将和DISP_FIT相同
        DISP_FULLSCREEN:全屏


/**/ /        
// Media.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                    0
#define  MIN_VOLUME                    -10000

// The balance value
#define  MAX_BALANCE                    10000
#define  MIN_BALANCE                    -10000

// --------------------------------------------------------------------
// Enum value

enum  DISPLAYMODE
... {    
    //Fit to the play 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.
    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 property
typedef  struct
... {
    //The volume 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 .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;

    //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 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();
    void Close();
    BOOL CheckVisibility();
    void SetVideoWindow(HWND hWndVideo);
    BOOL Open(TCHAR * pszFileName);
    BOOL Stop();
    BOOL Pause();
    BOOL Play();
    virtual ~CMedia();

protected:


    CMedia();
    
    // Collection of interfaces
    IGraphBuilder *m_pGB;
    IMediaControl *m_pMC;
    IMediaEventEx *m_pME;
    IVideoWindow  *m_pVW;
    IBasicAudio   *m_pBA;
    IBasicVideo   *m_pBV;
    IMediaSeeking *m_pMS;

    TCHAR m_szFileName[MAX_PATH];
    HWND m_hWndVideo; //The window play video
    HWND m_hWndNotify; //The window notify
    BOOL 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 define

// Default play mode
#define  DEFAULT_DISPLAY_MODE        DISP_NATIVE

// ----------------------------------------------------------------------
// Initialize
CMedia  * 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_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;
        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 media file

    if(m_pMC == NULL)
    ...{
        return FALSE;
    }


        


    m_pMC->Run();

    return TRUE;
}





// ------------------------------------------------------------
// Description:
//     Pause. 
//     When you call the function,you should call Open() before.
//
// -------------------------------------------------------------
BOOL CMedia::Pause()
... {

    if(m_pMC == NULL)
    ...{
        return FALSE;
    }

    
    m_pMC->Pause();

    return 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;
    }


    
    m_pMC->Stop();    
    m_pMS->SetPositions(0, AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning);    
   
    return TRUE;
}





// --------------------------------------------------------------------------
// Description:
//     Open the media 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)
    ...{
        goto END;
    }

    else
    ...{
        _tcscpy(m_szFileName,pszFileName);

        //Check the file existing
        HANDLE hdFile = CreateFile(m_szFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
        if(hdFile == INVALID_HANDLE_VALUE)
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值