我最近在用MCI函數(shù)做音樂播放器,我也遇到了類似的問題,我發(fā)現(xiàn)對(duì)于恒定碼率的mp3文件,可以得到正確的結(jié)果,但是對(duì)于可變碼率的MP3,得到的長(zhǎng)度是不正確的,應(yīng)該是MCI本身的問題。而且我通過觀察發(fā)現(xiàn),對(duì)于可變碼率的音頻文件,MCI識(shí)別的長(zhǎng)度誤差滿足下面的關(guān)系:MCI識(shí)別的長(zhǎng)度/實(shí)際長(zhǎng)度≈比特率/128。
創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、鶴山網(wǎng)絡(luò)推廣、小程序設(shè)計(jì)、鶴山網(wǎng)絡(luò)營(yíng)銷、鶴山企業(yè)策劃、鶴山品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供鶴山建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com
API函數(shù) mciSendString
mciSendString("setaudio mp3 volume to 50",0,0,0);
但是請(qǐng)注意:上面那個(gè)mp3是Alias即別名,別名是有你open文件的時(shí)候指定的哦!
1.slider的使用可以查看MSDN
2.暫停和播放的時(shí)候,加個(gè)變量記錄歌曲播放的進(jìn)度。
加個(gè)SND_LOOP循環(huán)就可以了呀!
假如你想在背景樂前還有其他很多音樂的話,建議你使用VFW,方便簡(jiǎn)單
可以同時(shí)播放N多音樂,下面時(shí)以前寫的一個(gè)mp3播放器的,見笑呵呵!
支持wav,mid,mp3,wma等音頻格式,如果音樂播放的時(shí)候繼續(xù)打開,前面的音樂不會(huì)聽掉,而是疊加在一起,實(shí)現(xiàn)你的背景音樂,MCIWnd開頭的就是VFW的函數(shù),使用很簡(jiǎn)單,估計(jì)你一看函數(shù)名就知道作用了!
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);//得到文件長(zhǎng)度
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() //暫停,恢復(fù)
{
//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);
}
本次的實(shí)訓(xùn)的mp3播放器主要涉及到的內(nèi)容如下:
MCI API :負(fù)責(zé)音樂的播放,暫停,繼續(xù),停止等功能
2)鏈表的構(gòu)建
3)文件讀取問題
文件存儲(chǔ)有很多種方式,將數(shù)據(jù)寫入文件時(shí)可以以空格或者回車為結(jié)束。
在讀取時(shí),不管是硬fscanf還是gets()進(jìn)行讀取,都要注意一點(diǎn),以gets為例,gets是讀到回車符號(hào)結(jié)尾,但是回車符號(hào)會(huì)被讀取進(jìn)去。也就是說,需要將讀取到的字符串進(jìn)行處理,最后一個(gè)字符要置為‘0’;一定要注意這個(gè)問題。
還有一個(gè)_finddata這個(gè)結(jié)構(gòu)體的問題:
此外由于在win10系統(tǒng)下不知道是我個(gè)人原因還是大部分人都有的的問題在編譯時(shí)findnext會(huì)報(bào)錯(cuò), 因?yàn)開findnext()返回類型為intptr_t而非long型,從“intptr_t”轉(zhuǎn)換到“l(fā)ong”丟失了數(shù)據(jù)。只需要把一般寫的:
long _findfirst( char *filespec, struct _finddata_t fileinfo );
返回值:
如果查找成功的話,將返回一個(gè)long型的唯一的查找用的句柄(就是一個(gè)唯一編號(hào))。這個(gè)句柄將在_findnext函數(shù)中被使用。若失敗,則返回-1。
參數(shù):
filespec:標(biāo)明文件的字符串,可支持通配符。比如: .c,則表示當(dāng)前文件夾下的所有后綴為C的文件。
fileinfo :這里就是用來存放文件信息的結(jié)構(gòu)體的指針。這個(gè)結(jié)構(gòu)體必須在調(diào)用此函數(shù)前聲明,不過不用初始化,只要分配了內(nèi)存空間就可以了。
函數(shù)成功后,函數(shù)會(huì)把找到的文件的信息放入這個(gè)結(jié)構(gòu)體中。
int _findnext( long handle, struct _finddata_t *fileinfo );
返回值:
若成功返回0,否則返回-1。
參數(shù):
handle:即由_findfirst函數(shù)返回回來的句柄。
fileinfo:文件信息結(jié)構(gòu)體的指針。找到文件后,函數(shù)將該文件信息放入此結(jié)構(gòu)體中。
int _findclose( long handle );
返回值:成功返回0,失敗返回-1。
參數(shù): handle :_findfirst函數(shù)返回回來的句柄
一下為一個(gè)簡(jiǎn)化的版本主要是文件操作:
function.h
function.c
main.c
可以使用PlaySound()函數(shù)播放wav聲音,該函數(shù)原型位于windows.h中,
函數(shù)原型為:
BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound);
參數(shù)pszSound是指定了要播放聲音的字符串,該參數(shù)可以是WAVE文件的名字,或是WAV資源的名字,或是內(nèi)存中聲音數(shù)據(jù)的指針,或是在系統(tǒng)注冊(cè)表WIN.INI中定義的系統(tǒng)事件聲音。如果該參數(shù)為NULL則停止正在播放的聲音。
參數(shù)hmod是應(yīng)用程序的實(shí)例句柄,當(dāng)播放WAV資源時(shí)要用到該參數(shù),否則它必須為NULL。
參數(shù)fdwSound是標(biāo)志的組合,各種可選的標(biāo)志及意義如下所示。若成功則函數(shù)返回TRUE,否則返回FALSE。
播放標(biāo)志以及含義:
SND_APPLICATION
用應(yīng)用程序指定的關(guān)聯(lián)來播放聲音。
SND_ALIAS
pszSound參數(shù)指定了注冊(cè)表或WIN.INI中的系統(tǒng)事件的別名。
SND_ALIAS_ID
pszSound參數(shù)指定了預(yù)定義的聲音標(biāo)識(shí)符。
SND_ASYNC
用異步方式播放聲音,PlaySound函數(shù)在開始播放后立即返回。
SND_FILENAME
pszSound參數(shù)指定了WAVE文件名。
SND_LOOP
重復(fù)播放聲音,必須與SND_ASYNC標(biāo)志一塊使用。
SND_MEMORY
播放載入到內(nèi)存中的聲音,此時(shí)pszSound是指向聲音數(shù)據(jù)的指針。
SND_NODEFAULT
不播放缺省聲音,若無此標(biāo)志,則PlaySound在沒找到聲音時(shí)會(huì)播放缺省聲音。
SND_NOSTOP
PlaySound不打斷原來的聲音播出并立即返回FALSE。
SND_NOWAIT
如果驅(qū)動(dòng)程序正忙則函數(shù)就不播放聲音并立即返回。
SND_PURGE
停止所有與調(diào)用任務(wù)有關(guān)的聲音。若參數(shù)pszSound為NULL,就停止所有的聲音,否則,停止pszSound指定的聲音。
SND_RESOURCE
pszSound參數(shù)是WAVE資源的標(biāo)識(shí)符,這時(shí)要用到hmod參數(shù)。
SND_SYNC
同步播放聲音,在播放完后PlaySound函數(shù)才返回。
************************************************************
例如我想播放在C:\WINDOWS\Media目錄中的 Windows XP 啟動(dòng).wav 文件
程序如下:
#include windows.h
#include stdlib.h
int main(int argc, char* argv[])
{
PlaySound("C:\\WINDOWS\\Media\\Windows XP 啟動(dòng).wav", NULL, SND_FILENAME | SND_ASYNC);
system("pause");
return 0;
}