VC下实现循环播放MP3,wma等音乐。
作者:遇见恒星
这几天在研究WINDOWS下的MCI编程。看了好多资料,基本上弄懂了一些。
以下是我写的代码:大家看看,希望对大家有帮助
提示:代码中的歌曲1.wma 和1.mp3 必须和程序放在一起,你也可以设置路径。如:你要播放D盘下的文件夹my program 里面的一首歌曲“千里之外.mp3”可以设置为:“d://my program//千里之外.mp3”,具体在程序中是改mciopen.lpstrElementName=” d://my program//千里之外.mp3”即可。
#include
#include
#include
#pragma comment(lib,"winmm.lib")
#include
#include
using namespace std;
void main()
{
bool first_song=true;//用这个first_song标记,如果为true,则播放第一首歌曲“1.wma”,为false则播放“1.mp3”
unsigned long wLength;//wLength用来 存储歌曲的长度,
MCI_STATUS_PARMS statusParms; //statusParms时来获取歌曲相关信息的数据
string song_name="1.wma";
MCI_OPEN_PARMS mciopen;//定义mciopen打开参数,任何歌曲都要先打开设备再播放
mciopen.lpstrElementName=song_name.c_str();//mciopen里面的lpstrElementName项是数据元素,放的是歌曲名
mciopen.lpstrDeviceType=0;//mciopen的lpstrDeviceType项是设备类型,放的是要用到的设备类型名,一般mp3和wma是用“mpegvideo”设备类型,这项也可以不写,系统会自动去搜索对应的类型名。
mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&mciopen);
first_song=false;//这个是为了调用播放下一首歌曲“1.mp3“设置为false值的。
UINT deviceID=mciopen.wDeviceID;//这个是获取打开后的设备的ID,下面将要用到这ID播放歌曲。
MCI_PLAY_PARMS mciplay;//定义播放参数mciplay
mciplay.dwFrom=0;//播放从头开始,from 0。
mciSendCommand(deviceID, MCI_PLAY,MCI_NOTIFY|MCI_FROM, (DWORD)&mciplay);//发送播放命令,其中用到了设备IDdeviceID
mciSendCommand(deviceID,MCI_SEEK,MCI_SEEK_TO_END,NULL); //这项发送的命令是获取歌曲的长度MCI_SEEK_TO_END
statusParms.dwItem=MCI_STATUS_POSITION; //获取信息statusParms.dwItem这项定义为MCI_STATUS_POSITION,表示让返回的statusParms.dwReturn是歌曲的长度值
mciSendCommand(deviceID,MCI_STATUS,MCI_STATUS_ITEM,(DWORD)(LPVOID)&statusParms); //这个命令是拾获取到的歌曲长度信息放到statusParms数据结构中,具体是statusParms.dwReturn
wLength=statusParms.dwReturn;//-----得到结束的长度,也就是当前播放的歌曲的长度。
printf("歌曲长度:%d/r",wLength);
char str[128];
int i=0;
while(1)
{
sprintf(str,"播放时间:/t%d",i);
printf("%s/r",str);//这个是输出播放的秒数,后面Sleep(1000)便是起到让程序休眠1000毫秒。而且“/r”是把输出信息放到本行开头,所以为什么我们看到的是不断的计数。就是把上一次输出信息覆盖了。
i++;//时间计数。
statusParms.dwItem=MCI_STATUS_POSITION;
mciSendCommand(deviceID,MCI_STATUS,MCI_STATUS_ITEM,(DWORD)(LPVOID)&statusParms);//这两项是为了获取当前播放歌曲的进度,存放在 statusParms.dwReturn数据项中。
if(int(statusParms.dwReturn>=wLength))
{//如果出现歌曲已经播放完,那么我们就要启动播放下一首歌曲了,在这里也可以让设备跳到歌曲开头,实现单首歌曲循环播放。
i=0;
mciSendCommand(deviceID,MCI_CLOSE,NULL,NULL); //先关闭当前播放设备,下面是重新打开新的设备。
wLength=0;//歌曲长度置为0;方便上面的判断语句。
if (!first_song)//通过first_song的值来决定要播放的下一首歌曲。
{
mciopen.lpstrElementName="1.wma";
first_song=true;//要把值置反,播放下一首歌曲要用到这个first_song来判断。
}
else
{
mciopen.lpstrElementName="1.mp3";
first_song=false;
}
mciopen.lpstrDeviceType=0;//不用指定设备类型名,系统会自动寻找,这是编程一种偷懒的表现,效率不错,呵呵。
mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&mciopen);//打开设备
deviceID=mciopen.wDeviceID;//获取打开设备的id,
mciSendCommand(deviceID,MCI_SEEK,MCI_SEEK_TO_END,NULL);//将位置定位到歌曲的结尾,为了得到歌曲的长度信息。
statusParms.dwItem=MCI_STATUS_POSITION;
mciSendCommand(deviceID,MCI_STATUS,MCI_STATUS_ITEM,(DWORD)(LPVOID)&statusParms); //得到了歌曲的长度信息,存放在statusParms.dwReturn中。
wLength=statusParms.dwReturn;//-----得到结束的长度, wLength是用来判断的,所以要把歌曲的长度信息赋值给它
//mciSendCommand(deviceID,MCI_SEEK,MCI_SEEK_TO_START,NULL); //这项就是让歌曲重新定位到开头,下面一句 mciplay.dwFrom=0也是实现一样的功能,这两个中选一个即可。
mciplay.dwFrom=0;//从歌曲开头开始播放,下面命令便是,如果不让歌曲重新定位到开头,下面发送命令的时候就已经到了歌曲的结尾了,自然就播放不了了。
mciSendCommand(deviceID, MCI_PLAY,MCI_NOTIFY|MCI_FROM, (DWORD)(LPVOID)&mciplay);//播放歌曲,这里用到的是 MCI_NOTIFY|MCI_FROM参数,MCI_NOTIFY是通知类型,MCI_FROM是从指定位置开始播放。
}
Sleep(1000);
}
}
//上面是用mciSendCommand实现循环播放或者多首歌曲播放。下面是通过mciSendString来实现单首歌曲循环播放,更简单。
/*
#include
#include
#include
#pragma comment(lib,"winmm.lib")
void main()
{
char buf[50];
MCIERROR mcierror;
mcierror=mciSendString("open 1.mp3 alias 设备1",buf,50,NULL);//命令"open 1.mp3 alias 设备1"也可以写成"open 1.mp3 type mpegvideo alias 设备1",不写的话系统会自己寻找对应设备。“alias 设备1”是另外起名为设备1,以后播放的时候直接用“设备1”即可。
if (mcierror)
{
mciGetErrorString(mcierror,buf,strlen(buf));
printf("%s",buf);
return;
}
mciSendString("play 设备1 repeat",buf,50,NULL);//单首歌曲循环播放。"play 设备1 repeat"
int time=0;
char time_all[60];
while (1)
{
sprintf(time_all,"播放时间:%d",time);
printf("%s/r",time_all);
time++;
Sleep(1000);
}
}*/