新网创想网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
我最近在用MCI函数做音乐播放器,我也遇到了类似的问题,我发现对于恒定码率的mp3文件,可以得到正确的结果,但是对于可变码率的MP3,得到的长度是不正确的,应该是MCI本身的问题。而且我通过观察发现,对于可变码率的音频文件,MCI识别的长度误差满足下面的关系:MCI识别的长度/实际长度≈比特率/128。
创新互联专注为客户提供全方位的互联网综合服务,包含不限于网站设计、成都网站制作、鹤山网络推广、小程序设计、鹤山网络营销、鹤山企业策划、鹤山品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联为所有大学生创业者提供鹤山建站搭建服务,24小时服务热线:13518219792,官方网址:www.cdcxhl.com
API函数 mciSendString
mciSendString("setaudio mp3 volume to 50",0,0,0);
但是请注意:上面那个mp3是Alias即别名,别名是有你open文件的时候指定的哦!
1.slider的使用可以查看MSDN
2.暂停和播放的时候,加个变量记录歌曲播放的进度。
加个SND_LOOP循环就可以了呀!
假如你想在背景乐前还有其他很多音乐的话,建议你使用VFW,方便简单
可以同时播放N多音乐,下面时以前写的一个mp3播放器的,见笑呵呵!
支持wav,mid,mp3,wma等音频格式,如果音乐播放的时候继续打开,前面的音乐不会听掉,而是叠加在一起,实现你的背景音乐,MCIWnd开头的就是VFW的函数,使用很简单,估计你一看函数名就知道作用了!
void CMiniMp3Dlg::OnBtn1() //打开
{
// TODO: Add your control notification handler code here
m_Audio = NULL;
if(m_Audio == NULL)
{
CFileDialog mp3(TRUE,NULL,NULL,OFN_HIDEREADONLY,"MP3 WMA Files (*.mp3 *.WMA)|*.mp3;*.wma|");
if(mp3.DoModal() == IDOK)
{
m_Path = mp3.GetPathName();
m_Audio = MCIWndCreate(this-GetSafeHwnd(),
AfxGetInstanceHandle(),
WS_CHILD|MCIWNDF_NOMENU,m_Path);
long snd =MCIWndGetLength(m_Audio);//得到文件长度
m_sInfo=TimeFormat(snd);
//m_sInfo.Format("%d",snd);
UpdateData(FALSE);
m_cSliderMusic.SetRangeMin(0);
m_cSliderMusic.SetRangeMax(snd/1000);
}
}
}
void CMiniMp3Dlg::OnBtn2() //播放
{
// TODO: Add your control notification handler code here
MCIWndHome(m_Audio);
MCIWndPlay(m_Audio);
SetTimer(0,1000,NULL);
nP=0;
}
void CMiniMp3Dlg::OnBtn3() //暂停,恢复
{
//long snd =MCIWndGetPosition(m_Audio);
//m_sInfo=TimeFormat(snd);
if (GetMode(m_Audio)==1)
MCIWndPause(m_Audio);
else
if (GetMode(m_Audio)==2)
MCIWndResume(m_Audio);
}
void CMiniMp3Dlg::OnOK() //销毁
{
// TODO: Add extra validation here
MCIWndDestroy(m_Audio);
CDialog::OnOK();
}
void CMiniMp3Dlg::OnBtn4() //停止
{
// TODO: Add your control notification handler code here
MCIWndStop(m_Audio);
}
本次的实训的mp3播放器主要涉及到的内容如下:
MCI API :负责音乐的播放,暂停,继续,停止等功能
2)链表的构建
3)文件读取问题
文件存储有很多种方式,将数据写入文件时可以以空格或者回车为结束。
在读取时,不管是硬fscanf还是gets()进行读取,都要注意一点,以gets为例,gets是读到回车符号结尾,但是回车符号会被读取进去。也就是说,需要将读取到的字符串进行处理,最后一个字符要置为‘0’;一定要注意这个问题。
还有一个_finddata这个结构体的问题:
此外由于在win10系统下不知道是我个人原因还是大部分人都有的的问题在编译时findnext会报错, 因为_findnext()返回类型为intptr_t而非long型,从“intptr_t”转换到“long”丢失了数据。只需要把一般写的:
long _findfirst( char *filespec, struct _finddata_t fileinfo );
返回值:
如果查找成功的话,将返回一个long型的唯一的查找用的句柄(就是一个唯一编号)。这个句柄将在_findnext函数中被使用。若失败,则返回-1。
参数:
filespec:标明文件的字符串,可支持通配符。比如: .c,则表示当前文件夹下的所有后缀为C的文件。
fileinfo :这里就是用来存放文件信息的结构体的指针。这个结构体必须在调用此函数前声明,不过不用初始化,只要分配了内存空间就可以了。
函数成功后,函数会把找到的文件的信息放入这个结构体中。
int _findnext( long handle, struct _finddata_t *fileinfo );
返回值:
若成功返回0,否则返回-1。
参数:
handle:即由_findfirst函数返回回来的句柄。
fileinfo:文件信息结构体的指针。找到文件后,函数将该文件信息放入此结构体中。
int _findclose( long handle );
返回值:成功返回0,失败返回-1。
参数: handle :_findfirst函数返回回来的句柄
一下为一个简化的版本主要是文件操作:
function.h
function.c
main.c
可以使用PlaySound()函数播放wav声音,该函数原型位于windows.h中,
函数原型为:
BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound);
参数pszSound是指定了要播放声音的字符串,该参数可以是WAVE文件的名字,或是WAV资源的名字,或是内存中声音数据的指针,或是在系统注册表WIN.INI中定义的系统事件声音。如果该参数为NULL则停止正在播放的声音。
参数hmod是应用程序的实例句柄,当播放WAV资源时要用到该参数,否则它必须为NULL。
参数fdwSound是标志的组合,各种可选的标志及意义如下所示。若成功则函数返回TRUE,否则返回FALSE。
播放标志以及含义:
SND_APPLICATION
用应用程序指定的关联来播放声音。
SND_ALIAS
pszSound参数指定了注册表或WIN.INI中的系统事件的别名。
SND_ALIAS_ID
pszSound参数指定了预定义的声音标识符。
SND_ASYNC
用异步方式播放声音,PlaySound函数在开始播放后立即返回。
SND_FILENAME
pszSound参数指定了WAVE文件名。
SND_LOOP
重复播放声音,必须与SND_ASYNC标志一块使用。
SND_MEMORY
播放载入到内存中的声音,此时pszSound是指向声音数据的指针。
SND_NODEFAULT
不播放缺省声音,若无此标志,则PlaySound在没找到声音时会播放缺省声音。
SND_NOSTOP
PlaySound不打断原来的声音播出并立即返回FALSE。
SND_NOWAIT
如果驱动程序正忙则函数就不播放声音并立即返回。
SND_PURGE
停止所有与调用任务有关的声音。若参数pszSound为NULL,就停止所有的声音,否则,停止pszSound指定的声音。
SND_RESOURCE
pszSound参数是WAVE资源的标识符,这时要用到hmod参数。
SND_SYNC
同步播放声音,在播放完后PlaySound函数才返回。
************************************************************
例如我想播放在C:\WINDOWS\Media目录中的 Windows XP 启动.wav 文件
程序如下:
#include windows.h
#include stdlib.h
int main(int argc, char* argv[])
{
PlaySound("C:\\WINDOWS\\Media\\Windows XP 启动.wav", NULL, SND_FILENAME | SND_ASYNC);
system("pause");
return 0;
}