基于LINUX系统的音乐播放器

做了个音乐播放器的项目,要求能实现分析歌词,歌词滚屏,唱到的那一句显示红色。
可以通过数字键1,2来选择要播放的歌曲,但是要按三遍。在这里插入图片描述
在这里插入图片描述
附上源码:
main.c:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"start_mplayer.h"
#include"console.h"

int main(int argc,charargv[])
{ int b =0;
printf(“敲3次1:简单爱\n”);
printf(“敲3次2:山水之间\n”);
scanf("%d\n",&b);
/
while(b1||b2)
{*/
if (b1)
{mplayer_play(“简单爱.mp3”);}
else if(b
2)
{mplayer_play(“山水之间.mp3”);}

//mplayer_play(“简单爱.mp3”);
char *arr=NULL;
arr = geci(arr);

char*buf[128]={NULL};
int a = 0;
a = cut_geci(buf,arr);
printf("歌词一共%d行\n",a);
char *last_time = buf[a-1];
int min = 0,sec = 0;
sscanf(last_time,"[%d:%d.64]",&min,&sec);
int end_time = min*60+sec+5;
cusor_hide(); 
int i=0;

for(i=0;i<4;i++)
{
set_fg_color(COLOR_MAGENTA);
char tmp[128]="";
sscanf(buf[i],"%*[:]:%[]]",tmp);
switch (i)
{
case 0:
printf(“歌名:%s\n”,tmp);
break;
case 1:
printf(“歌手名:%s\n”,tmp);
break;
case 2:
printf(“作词:%s\n”,tmp);
break;
case 3:
printf(“作曲:%s\n\n”,tmp);
break;

    default:
      break;  
    }
}
i=4;

LRC *head=NULL;

for(i=4;i<a;i++)
{
char *str_lrc = buf[i];
//[03:34.64][02:34.71][01:05.83]我想就这样牵着你的手不放开
//1、寻找歌词的位置
while(*str_lrc == ‘[’)
str_lrc +=10;
//str_lrc指向了歌词的位置

//逐个时间分析
char *str_time = buf[i];
while(str_time == ‘[’)
{
int m = 0,s = 0;
sscanf(str_time,"[%d:%d.64]", &m,&s);
int time = m
60+s;//以秒为单位

   //将时间 和 歌词  一一对应 放入 结构体
  
   LRC tmp;
   tmp.time = time;
   strcpy(tmp.lrc, str_lrc);
   
   //调用链表的有序插入函数
   head = insert_link(head,tmp);
  
   //分析下一个时间
   str_time  += 10;

}

}
// print_link(head);

i=0;

int j=0;
char buf1[128]="";
char buf2[128]="";
char buf3[128]="";
char buf4[128]="";

while(i<260)
{    
   
    cusor_moveto(40,6);
    set_fg_color(COLOR_RED);
     printf("%02d:%02d",i/60,i%60);
     fflush(stdout);
      set_fg_color(COLOR_WHITE);
     //到链表查询 
     LRC *ret = search_lrc(head,i);
     if(ret != NULL)
     { 
       my_strcpy(buf1,buf2);
        
		      my_strcpy(buf2,buf3);
       
		      my_strcpy(buf3,buf4);
		      my_strcpy(buf4, ret->lrc);

		      cusor_moveto(30,7);
		      printf("%s               ", buf1);

	     	cusor_moveto(30,8);
	      	printf("%s               ", buf2);

	    	cusor_moveto(30,9);
	    	printf("%s                 ", buf3);

	     cusor_moveto(30,10);
	   	 set_fg_color(COLOR_RED);
		   printf("%s                ", buf4);//当前歌词
	     set_fg_color(COLOR_WHITE);
		   fflush(stdout);
     }
     
     
    
     
     sleep(1);//休眠1s
    cusor_moveto(0,12);
    printf("进度:%ds\n",i);
    cusor_moveto(80,12);
    printf("总时长:%ds",end_time);
    
     i++;
    
     if(i%3!=0)
     { cusor_moveto((i/3)+6,12);
    printf(">");}
}

/*
cusor_moveto(30,11);
char abb[128]="";
if(i==end_time)
printf(“你想继续吗?yes or no\n”);
scanf("%s",abb);
if(strcmp(abb,“no”)==0)
{
break;
}
else if(strcmp(abb,“yes”)==0)
{
continue;
}
else
{
printf(“你输得啥呀,不对!”);
}*/

return 0;}
fun.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct lrc
{
int time;
char lrc[128];

    struct lrc *next;
}LRC;

char* geci (char*arr)
{
long file_len = 0;
FILE *fp = NULL;
int b=0;
scanf("%d\n",&b);
if (b1)
{
fp = fopen(“简单爱.lrc”,“r”);
}
else if(b
2)
{
fp = fopen(“山水之间.lrc”,“r”);
}

    if(fp == NULL)
     {
	 perror("fopen");
	 return;
     }

//打开文件
fseek(fp, 0, 2);
file_len = ftell(fp);
rewind(fp);

arr = (char *)calloc(1,file_len+1);
if(arr == NULL)
  {
	fclose(fp);
	return ;
  }

fread(arr, file_len, 1, fp);
//printf("file_len=%ld\n", file_len);
//printf("%s\n", buf);

fclose(fp);
return arr;

}

int cut_geci(charbuf[],chararr)
{
int i=0;

buf[i] = strtok(arr,"\r\n");

while(buf[i]!=NULL)
{
i++;
buf[i] = strtok(NULL,"\r\n");
}

return i;
}
//双向链表
/*
LRCinsert_link(LRChead,LRC tmp)
{
LRC *pi = (LRC *)calloc(1,sizeof(LRC));
if(pi == NULL)
{
perror(“calloc”);
return head;
}
*pi = tmp;
pi->next = NULL;

if(head == NULL)
{
    head = pi;
    return head;
}
else
{
    LRC*pb =head,*pf = head;
    while(pb->time<pi->time&&pb->next!= NULL)
    {
        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;

}

void print_link(LRC *head)
{
//判断链表是否存在
if(head == NULL)
{
printf(“link not found\n”);
return;
}
else//链表存在
{
LRC pb = head;
do
{
//访问节点内容
printf(“time=%d, geci=%s\n”, pb->time,pb->lrc);
//pb指向下一个节点
pb = pb->next;
}while(pb != head);
}
return;
}
/

LRC* insert_link(LRC *head, LRC tmp)
{
//1、给待插入的节点pi 申请 堆区空间
LRC *pi = (LRC *)calloc(1,sizeof(LRC));
if(pi == NULL)
{
perror(“calloc”);
return head;
}

//2、将tmp的内容 赋值给 *pi
*pi = tmp;
pi->next = NULL;

//3、链表节点pi的插入
if(head == NULL)//链表不存在
{
	head = pi;
	return head;
}
else//存在
{
	//a、寻找插入点
	LRC *pb = head, *pf = head;
	while(pb->time < pi->time && pb->next != NULL)
	{
		pf = pb;
		pb = pb->next;
	}

	//b、插入点的判断
	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;

}
/*void print_link(LRC *head)
{
if(head == NULL)//链表不存在
{
printf(“link not find\n”);
return;
}
else
{
LRC *pb = head;
while(pb != NULL)
{
printf(“time=%d geci:%s\n”, pb->time, pb->lrc);
//pb指向下一个节点
pb = pb->next;
}

}

return;

}*/

LRC* search_lrc(LRC *head, int i)
{
//1、判断链表是否存在
if(head == NULL)//不存在
{
printf(“link not found\n”);
return NULL;
}
else//链表存在
{
LRC *pb = head;

	//逐个将节点中的time 和 i比较 如果不相等 pb=pb->next
	while(pb->time!=i && pb->next != NULL)
		pb = pb->next;

	//判断是否找到
	if(pb->time == i)//找到
		return pb;
	else//没找到
		return NULL;
}

return NULL;

}

char *my_strcpy(char *dst,const char *src)
{
#if 0
do
{
*dst = *src;
dst++;
src++;
}while(*src != ‘\0’);
*dst=’\0’;
#endif
while(*dst++ = *src++);

}

(注释掉的部分是存在问题的双链表插入和遍历)
start_mplyer.h
#ifndef START_MPLAYER_H
#define START_MPLAYER_H
//启动mplayer播放器
//参数song_path 为歌曲的路径
typedef struct lrc
{
int time;
char lrc[128];

    struct lrc *next;
}LRC;

extern void mplayer_play(char * song_path);
extern char *geci(char *arr);
extern int cut_geci(char buf[],char arr);
extern LRC
insert_link(LRC
head,LRC tmp);
//extern void print_link(LRC head);
extern LRC
search_lrc(LRC *head,int i);
extern char *my_strcpy(char *dst,const char *src);

#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
;
}
另外使用了光标定位和颜色变换的程序

Makefile:
exec=main
cc=gcc
obj=main.o start_mplayer.o fun.o console.o
cflags=-Wall -g
( e x e c ) : (exec): (exec):(obj)
$(cc) $^ -o $@ $(cflags)
%.o:%.c
$(cc) -c $< -o $@ $(cflags)
clean:
rm $(exec) *.o

cosole.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("\33[?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);
}

congsole.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

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值