首页 > 代码库 > windows环境下音频文件播放

windows环境下音频文件播放

       最近一个小项目要用到音乐播放模块,于是翻了一下资料,发现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 -999

class 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