mciSendCommand对本地音乐的播放

mci的详细使用文档如下:http://www.360doc.com/content/12/0904/09/10660072_234175177.shtml

下面给出我对它进行的一个简单的封装,调用时只需要定义一个CPlayer的对象,然后调用Open()函数即可播放。

代码如下:

//Player.h
#pragma once
#include<windows.h>
#include<mmsystem.h>
#include<string>
#pragma comment(lib,"winmm.lib")
//命令参见:http://www.360doc.com/content/12/0904/09/10660072_234175177.shtml
typedef struct _MP3INFO //MP3信息的结构
{
	char Identify[3]; //TAG三个字母
					  //这里可以用来鉴别是不是文件信息内容
	char Title[31];   //歌曲名,30个字节
	char Artist[31];  //歌手名,30个字节
	char Album[31];   //所属唱片,30个字节
	char Year[5];	  //年,4个字节
	char Comment[29]; //注释,28个字节
	unsigned char reserved;  //保留位,	1个字节
	unsigned char reserved2; //保留位,1个字节
	unsigned char reserved3; //保留位,1个字节
} MP3INFO;
class CPlay
{
public:
	CPlay();
	CPlay(const std::string&);
	~CPlay();
	
	//对于播放新的歌曲则需要制定路径,若是暂停后需要恢复播放,则不需要添加参数
	void Play( std::string  f="");
	void Pause();
	void Close();
	int GetLength();//输出音乐总长,以ms为单位
	int GetCurrentPlayPos();//输出当前音乐播放位置
	void Go(int); //快进or快退,int代表跳转的间隔时间
	void SetFile(std::string);
	void SetHwnd(HWND);
	bool GetInfo(const std::string &path, MP3INFO& mp3info);
	//bool GetCurrentMusicInfo(MP3INFO& mp3info);
	void StartRecord();
	void EndRecord();
private:
	void Open();
	MCI_PLAY_PARMS playParms; //播放命令消息参数
	MCI_OPEN_PARMS openParms; //打开命令消息参数
	MCI_STATUS_PARMS statusParms; //状态命令消息参数
	MCI_SEEK_PARMS seekParms; // 定位命令消息参数
	MCI_RECORD_PARMS  recordParms; //录音命令消息参数
	MCI_SAVE_PARMS   saveParms; //保存命令消息参数
	MCI_GENERIC_PARMS genericParms;
	MCIDEVICEID wDeviceID; //设备ID,系统用ID来标识不同的设备,以保证命令发给正确的对象。

	HWND hWnd; //窗口句柄
	std::string filePath; //文件位置



};
#include"Player.h"
#include<algorithm>
using namespace std;

CPlay::CPlay() {}
CPlay::~CPlay() {}
CPlay::CPlay(const std::string &path) :filePath(path) { }
void CPlay::Open()
{
	Close();
	openParms.dwCallback = (DWORD)hWnd;
//	openParms.lpstrDeviceType = "avivideo";
	openParms.lpstrElementName = filePath.c_str();
	mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)(LPVOID)&openParms);
}
void CPlay::Play(  std::string  f)
{
	if (f != "")
	{
		filePath = f;
		Open();
	}
	mciSendCommand(wDeviceID, MCI_STOP, MCI_NOTIFY, (DWORD)(LPVOID)&playParms);
	wDeviceID = openParms.wDeviceID;
	mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&playParms);
}
void CPlay::Pause()
{
	mciSendCommand(wDeviceID, MCI_PAUSE, MCI_NOTIFY, (DWORD)(LPVOID)&playParms);
}
void CPlay::Close()
{
	mciSendCommand(wDeviceID, MCI_CLOSE, NULL, NULL);
}
int CPlay::GetLength()
{
	statusParms.dwItem = MCI_STATUS_LENGTH;
	DWORD dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,
		MCI_STATUS_ITEM, (DWORD)(LPVOID)&statusParms);
	int nTime = statusParms.dwReturn;
	return nTime;
}
int CPlay::GetCurrentPlayPos()
{
	statusParms.dwItem = MCI_STATUS_POSITION;
	DWORD dwReturn = mciSendCommand(wDeviceID, MCI_STATUS,
		MCI_STATUS_ITEM, (DWORD)(LPVOID)&statusParms);
	int nTime = statusParms.dwReturn;
	return nTime;
}

void CPlay::Go(int t)//跳转,t为跳转的时间,如 5 则前进5s,-5则后退5s
{
	//先获得当前播放位置
	int Time = GetCurrentPlayPos();
	//再调整时间
	seekParms.dwTo = Time + t*1000;
	DWORD dwReturn = mciSendCommand(wDeviceID, MCI_SEEK, MCI_WAIT | MCI_NOTIFY | MCI_TO, (DWORD)(LPVOID)&seekParms);
	mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID)&playParms);
}
void CPlay::SetFile(string file)
{
	filePath = file;
	Open();
}
void CPlay::SetHwnd(HWND hwnd)
{
	hWnd = hwnd;
}
bool CPlay::GetInfo(const std::string &path, MP3INFO& mp3info)
{
	if (path.empty())
		return false;
	FILE * fp;
	unsigned char mp3tag[128] = { 0 };

	fp = fopen(path.c_str(), "rb");
	if (NULL == fp)
	{
		//	QMessageBox::information(this, "提示", "打开文件失败");
		return false;
	}
	fseek(fp, -128, SEEK_END);
	fread(&mp3tag, 1, 128, fp);
	if (!((mp3tag[0] == 'T' || mp3tag[0] == 't')
		&& (mp3tag[1] == 'A' || mp3tag[1] == 'a')
		&& (mp3tag[2] == 'G' || mp3tag[0] == 'g')))
	{
		printf("mp3 file is error!!");
		fclose(fp);
		//QMessageBox::information(this, "提示", "解析当前文件失败");
		return false;
	}
	//获取Mp3信息
	memcpy((void *)mp3info.Identify, mp3tag, 3); //获得tag
	memcpy((void *)mp3info.Title, mp3tag + 3, 30); //获得歌名
	memcpy((void *)mp3info.Artist, mp3tag + 33, 30); //获得作者
	memcpy((void *)mp3info.Album, mp3tag + 63, 30); //获得唱片名
	memcpy((void *)mp3info.Year, mp3tag + 93, 4); //获得年
	memcpy((void *)mp3info.Comment, mp3tag + 97, 28); //获得注释
	memcpy((void *)&mp3info.reserved, mp3tag + 125, 1); //获得保留
	memcpy((void *)&mp3info.reserved2, mp3tag + 126, 1);
	memcpy((void *)&mp3info.reserved3, mp3tag + 127, 1);
	fclose(fp);
}
void CPlay::StartRecord() //录音
{
	//先停止当前播放
	mciSendCommand(wDeviceID, MCI_STOP, MCI_WAIT,
		(DWORD)(LPVOID)&playParms);
	mciSendCommand(wDeviceID, MCI_CLOSE, NULL, NULL);
	//再删除原来的录音文件
	try
	{
		DeleteFile("D:\\LuYin.wav");
	}
	catch(...)
	{
	//  删除出错处理
	//	cout << "\nDelete Error!!  Error Code: ";
	//	cerr << GetLastError() << endl;
		return;
	}
	//system("del D:\\LuYin.wav");
	//重新打开一个新的文件
	openParms.dwCallback = 0;
	openParms.wDeviceID = 0;
	openParms.lpstrDeviceType = "waveaudio"; //文件类型
	openParms.lpstrElementName = "";
	mciSendCommand(0, MCI_OPEN,
		MCI_WAIT | MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,
		(DWORD)(LPVOID)&openParms);
	//开始录音
	wDeviceID = openParms.wDeviceID;
	recordParms.dwFrom = 0;
	recordParms.dwTo = 0;
	recordParms.dwCallback = (DWORD)hWnd;
	mciSendCommand(wDeviceID, MCI_RECORD, MCI_NOTIFY,
		(DWORD)(LPVOID)&recordParms);
}
void CPlay::EndRecord()
{
	//退出循环后暂停录音
	mciSendCommand(wDeviceID, MCI_STOP, MCI_WAIT, (DWORD)(LPVOID)&genericParms);
	saveParms.dwCallback = 0;
	saveParms.lpfilename = "D:\\LuYin.wav";
	mciSendCommand(wDeviceID, MCI_SAVE, MCI_WAIT | MCI_SAVE_FILE, (DWORD)(LPVOID)&saveParms);//保存录音
	mciSendCommand(wDeviceID, MCI_CLOSE, NULL, NULL);//关闭设备
													 //暂停后播放录音
	filePath = "D:\\LuYin.wav";
	openParms.lpstrElementName = filePath.c_str();
	openParms.dwCallback = (DWORD)hWnd;
	mciSendCommand(wDeviceID, MCI_OPEN, MCI_WAIT | MCI_OPEN_ELEMENT, (DWORD)(LPVOID)&openParms);
	wDeviceID = openParms.wDeviceID;
	mciSendCommand(wDeviceID, MCI_PLAY, MCI_WAIT, (DWORD)(LPVOID)&playParms);
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值