#include <vfw.h>
#pragma comment(lib,"vfw32.lib")
● 簡單實現
要實現一個播放器,首先要先創建一個MFC應用程序,例如一個基於Dialog的MFC程序。一個簡單實現的代碼以下:
HWND m_hAudio;
m_hAudio = MCIWndCreate( GetSafeHwnd(), AfxGetInstanceHandle(), WS_CHILD | MCIWNDF_NOMENU, _T("音樂.mp3") ); git
//m_hAudio = MCIWndCreate(m_hWnd,NULL,WS_CHILD | WS_CAPTION | WS_VISIBLE | MCIWNDF_SHOWPOS | MCIWNDF_SHOWNAME,filename);//能夠顯示播放器的小窗口。 程序員
if( MCIWndCanPlay( m_hAudio ) )
{
MCIWndPlay( m_hAudio );
}
這樣,就能夠播放出音樂來。支持的格式有wave files, midi files, AVI Video, cd audio, vcr, video disc, and others..,本身嘗試了一下,好像還能夠播放視頻中的音軌。編程
● 經常使用的API函數 數據結構
/** 窗口句柄所指對象是否可播放 */
MCIWndCanPlay(hwnd)
/** 窗口句柄所指對象是否可錄音 */
MCIWndCanRecord(hwnd)
/** 進行錄音 */
MCIWndRecord(hwnd)
/** 關閉窗口句柄 */
MCIWndClose(hwnd)
/** 播放窗口句柄所指對象 */
MCIWndPlay(hwnd)
/** 中止播放窗口句柄所指對象 */
MCIWndStop(hwnd)
/** 暫停播放窗口句柄所指對象 */
MCIWndPause(hwnd)
/** 恢復(暫停)播放窗口句柄所指對象 */
MCIWndResume(hwnd)
/** 移動播放進度至指定位置 */
MCIWndSeek(hwnd, lPos)
/** 移動播放進度至初始位置 */
MCIWndHome(hwnd)
/** 移動播放進度至結束位置 */
MCIWndEnd(hwnd)
/** 倒退播放窗口句柄所指對象 */
MCIWndPlayReverse(hwnd)
/** 從指定位置播放窗口句柄所指對象 */
MCIWndPlayFrom(hwnd, lPos)
/** 播放窗口句柄所指對象直至指定位置 */
MCIWndPlayTo(hwnd, lPos)
/** 播放窗口句柄所指對象的指定區間 */
MCIWndPlayFromTo(hwnd, lStart, lEnd)
/** 獲取當前的播放進度 */
MCIWndGetPosition(hwnd)
/** 獲取窗口句柄所指對象文件的長度 */
MCIWndGetLength(hwnd)
/** 銷燬窗口句柄 */
MCIWndDestroy(hwnd)
/** 設置播放音量 */
MCIWndSetVolume(hwnd,iVol)
/** 獲取當前播放音量 */
MCIWndGetVolume(hwnd)
/** 設置播放速率 */
MCIWndSetSpeed(hwnd,iSpeed)
/** 獲取播放速率 */
MCIWndGetSpeed(hwnd)
/** 設置是否循環播放 */
MCIWndSetRepeat(hwnd,f)
/** 獲取是否循環播放 */
MCIWndGetRepeat(hwndide
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////函數
MCIWnd的使用 Windows中提供了一個MCIWnd窗口類,能夠更加方便的在一個VC窗口中操做多媒體。 使用MCIWnd,源文件中須要包含頭文件 vfw.h,在Project->Settings->Link->Object/libray module中加入庫 vfw32.lib。 1、MCIWnd的建立 MCIWnd子窗口的建立可以使用MCIWndCreate函數: HWND MCIWndCreate( HWND hwndParent, //父窗口句柄 HINSTANCE hInstance, //應用程序的實例句柄 DWORD dwStyle, //顯示風格 LPSTR szFile //多媒體文件名 ); 返回的HWND能夠保存下來,以供之後使用,也可不保存。 該函數會在其父窗口上建立一個子窗口,相似於建立一個控間如按扭或列表框等。 該子窗口會佔據父窗口必定空間,可帶有播放按鈕、進度條、菜單按鈕等。 圖3.3.1 MCIWnd子窗口 示例: (1)建一個多文檔的MFC應用程序。 (2)在View類的頭文件中加入變量: HWND m_mciWnd; (3)在View類中用ClassWizard重載OnInitialUpdate函數。 (4)在此函數中加入代碼: m_mciWnd=MCIWndCreate(m_hWnd, AfxGetInstanceHandle(), MCIWNDF_SHOWALL | MCIWNDF_RECORD, GetDocument()->GetPathName()); 這裏,m_hWnd爲此View窗口的HWND, AfxGetInstanceHandle()可取得本應用程序的實例句柄, MCIWNDF_flag們決定了子窗口中是否要加入播放按鈕、錄音按鈕、菜單按鈕、進度條等控件, GetDocument()->GetPathName()則可得到經過打開文件對話框取得的文件名。 (5)編譯運行。 (6)在運行的程序中已經能夠任意打開一個多媒體文件進行播放。例如 .wav、.avi、.mid文件。 2、MCIWnd的使用 若是在MCIWnd子窗口中有播放按鈕、錄音按鈕、菜單按鈕、進度條等控件,能夠經過它們操做多媒體。 若是象上例同樣保存了MCIWndCreate函數返回的HWND,則無論子窗口中是否有控件,均可經過MCIWndxxxx函數操做多媒體。 (7)在上面的程序中加入ID爲 ID_NEW、ID_OPEN、ID_PLAY、ID_PLAYREVERSE、ID_RECORD、ID_SAVE、ID_STOP、ID_CLOSE 的菜單項或Toolbar按鈕。 (8)在 ID_NEW 的消息響應函數中加入: MCIWndNew(m_mciWnd,"waveaudio"); MCIWnd子窗口能夠創建一個新的音頻多媒體文件。 (9)在 ID_OPEN 的消息響應函數中加入: MCIWndOpen(m_mciWnd,"c:\\MyWav.wav",0); MCIWnd子窗口能夠打開一個已存在的多媒體文件。 (10)在 ID_PLAY 的消息響應函數中加入: MCIWndPlay(m_mciWnd); MCIWnd子窗口能夠播放多媒體文件。 (11)在 ID_PLAYREVERSE 的消息響應函數中加入: MCIWndPlayReverse(m_mciWnd); MCIWnd子窗口能夠倒着播放視頻多媒體文件。 (12)在 ID_RECORD 的消息響應函數中加入: MCIWndRecord(m_mciWnd); MCIWnd子窗口能夠錄製音頻多媒體文件。 (13)在 ID_SAVE 的消息響應函數中加入: MCIWndSave(m_mciWnd,"c:\\MyWav.wav"); MCIWnd子窗口能夠保存已錄製的音頻多媒體文件。 (14)在 ID_STOP 的消息響應函數中加入: MCIWndStop(m_mciWnd); MCIWnd子窗口能夠中止正在播放或錄製的多媒體文件。 (15)在 ID_CLOSE 的消息響應函數中加入: MCIWndClose(m_mciWnd); MCIWnd子窗口能夠關閉當前的多媒體文件,若要再使用,必須從新打開。 (16)編譯運行。 /////////////////////////////////////////////////////////////////////////////////////////////// 如何響應消息: 建立播放播放窗口時使用 MCIWNDF_NOTIFYMODE 屬性。 而後作一個消息映射。 ON_MESSAGE(MCIWNDM_NOTIFYMODE, OnMCINotify) 而後在OnMCINotify()函數中判斷是否收到中止消息(播完就會收到),而後播放下一個。 相關代碼以下: .h中 afx_msg void OnMCINotify(WPARAM wParam,LPARAM lParam); .cpp中 ON_MESSAGE(MCIWNDM_NOTIFYMODE, OnMCINotify) BOOL MyVideoDlg::OnInitDialog() { ...... m_hWndVideo = MCIWndCreate( this-> GetSafeHwnd(), AfxGetInstanceHandle(), WS_CHILD|WS_VISIBLE|WS_BORDER| MCIWNDF_NOPLAYBAR | MCIWNDF_NOMENU|MCIWNDF_NOTIFYMODE, m_sFileName.GetBuffer(10)); MCIWndPlay(m_hWndVideo); ...... } void MyVideoDlg::OnMCINotify(WPARAM wParam,LPARAM lParam) { if(lParam==MCI_MODE_STOP) { 播放下一個 } } /////////////////////////////////////////////////////////////////////////////////////////////// MCI(媒體控制接口)相關知識 MCI(Media Control Interface)媒體控制接口是MircroSoft提供的一組多媒體設備和文件的標準接口,它的好處是能夠方便地控制絕大多數多媒體設備包括音頻、視頻、影碟、錄像等多媒體設備,而不須要知道它們的內部工做情況。可是古人云:成也蕭何,敗也蕭何。MCI雖然看上去高大全,但對於一些高級應用來講,它是遠遠不夠的。 MCI的控制方式: 通常說來,程序員使用兩個函數就能夠與MCI打交道了: MCIERROR mciSendCommand(MCIDEVICEID wDeviceID, UINT uMsg, DWORD dwFlags, DWORD dwParam); 命令字符串方式,用接近於平常生活用語的方式發送控制命令,適用於高級編程如VB、TOOLBOOK等。 MCIERROR mciSendString(LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback); 命令消息方式,用專業語法發送控制消息,適用於VC等語言編程,此方式直接與MCI設備打交道。 對於mciSendCommand,第一個參數指定了設備標識,這個標識會在程序員打開MCI設備時由系統提供。第二個參數指定將如何控制設備,詳細請查閱後面「MCI指令」一欄。第三個參數爲訪問標識,第四個參數通常是一個數據結構,標識程序在訪問MCI時要的一些信息。有關詳細資料,請查閱本光盤配套書。 對於mciSendString,第一個參數爲一串控制字符串,返回信息由系統填入第二個參數,第三個參數指明返回信息的最大長度,若對MCI裝置設定了"notify"標誌則須要在第四個參數填上返回窗口句柄。 舉例: mciSendCommand(DeviceID, MCI_CLOSE, NULL, NULL); // 關閉一個MCI設備 mciSendString("open aaa.avi", 0, 0, 0); // 打開文件"aaa.avi" MCI的設備類型: 設備描述描述字符串說明 MCI_ALL_DEVICE_ID全部設備 MCI_DEVTYPE_ANIMATIONAnimation動畫設備 MCI_DEVTYPE_CD_AUDIOCdaudioCD音頻 MCI_DEVTYPE_DATDat數字音頻 MCI_DEVTYPE_DIGITAL_VIDEODigitalvideo數字視頻 MCI_DEVTYPE_OTHEROther未定義設備 MCI_DEVTYPE_OVERLAYOverlay重疊視頻 MCI_DEVTYPE_SCANNERScanner掃描儀 MCI_DEVTYPE_SEQUENCERSequencer MIDI序列器 MCI_DEVTYPE_VCRVcr合式錄像機 MCI_DEVTYPE_VIDEODISCVideodisc激光視盤 MCI_DEVTYPE_WAVEFORM_AUDIOwaveaudio Wave音頻 對於未在上面定義的MCI設備,用戶可查看system.ini文件中[mci]部分,例如: [mci] cdaudio=mcicda.drv sequencer=mciseq.drv waveaudio=mciwave.drv avivideo=mciavi.drv videodisc=mcipionr.drv vcr=mcivisca.drv ActiveMovie=mciqtz.drv QTWVideo=mciqtw.drv MPEGVideo=C:\PROGRA~1\XING\XINGMP~1\xmdrv95.dll 其中最後兩句分別指明瞭Apple的QuickTime設備,設備名爲"QTWVidio"、MPEG影像設備,設備名爲"MPEGVideo"。 //------------------------------ // 廣告時間: // 歡迎訪問 C++ Builder 研究 - http://www.ccrun.com //------------------------------ 在MCI編程中,既能夠將設備描述當設備名,也能夠將描述字符串當設備名,一個極端偷懶的辦法是程序員不要在程序中指定設備名,Windows將自動根據文件擴展名識別設備類型。 舉個例子來講,打開一個多媒體文件有如下三種方式: [1]:自動識別:打開一個"WAV"文件 MCI_OPEN_PARMS mciOpen; mciOpen.lpstrDeviceType = 0; mciOpen.lpstrElementName = "aaa.wav"; mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&mciOpen); [2]:指定設備描述:打開CD播放器 MCI_OPEN_PARMS mciOpen; mciOpen.lpstrDeviceType = (LPSTR)MCI_DEVTYPE_CD_AUDIO ; mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID, (DWORD)&mciOpen); [3]:指定描述字符串: 打開一個AVI文件 MCI_OPEN_PARMS mciOpen; mciOpen.lpstrDeviceType = "avivideo"; mciOpen.lpstrElementName = "aaa.avi"; mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)&mciOpen); 注意三種打開方式中,函數第三個參數的區別,後面會講到這種區別。 MCI指令 MCI_BREAK設置中斷鍵,缺省是」CTRL+BREAK" MCI_CAPTURE抓取當前幀並存入指定文件,僅用於數字視頻 MCI_CLOSE關閉設備 MCI_CONFIGURE彈出配置對話框,僅用於數字視頻 MCI_COPY拷貝數據至剪貼板 MCI_CUE延時播放或錄音 MCI_CUT刪除數據 MCI_DELETE刪除數據 MCI_ESCAPE僅用於激光視頻 MCI_FREEZE將顯示定格 MCI_GETDEVCAPS獲取設備信息 MCI_INDEX當前屏幕顯示與否,僅用於VCR設備 MCI_INFO獲取字符串信息 MCI_LIST獲取輸入設備數量,支持數字視頻和VCR設備 MCI_LOAD裝入一個文件 MCI_MARK取消或作一個記號,與MCI_SEEK配套 MCI_MARK取消或作一個記號,與MCI_SEEK配套 MCI_MONITOR爲數字視頻指定報告設備 MCI_OPEN打開設備 MCI_PASTE粘帖數據 MCI_PAUSE暫停當前動做 MCI_PLAY播放 MCI_PUT設置源、目的和邊框矩形 MCI_QUALITY定義設備缺省質量 MCI_RECORD開始錄製 MCI_RESERVE分配硬盤空間 MCI_RESTORE拷貝一個bmp文件至幀緩衝 MCI_RESUME使一個暫停設備從新啓動 MCI_SAVE保存數據 MCI_SEEK更改媒體位置 MCI_SET設置設備信息 MCI_SETAUDIO設置音量 MCI_SETTIMECODE啓用或取消VCR設備的時間碼 MCI_SETTUNER設置VCR設備頻道 MCI_SETVIDEO設置video參數 MCI_SIGNAL在工做區上設置指定空間 MCI_STATUS獲取設備信息 MCI_STEP使播放設備跳幀 MCI_STOP中止播放 MCI_SYSINFO返回MCI設備信息 MCI_UNDO取消操做 MCI_UNFREEZE使使用MCI_UNFREEZE的視頻緩衝區恢復運動 MCI_UPDATE更新顯示區域 MCI_WHERE獲取設備裁減矩形 MCI_WINDOW指定圖形設備窗口和窗口特性 其中比較經常使用的指令有MCI_OPEN、MCI_CLOSE、MCI_PLAY、MCI_STOP、MCI_PAUSE、MCI_STATUS等等。