main.c
#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include<stdlib.h>
#include"code/start_mplayer.h"
#include"code/song_lrc.h"
#include"pos/console.h"
int main(int argc,char *argv[])
{
//读取歌词文件
char *arr = NULL;
LRC *head = NULL;
arr = read_lrc(arr);
set_bg_color(30);//设置字体背景色
//按行切割
char *buf[128]={arr,NULL};
int i=0;
cusor_hide();//隐藏光标
while(1)//切割
{
buf[i] = strtok(buf[i],"\r\n");
if(buf[i] == NULL)
break;
i++;
}
int n = i;//总行数
clear_screen();//清屏
//逐行分析
head = analyse_row(head,buf,n);
//启动mplayer
mplayer_play("song/简单爱.mp3");
//模拟时钟、滚屏、反显
imitate_clock(head,n,buf);
cusor_set_pos();//恢复光标位置
cusor_show();//显示光标
free(head);
free(arr);
return 0;
}
makefile
exec=main
cc=gcc
obj=main.o code/start_mplayer.o code/read_lrc.o code/lrc_link.o pos/console.o code/analyse_row.o code/imitate_clock.o#你要修改的地方
cflags=-Wall -g
$(exec):$(obj)
$(cc) $^ -o $@ $(cflags)
%.o:%.c
$(cc) -c $< -o $@ $(cflags)
clean:
rm $(exec) *.o code/*.o pos/*.o
code文件
analyse_row.c
#include<stdio.h>
#include<string.h>
#include "../pos/console.h"
#include"song_lrc.h"
LRC* analyse_row(LRC *head,char **buf,int n)
{
int i = 0;
for(i=0;i<n;i++)
{
char c=0;
sscanf(buf[i],"[%c:",&c);
if(c>=48 && c<=57)
{
char *str_lrc = buf[i];
while(*str_lrc=='[')
str_lrc +=10;
//strlrc 指向了歌词的位置
char *str_time = buf[i];
while(*str_time=='[')
{
int m = 0,s = 0;
sscanf(str_time,"[%d:%d.80]",&m,&s);
int time = m*60+s;
LRC temp;
temp.time=time;
strcpy(temp.lrc,str_lrc);
head = insert_link(head,temp);
str_time +=10;
}
}
else
{
cusor_moveto(55,5+i);
char tmp[128]="";
char tmp1[128]="";
sscanf(buf[i],"%*[^:]:%[^]]",tmp);
sscanf(buf[i],"[%[^:]",tmp1);
if(strcmp(tmp1,"ti")==0)
{
strcpy(tmp1,"歌名");
}
else if(strcmp(tmp1,"ar")==0)
{
strcpy(tmp1,"歌手");
}
else if(strcmp(tmp1,"al")==0)
{
strcpy(tmp1,"专辑");
}
else if(strcmp(tmp1,"by")==0)
{
strcpy(tmp1,"制作");
}
set_fg_color(37);//设置字体前景色
printf("%s: %s\n",tmp1,tmp);
}
}
return head;
}
imitate_clock.c
#include<stdio.h>
#include<string.h>
#include <unistd.h>
#include"song_lrc.h"
#include"../pos/console.h"
void imitate_clock(LRC *head,int n,char **buf)//模拟时钟
{
int t=0;
int i=0;
LRC *pi=NULL,*pf=NULL,*pr=NULL;
while(t<266)
{
set_fg_color(37);//设置字体前景色
cusor_moveto(79,23);
printf("] %d:%d",4,25);//歌曲总时间
cusor_moveto(38,23);
printf("%02d:%02d [",t/60,t%60);//时钟
fflush(stdout);
int line =0;
cusor_moveto(45,23);
while(line<t)//进度条
{
printf(">");
line +=8;
}
//到链表查询
LRC *ret = search_link(head,t);
if(ret != NULL)
{
clear_screen();//清屏
for(i=0;i<n;i++)
{
cusor_moveto(55,5+i);
char b=0;
sscanf(buf[i],"[%c:",&b);
if(b<48 || b>57)
{
char tmp[128]="";
char tmp1[128]="";
sscanf(buf[i],"%*[^:]:%[^]]",tmp);
sscanf(buf[i],"[%[^:]",tmp1);
if(strcmp(tmp1,"ti")==0)
{
strcpy(tmp1,"歌名");
}
else if(strcmp(tmp1,"ar")==0)
{
strcpy(tmp1,"歌手");
}
else if(strcmp(tmp1,"al")==0)
{
strcpy(tmp1,"专辑");
}
else if(strcmp(tmp1,"by")==0)
{
strcpy(tmp1,"制作");
}
printf("%s: %s\n",tmp1,tmp);
}
}
cusor_moveto(79,23);
printf("] %d:%d",4,25);//歌曲总时间
cusor_moveto(38,23);
printf("%02d:%02d [",t/60,t%60);//时钟
fflush(stdout);
cusor_moveto(45,23);
int line1=0;
while(line1<t)//进度条
{
printf(">");
line1 +=8;
}
cusor_moveto(50,12);
set_fg_color(37);//设置字体前景色
if(pi!=NULL)
{
printf("%s\n", pi->lrc);
}
cusor_moveto(50,13);
set_fg_color(37);//设置字体前景色
if(pr!=NULL)
{
pi=pr;
printf("%s\n", pr->lrc);
}
cusor_moveto(50,14);
set_fg_color(37);//设置字体前景色
if(pf!=NULL)
{
pr=pf;
printf("%s\n", pf->lrc);
}
cusor_moveto(50,15);
set_fg_color(36);//设置字体前景色
if(ret->lrc!=NULL)
{
pf=ret;
printf("%s\n", ret->lrc);
}
for(i=0;ret->next!=NULL&&i<3;i++)
{
cusor_moveto(50,16+i);
set_fg_color(37);//设置字体前景色
printf("%s\n",ret->next->lrc);
ret=ret->next;
}
}
sleep(1);//休眠1s
t++;
}
}
lrc_link.c
#include<stdio.h>
#include<stdlib.h>
#include"song_lrc.h"
LRC* insert_link(LRC *head,LRC tmp)//插入链表节点
{
LRC *pi = NULL;
pi = (LRC *)calloc(1,sizeof(LRC));//动态申请堆区空间
if(pi == NULL)
{
perror("calloc");
return NULL;
}
*pi = tmp;//把tmp的值赋值给pi
pi->next = NULL;
if(head == NULL)
{
head = pi;
return head;
}
else
{
LRC *pb = head,*pf;
while(pb->time<pi->time && pb->next!=NULL)
{
pf = pb;//pf保存pb的节点
pb = pb->next;
}
if(pb->time>=pi->time)
{
if(pb==head)//头部插入
{
pi->next=head;
head = pi;
return head;
}
else//中部插入
{
pf->next=pi;
pi->next=pb;
return head;
}
}
else
{
pb->next=pi;
return head;
}
}
return head;
}
LRC* search_link(LRC *head,int t)//搜索链表节点信息
{
if(head == NULL)
{
printf("link not found\n");
return NULL;
}
else
{
LRC *pb = head;
while(t!=pb->time && pb->next!=NULL)
{
pb = pb->next;
}
if(t==pb->time)
{
return pb;
}
else
{
return NULL;
}
}
}
read_lrc.c
#include<stdio.h>
#include<stdlib.h>
char* read_lrc(char *arr)
{
long file_len = 0;
FILE *fp = fopen("lrc/简单爱.lrc","r");
if(fp==NULL)
{
perror("fopen");
return NULL;
}
fseek(fp,0,2);//将文件流指针定义到文件末尾
file_len=ftell(fp);//使用ftell计算文件的偏移量,文件的总大小
rewind(fp);//复位文件流指针
arr = (char *)calloc(1,file_len+1);
if(arr==NULL)
{
perror("calloc");
return NULL;
}
fread(arr,file_len,1,fp);//一次性 将文件数据 读入到 内存空间
return arr;
fclose(fp);
}
song_lrc.h
```c
#ifndef __SONG_LRC_H__
#define __SONG_LRC_H__
typedef struct lrc
{
int time;
char lrc[128];
struct lrc *next;
}LRC;
extern char* read_lrc(char *arr);//读取歌词文件
extern LRC* insert_link(LRC *head,LRC tmp);//插入链表节点
extern LRC* search_link(LRC *head,int t);//搜索链表节点信息
extern LRC* analyse_row(LRC *head,char **buf,int n);//逐行分析
extern void imitate_clock(LRC *head,int n,char **buf);//模拟时钟
#endif
start_mplayer.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
//启动mplayer播放器
//参数song_path 为歌曲的路径
void mplayer_play(char * song_path)
{
pid_t pid;
pid=fork();
if(pid<0)
{
perror("fork");
}
else if(pid==0)
{
close(1);
close(2);
execlp("mplayer","mplayer","-slave","-quiet",song_path,NULL);
exit(0);
}
else
;
}
start_mplayer.h
#ifndef __START_MPLAYER_H__
#define __START_MPLAYER_H__
//启动mplayer播放器
//参数song_path 为歌曲的路径
extern void mplayer_play(char * song_path);
#endif
pos文件
console.c
#include <stdio.h>
#include <stdlib.h>
#include "console.h"
void cusor_moveto(int x, int y)
{// ESC[y;xH
printf("\033[%d;%dH",y,x);
fflush(stdout);
}
//保存光标位置
void cusor_get_pos(void)
{// ESC[s
printf("\033[s");
fflush(stdout);
}
//恢复光标位置
void cusor_set_pos(void)
{// ESC[u
printf("\033[u");
fflush(stdout);
}
void cusor_hide(void)
{
printf("\033[?25l");
}
void cusor_show(void)//显示光标
{
printf("\033[?25h");
}
//清屏
void clear_screen(void)
{// ESC[2J
printf("\033[2J");
fflush(stdout);
}
/*
COLOR_RED 红
COLOR_BLACK 黑
COLOR_GREEN 绿
COLOR_BLUE 蓝
COLOR_YELLOW 黄
COLOR_WHITE 白
COLOR_CYAN 青
COLOR_MAGENTA 洋红
*/
//设置前景颜色
void set_fg_color(int color)
{// ESC[#m
printf("\033[%dm",color);
fflush(stdout);
}
//设置背景颜色
void set_bg_color(int color)
{// ESC[#m
printf("\033[%dm",(color+10));
fflush(stdout);
}
console.h
#ifndef _CONSOLE_H_
#define _CONSOLE_H_
#define COLOR_RED 31
#define COLOR_BLACK 30
#define COLOR_GREEN 32
#define COLOR_BLUE 34
#define COLOR_YELLOW 33
#define COLOR_WHITE 37
#define COLOR_CYAN 36
#define COLOR_MAGENTA 35
/*
COLOR_RED 红
COLOR_BLACK 黑
COLOR_GREEN 绿
COLOR_BLUE 蓝
COLOR_YELLOW 黄
COLOR_WHITE 白
COLOR_CYAN 青
COLOR_MAGENTA 洋红
*/
extern void cusor_moveto(int x, int y);//光标跳转到 y行 x列
extern void cusor_get_pos(void);//保存光标位置
extern void cusor_hide(void);
extern void cusor_show(void);//显示光标
extern void cusor_set_pos(void);//恢复光标位置
extern void clear_screen(void);//清屏
extern void set_fg_color(int color);//设置字体前景色
extern void set_bg_color(int color);//设置字体背景色
#endif //_CONSOLE_H_
歌词列表
lrc文件
[ti:简单爱]
[ar:周杰伦]
[al:范特西]
[by:大脸猫]
[00:04.41]周杰伦 Chow, Jay Jou
[00:10.56]简单爱(台视Star blue蓝星主题曲)
[00:18.48]词:徐若瑄 曲:周杰伦
[00:26.44]说不上为什么 我变得很主动
[00:31.37]若爱上一个人 什么都会值得去做
[02:04.94][00:36.09]我想大声宣布 对你依依不舍
[02:09.97][00:41.26]连隔壁邻居都猜到我现在的感受
[02:14.94][00:46.17]河边的风 在吹着头发 飘动
[02:19.80][00:51.25]牵着你的手 一阵莫名感动
[02:24.61][00:55.86]我想带你 回我的外婆家
[02:28.32][00:59.79]一起看着日落 一直到我们都睡着
[03:34.64][02:34.71][01:05.83]我想就这样牵着你的手不放开
[03:39.68][02:39.34][01:10.71]爱能不能够永远单纯没有悲哀
[03:44.27][02:43.90][01:15.44]我想 带你骑单车
[03:46.74][02:46.60][01:18.05]我想 和你看棒球
[03:49.77][02:49.58][01:20.71]想这样没担忧
[03:51.61][02:51.59][01:22.69]唱着歌 一直走☆
[03:54.38][02:54.35][01:25.57]我想就这样牵着你的手不放开
[03:59.19][02:59.01][01:30.41]爱可不可以简简单单没有伤害
[04:03.77][03:03.73][01:35.04]你 靠着我的肩膀
[04:06.33][03:06.26][01:37.49]你 在我胸口睡着
[04:09.13][03:09.34][01:40.57]像这样的生活
[04:11.36][03:11.26][01:42.66]我爱你 你爱我★
[03:13.76][01:44.97]想~~~ 简!简!单!单! 爱~~~
[03:23.61][01:54.30]想~~~ 简!简!单!单! 爱~~~