⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 media.cpp

📁 本源码是关于在wince下如何使用directx播放多媒体文件的小程序
💻 CPP
字号:
///////////////////////////////////////////////////////////////////////
// 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)
         {
            //The file doesn't exist
            goto END;
        }
        else
         {
            CloseHandle(hdFile);
        }
    }

    



    // Initialize COM 
    if(CoInitializeEx(NULL, COINIT_MULTITHREADED) != S_OK)
     {
        goto END;
    }

    // Get the interface for DirectShow's GraphBuilder
    if(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGB) != S_OK)
     {
        goto END;
    }


    // Have the graph construct its the appropriate graph automatically
    if(m_pGB->RenderFile(m_szFileName, NULL) != NOERROR)
     {
        goto END;
    }
    

    // QueryInterface for DirectShow interfaces
    if(m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC) != NOERROR)
     {
        goto END;
    }
    if(m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME) != NOERROR)
     {
        goto END;
    }
    if(m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&m_pMS) != NOERROR)
     {
        goto END;
    }
    

    // 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->QueryInterface(IID_IBasicVideo, (void **)&m_pBV) != NOERROR)
     {
        goto END;
    }
    

    // Query for audio interfaces, which may not be relevant for video-only files
    if(m_pGB->QueryInterface(IID_IBasicAudio, (void **)&m_pBA) != NOERROR)
     {
        goto END;
    }
    
    // Is this an audio-only file (no video component)?
    if (CheckVisibility() == TRUE)
     {
        if(m_pVW->put_Owner((OAHWND)m_hWndVideo) != NOERROR)
         {
            goto END;
        }

    
        if(m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN) != NOERROR)
         {
            goto END;
        }
    }
    


    //Set play mode
    SetDisplayMode(m_DispMode);
    
    
    bResult = TRUE;

END:    

    if(bResult == FALSE)
     {
        //Release the resource
        Close();
    }

    return bResult;
}




//------------------------------------------------------------
//Description:
//    This method sets an owning parent for the video window. 
//
//Parameters:
//    hWnd : [in] Handle of new owner window. 
//
//----------------------------------------------------------
void CMedia::SetVideoWindow(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 
//
//------------------------------------------------------------
BOOL CMedia::CheckVisibility()
 {
    
    
    if (!m_pVW)
     {
        //No VideoWindow interface.  Assuming audio/MIDI file or unsupported video codec
        return FALSE;
    }
    
    if (!m_pBV)
     {
        //No BasicVideo interface.  Assuming audio/MIDI file or unsupported video codec.
        return FALSE;
    }
    
    
    // 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
    // of a supported format.
    long lVisible;
    if(m_pVW->get_Visible(&lVisible) != NOERROR)
     {
        return FALSE;
    }
    
    
    return TRUE;
}




//------------------------------------------------------------
//Description:
//    Release the resource which opened in the Open()    
//
//------------------------------------------------------------
void CMedia::Close()
 {

    // Relinquish ownership (IMPORTANT!) after hiding
    if(m_pVW)
     {
        m_pVW->put_Visible(OAFALSE);
        m_pVW->put_Owner(NULL);
    }

    if(m_pMC != NULL)
     {
        m_pMC->Release();
        m_pMC = NULL;
    }

    if(m_pME != NULL)
     {
        m_pME->SetNotifyWindow(NULL,NULL,NULL);

        m_pME->Release();
        m_pME = NULL;
    }

    if(m_pMS != NULL)
     {
        m_pMS->Release();
        m_pMS = NULL;
    }

    if(m_pBV != NULL)
     {
        m_pBV->Release();
        m_pBV = NULL;
    }
    
    if(m_pBA != NULL)
     {
        m_pBA->Release();
        m_pBA = NULL;
    }
    
    if(m_pVW != NULL)
     {
        m_pVW->Release();
        m_pVW = NULL;
    }

    if(m_pGB != NULL)
     {
        m_pGB->Release();
        m_pGB = NULL;
    }

    // Finished with COM
    memset(m_szFileName,0,sizeof(m_szFileName));


    CoUninitialize();
}


//------------------------------------------------------------
//Description:
//    Get the instance of object
//
//------------------------------------------------------------
CMedia * CMedia::GetInstance()
 {
    if(m_pInstance == NULL)
     {
        m_pInstance = new CMedia();
    }

    return m_pInstance;
}




//------------------------------------------------------------
//Description:
//    Get the media file property.
//    When 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;
    }


    //Get the audio property
    m_pBA->get_Volume(&prop.lVolume);
    m_pBA->get_Balance(&prop.lBalance);


    //Get the video property
    if(CheckVisibility() == TRUE)
     {
        m_pBV->get_BitRate(&prop.lBitRate);
        m_pBV->GetVideoSize(&prop.lWidth,&prop.lHeight);

    }

    *pOutProperty = prop;


    return TRUE;
}


//------------------------------------------------------------
//Description:
//    Set the display 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;

    if(mode == DISP_FULLSCREEN)
     {
        m_pVW->put_FullScreenMode(OATRUE);
    }
    else
     {
        //Restore to the normal mode
        m_pVW->put_FullScreenMode(OAFALSE);
        
        RECT rcWnd =  {0};
        GetClientRect(m_hWndVideo,&rcWnd);
        LONG lWndWidth = rcWnd.right - rcWnd.left;
        LONG lWndHeight = rcWnd.bottom - rcWnd.top;

        MEDIAPROPERTY prop =  {0};
        GetMediaProperty(&prop);


        if(mode == DISP_FIT || mode == DISP_NATIVE)
         {
            LONG lDispLeft,lDispTop,lDispWidth,lDispHeight;

            if(mode == DISP_NATIVE && lWndWidth >= prop.lWidth && lWndHeight >= prop.lHeight)
             {
                lDispLeft = (lWndWidth - prop.lWidth) / 2;
                lDispTop = (lWndHeight - prop.lHeight) / 2;
                lDispWidth = prop.lWidth;
                lDispHeight = prop.lHeight;
            }
            else
             {
                if(prop.lWidth * lWndHeight > lWndWidth * prop.lHeight)
                 {
                    lDispWidth = lWndWidth;                
                    lDispHeight = (LONG)((float)lDispWidth / (float)prop.lWidth * prop.lHeight);
                    lDispLeft = 0;
                    lDispTop = (lWndHeight - lDispHeight) / 2;        
                }
                else if(prop.lWidth * lWndHeight < lWndWidth * prop.lHeight)
                 {
                    lDispHeight = lWndHeight;
                    lDispWidth = (LONG)((float)lDispHeight / (float)prop.lHeight * prop.lWidth);
                    lDispLeft = (lWndWidth - lDispWidth) / 2;
                    lDispTop = 0;
                }
                else
                 {
                    lDispWidth = lWndWidth;                
                    lDispHeight = lWndHeight;
                    lDispLeft = 0;
                    lDispTop = 0;
                }
            }

            



            m_pVW->put_Left(lDispLeft);
            m_pVW->put_Top(lDispTop);
            m_pVW->put_Width(lDispWidth);
            m_pVW->put_Height(lDispHeight);
        }
        else if(mode == DISP_STRETCH)
         {

            m_pVW->put_Left(0);
            m_pVW->put_Top(0);
            m_pVW->put_Width(lWndWidth);
            m_pVW->put_Height(lWndHeight);
        }
    
    }



    return TRUE;
}


//------------------------------------------------------------
//Description:
//    Set the volume.
//    When you call the function,you should call Open() before.
//
//Parameters:
//    lVolume:[in] The volume (amplitude) of the audio signal. 
//            Range is –10,000 to 0.
//    lBalance:[in]  The balance for the audio signal. Default value is 0.
//            The value from –10,000 to 10,000 indicating the stereo balance.
//
//------------------------------------------------------------
BOOL CMedia::SetVolume(LONG lVolume, LONG lBalance)
 {
    if(m_pBA == NULL)
     {
        return FALSE;
    }

    if(lVolume < MIN_VOLUME && lVolume > MAX_VOLUME && lBalance < MIN_BALANCE && lBalance > MAX_BALANCE)
     {
        return FALSE;
    }

    m_pBA->put_Volume(lVolume);
    m_pBA->put_Balance(lBalance);

    return TRUE;
}




//----------------------------------------------------------------------
//Description:
//    Registers a window that will handle messages when a specified event occurs.
//
//Parameters:
//    hWnd:[in] Handle of window to notify. Pass NULL to stop notification. 
//    wMsg:[in] Window message to be passed as the notification. 
//    lInstanceData:[in] Value (instance data) to be passed as the lParam parameter for the lMsg message.
//
//-----------------------------------------------------------------------------
BOOL CMedia::SetNotifyWindow(HWND hWnd, UINT wMsg,long lInstanceData)
 {
    if(m_pME == NULL)
     {
        return FALSE;
    }

    m_pME->SetNotifyWindow((OAHWND)hWnd,wMsg,lInstanceData);

    return TRUE;
}


//----------------------------------------------------------------------
//Description:
//    This method retrieves the notification event. 
//
//-----------------------------------------------------------------------
BOOL CMedia::GetEvent(LONG *plEvCode, LONG *plParam1, LONG *plParam2)
 {
    if(m_pME == NULL)
     {
        return FALSE;
    }

    LONG evCode, evParam1, evParam2;    

    if(m_pME->GetEvent(&evCode, &evParam1, &evParam2, 0) == NOERROR)
     {
        *plEvCode = evCode;
        *plParam1 = evParam1;
        *plParam2 = evParam2;

        // Spin through the events
        m_pME->FreeEventParams(evCode, evParam1, evParam2);        
    }
    else
     {
        return FALSE;
    }
    

    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -