標籤:音頻播放
最近一個小項目要用到音樂播放模組,於是翻了一下資料,發現windows環境下播放音頻檔案有MCI、DirectShow等幾種方式,當然也可以使用底層的api WaveOut播放。其中第一種方式最為簡單,程式僅需通過發送MCI命令即可控制媒體裝置,實現音頻檔案播放、暫停、停止等操作。其他兩種方式就比較繁瑣了,首先搭建DirectShow開發環境就比較周折,而使用WaveOut播放音頻,需要先解碼音頻以擷取pcm資料,然後才能播放。對於不涉及音頻資料處理、僅需播放音訊簡單使用情境,推薦使用MCI方式播放音頻檔案。MCI的用法思路可以概括為:先擷取裝置id,然後再向該裝置發送各種媒體控制命令,以實現媒體播放操作。下面為本人簡單封裝的MCI使用介面,頭、源檔案分別如下所示:
#ifndef _MUSIC_PLAYING_MANAGER_H#define _MUSIC_PLAYING_MANAGER_H#include <MMSystem.h>#pragma comment(lib, "winmm.lib")#define RESULT_ERROR -999class MusicPlayingManager{public:MusicPlayingManager(DWORD dwCallback);~MusicPlayingManager(void);private:DWORD m_dwCallback;MCIDEVICEID m_mciDeviceId;WCHAR m_szFileName[MAX_PATH];public:// 開啟音樂檔案void OpenMusicFile();// 播放/暫停/停止音樂void PlayMusic();void PauseMusic();void StopMusic();// 關閉音訊裝置void CloseDevice();};#endif
#include "StdAfx.h"#include "MusicPlayingManager.h"MusicPlayingManager::MusicPlayingManager(DWORD dwCallback){m_mciDeviceId = RESULT_ERROR;m_dwCallback = dwCallback;}MusicPlayingManager::~MusicPlayingManager(void){CloseDevice();}// 關閉裝置void MusicPlayingManager::CloseDevice(){if (m_mciDeviceId != RESULT_ERROR){mciSendCommand(m_mciDeviceId, MCI_CLOSE, NULL, NULL);m_mciDeviceId = RESULT_ERROR;}}// 開啟音樂檔案void MusicPlayingManager::OpenMusicFile(){// 選擇待播放的檔案CFileDialog dlg(TRUE, NULL, NULL,OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,L"音樂(*.mp3) | *.mp3||",NULL);dlg.m_ofn.lpstrTitle = L"請選擇歌曲檔案";if (dlg.DoModal() == IDOK){CString srcFileName = dlg.GetPathName();wcscpy_s(m_szFileName, srcFileName.GetBuffer(srcFileName.GetLength()));srcFileName.ReleaseBuffer();}// 先關閉裝置CloseDevice();// 再開啟裝置MCIERROR mciERR = ERROR_SUCCESS;MCI_OPEN_PARMS mciParams;ZeroMemory(&mciParams, sizeof(mciParams));mciParams.lpstrDeviceType = NULL;mciParams.lpstrElementName = m_szFileName;mciParams.dwCallback = m_dwCallback;mciERR = mciSendCommand(NULL, MCI_OPEN, MCI_NOTIFY | MCI_OPEN_ELEMENT, (DWORD_PTR)&mciParams);if (mciERR == ERROR_SUCCESS){m_mciDeviceId = mciParams.wDeviceID;MCI_SET_PARMS mciParams;ZeroMemory(&mciParams, sizeof(mciParams));mciParams.dwCallback = m_dwCallback;mciParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;mciSendCommand(m_mciDeviceId, MCI_SET, MCI_NOTIFY | MCI_SET_TIME_FORMAT, (DWORD_PTR)&mciParams);}else{m_mciDeviceId = RESULT_ERROR;AfxMessageBox(L"裝置開啟失敗");}}// 播放音樂void MusicPlayingManager::PlayMusic(){if (m_mciDeviceId != RESULT_ERROR){MCI_PLAY_PARMS mciParams;ZeroMemory(&mciParams, sizeof(mciParams));mciParams.dwCallback = m_dwCallback;mciSendCommand(m_mciDeviceId, MCI_PLAY, MCI_NOTIFY, (DWORD_PTR)&mciParams);}}// 暫停音樂void MusicPlayingManager::PauseMusic(){if (m_mciDeviceId != RESULT_ERROR){MCI_GENERIC_PARMS mciParams;ZeroMemory(&mciParams, sizeof(mciParams));mciParams.dwCallback = m_dwCallback;mciSendCommand(m_mciDeviceId, MCI_PAUSE, MCI_NOTIFY, (DWORD_PTR)&mciParams);}}// 停止音樂void MusicPlayingManager::StopMusic(){if (m_mciDeviceId != RESULT_ERROR){MCI_GENERIC_PARMS mciParams;ZeroMemory(&mciParams, sizeof(mciParams));mciParams.dwCallback = m_dwCallback;mciSendCommand(m_mciDeviceId, MCI_STOP, MCI_NOTIFY, (DWORD_PTR)&mciParams);mciSendCommand(m_mciDeviceId, MCI_SEEK, MCI_SEEK_TO_START, (DWORD_PTR)&mciParams);}} 用法很簡單,如下所示:
// 開啟檔案void CTestMusicPlayingDlg::OnBnClickedButtonOpenMusic(){m_pMusicPlayingMgr->OpenMusicFile();m_pMusicPlayingMgr->PlayMusic();}// 播放音樂void CTestMusicPlayingDlg::OnBnClickedButtonPlayMusic(){m_pMusicPlayingMgr->PlayMusic();}// 暫停音樂void CTestMusicPlayingDlg::OnBnClickedButtonPauseMusic(){m_pMusicPlayingMgr->PauseMusic();}// 停止音樂void CTestMusicPlayingDlg::OnBnClickedButtonStopMusic(){m_pMusicPlayingMgr->StopMusic();} 完整工程下載連結:http://download.csdn.net/detail/u013085897/7770721