VC下实现循环播放MP3,wma等音乐

来源:互联网 发布:儿童学编程好吗 编辑:程序博客网 时间:2024/05/17 08:29

VC下实现循环播放MP3wma等音乐。

作者:遇见恒星

这几天在研究WINDOWS下的MCI编程。看了好多资料,基本上弄懂了一些。

以下是我写的代码:大家看看,希望对大家有帮助

提示:代码中的歌曲1.wma 1.mp3 必须和程序放在一起,你也可以设置路径。如:你要播放D盘下的文件夹my program 里面的一首歌曲“千里之外.mp3”可以设置为:“d://my program//千里之外.mp3,具体在程序中是改mciopen.lpstrElementName=” d://my program//千里之外.mp3即可。

 

#include <windows.h>

#include <stdio.h>

#include <Mmsystem.h>

#pragma comment(lib,"winmm.lib")

 

#include <string>

#include <iostream>

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;//mciopenlpstrDeviceType项是设备类型,放的是要用到的设备类型名,一般mp3wma是用“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 <windows.h>

#include <stdio.h>

#include <mmsystem.h>

#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);

         }

}*/