您的位置:首页 > 其它

音乐播放器实现歌词同步

2011-01-14 21:25 801 查看


千千静听的歌词格式如下

[04:02.54][03:33.11][02:17.15][01:29.03]等 你 爱 我 爱 我
[00:26.86]等 你 爱 我
[03:40.75][02:24.74][01:37.65][00:35.58]哪怕只有一次也就足够
[03:48.06][02:31.78][01:44.36]等 你 爱 我 爱 我

所有我们可以用一个矩阵来存储歌词内容

TCHAR SongOn[MAX_PATH];								//正在播放的歌曲最短路径
TCHAR Lyric[120][100];								//歌词
TCHAR LyricOn[100];									//正要显示的歌词
int LyricIndex;										//正在播放的歌的序号
int Lcount;											//歌词句数
int NextSSends;										//下一句播放的时间
void CALLBACK on_timer(HWND hwnd,UINT uMessage,UINT iTimerID,DWORD dwTime);		//歌词显示
void LyricFront(HWND hwnd);							//前进或者后退改变歌词
void LyricSort();									//歌词排序
bool ShowLyrics(HWND hwnd);							//处理歌词


每50毫秒我们去检查一下是否下一句歌词可以显示了

由于我们在操作中不是只一直播放下去

这样,当我们在拖动进度条或快进快退时

要让歌词从头开始检查播放到那里来了

函数实现代码

bool ShowLyrics(HWND hwnd)
{//播放当前歌曲的歌词
//
KillTimer(hwnd,2);
ZeroMemory(Lyric,sizeof(Lyric));
FILE *fp;
TCHAR LPATH[MAX_PATH];
ZeroMemory(LPATH,sizeof(LPATH));
lstrcpy(LPATH,SongOn);
lstrcpy(LPATH+strlen(LPATH)-3,TEXT("lrc"));             //修改后缀
fp = fopen(LPATH,"r");
if(fp==NULL)return ERROR;                             //没有歌词或者打不开
TCHAR LyricLine[100];
Lcount=0;
while(!feof(fp))
{
ZeroMemory(LyricLine,sizeof(LyricLine));
fgets(LyricLine,sizeof(LyricLine),fp);
if(isdigit(LyricLine[1])&&isdigit(LyricLine[2]))
{//属于歌词

int rtimes=1;
memcpy(Lyric[Lcount],LyricLine,10);
while(10*rtimes<strlen(LyricLine)&&LyricLine[10*rtimes]=='[')
{//加时间头
memcpy(Lyric[Lcount+rtimes],LyricLine+10*rtimes,10);
rtimes++;
}
LyricLine[strlen(LyricLine)-1]='/0';
for(int i=0;i<rtimes;i++)
{
lstrcpy(Lyric[Lcount+i]+10,LyricLine+10*rtimes);
//MessageBox(hwnd,Lyric[Lcount+i],0,0);
}
Lcount+=rtimes;
//LyricLine[strlen(LyricLine)-1]='/0';
//lstrcpy(Lyric[Lcount++],LyricLine);
//MessageBox(hwnd,Lyric[Lcount-1],0,0);
}
}
LyricSort();                    //歌词排序
LyricIndex=0;
lstrcpy(LyricOn,Lyric[LyricIndex]);
int minute=(LyricOn[1]-'0')*10+LyricOn[2]-'0';
int second=(LyricOn[4]-'0')*10+LyricOn[5]-'0';
int ssecond=(LyricOn[7]-'0')*10+LyricOn[8]-'0';

NextSSends=(minute*60+second)*1000+ssecond*10;
SetTimer(hwnd,2,50,on_timer);
return true;
}
void LyricFront(HWND hwnd)
{//快进或者快退改变了歌词处理
TCHAR temp[20];
TCHAR temp1[MAX_PATH];
wsprintf(temp1,"status %s position",SongOn);
mciSendString(temp1,temp,sizeof(temp)/sizeof(TCHAR),NULL);
LyricIndex=0;
int iNextSSends=0;
int iLyricIndex=0;
do{//播放时间到
int minute=(Lyric[iLyricIndex][1]-'0')*10+Lyric[iLyricIndex][2]-'0';
int second=(Lyric[iLyricIndex][4]-'0')*10+Lyric[iLyricIndex][5]-'0';
int ssecond=(Lyric[iLyricIndex][7]-'0')*10+Lyric[iLyricIndex][8]-'0';
NextSSends=iNextSSends;
LyricIndex=iLyricIndex;
iNextSSends=(minute*60+second)*1000+ssecond*10;
iLyricIndex++;
}while(iNextSSends<atoi(temp));
LyricIndex--;
lstrcpy(LyricOn,Lyric[LyricIndex]);
//SetDlgItemText(hwnd,IDC_EDITLyrics,LyricOn+10);
}
void LyricSort()
{//歌词按时间排序
for(int i=1;i<Lcount;i++)
{
for(int j=0;j<Lcount-i;j++)
{
int minute=(Lyric[j][1]-'0')*10+Lyric[j][2]-'0';
int second=(Lyric[j][4]-'0')*10+Lyric[j][5]-'0';
int ssecond=(Lyric[j][7]-'0')*10+Lyric[j][8]-'0';
int iNextSSends=(minute*60+second)*1000+ssecond*10;
minute=(Lyric[j+1][1]-'0')*10+Lyric[j+1][2]-'0';
second=(Lyric[j+1][4]-'0')*10+Lyric[j+1][5]-'0';
ssecond=(Lyric[j+1][7]-'0')*10+Lyric[j+1][8]-'0';
int jNextSSends=(minute*60+second)*1000+ssecond*10;
if(iNextSSends>jNextSSends)
{//交换
TCHAR TEMP[100];
ZeroMemory(TEMP,sizeof(TEMP));
lstrcpy(TEMP,Lyric[j]);
lstrcpy(Lyric[j],Lyric[j+1]);
lstrcpy(Lyric[j+1],TEMP);
}
}
}
}


原理比较简单,就是字符串处理麻烦点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: