C 语言_Linux 下实现歌词滚动显示

评价:
3
(1用户)
/*
	1. 解析 lrc 格式的歌词文件
	2. 使用 fflush(stdout) 清屏
	3. 在屏幕上以如下格式显示
				歌曲:   简单爱
				演唱者: 周杰伦
				专辑:   范特西
				作词:   大脸猫
				   播放时间
				     歌词(当前时间对应的歌词, 高亮)
				  下一句歌词
				 再下一句歌词
	4. 只有歌词滚动, 其他不变
	5. 处理好歌词结尾, 不要出现段错误
	6. 可以试着在每行歌词后面加上 " ", 来消除覆盖错误
*/
/*
	printf("\033[%d;%dH", x, y);        //	光标跳转到 x 行 y 列
	printf("\033[s");                   //	保存光标位置
	printf("\033[u");                   //  恢复光标位置
	printf("\033[?25l");                //  隐藏光标
	printf("\33[?25h");                 //  显示光标
	printf("\033[2J");                  //  清屏
	printf("\033[%dm", color);          //  设置前景颜色
	printf("\033[%dm", (color + 10));   //  设置背景颜色
	//	30------BLACK
	//	31------RED
	//	32------GREEN
	//	33------YELLOW
	//	34------BLUE
	//	35------MAGRENTA
	//	36------CYAN
	//	37------WHITE		
*/

/*
	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

extern void cusor_hide(void);           //  隐藏光标
extern void cusor_show(void);           //  显示光标
extern void clear_screen(void);         //  清屏
extern void cusor_get_pos(void);        //  保存光标位置
extern void cusor_set_pos(void);        //  恢复光标位置
extern void set_bg_color(int color);    //  设置字体背景色
extern void set_fg_color(int color);    //  设置字体前景色
extern void cusor_moveto(int x, int y); //  光标跳转到 x行 y列

#endif	//_CONSOLE_H_

/*
	console.c
*/
#include <stdio.h>
#include <stdlib.h>

#include "console.h"

void cusor_hide(void)
{
    printf("\033[?25l");
}

void cusor_show(void)
{
    printf("\33[?25h");
}

void clear_screen(void)
{
    printf("\033[2J");
    fflush(stdout);
}

void cusor_get_pos(void)
{
    printf("\033[s");
    fflush(stdout);
}

void cusor_set_pos(void)
{
    printf("\033[u");
    fflush(stdout);
}

void set_bg_color(int color)
{
    printf("\033[%dm", (color + 10));
    fflush(stdout);
}

void set_fg_color(int color)
{
    printf("\033[%dm", color);
    fflush(stdout);
}

void cusor_moveto(int x, int y)
{
    printf("\033[%d;%dH", y, x);
    fflush(stdout);
}

/*
	lyricanalysis.h
*/
#ifndef _LYRICANALYSIS_H
#define _LYRICANALYSIS_H

typedef struct lrc
{
	int time;
	char song[200];
	struct lrc* next;
} LRC;

extern void Free_Link(LRC *pNode);                            //  释放链表
extern void SortTimeNodeLink(LRC *pNode);					//	歌词排序
extern void HeadInsertLRCNode(LRC **ppNodeLRC, int midtime);  //  歌词插入

#endif	//_LYRICANALYSIS_H

/*
	main.c
*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <unistd.h>

#include "console.h"
#include "lyricanalysis.h"

int main ()
{
    char cnt = 0;
	int systime = 0;
    char al[100] = {0};
    char ar[100] = {0};
	char by[100] = {0};
	char ti[100] = {0};
	LRC* pHeadLRC = NULL;
	LRC* pCopyLRC = NULL;
	char LrcStr[128] = {0};
	char *PLrcStr = LrcStr;

	FILE* fp = fopen ("./test.lrc", "r+");
	if (fp == NULL)
	{
		perror("main_fopen01");
		return -1;
	}
	else
	{
		while (NULL != fgets (LrcStr, 200, fp))
		{
			int min = 0;
			int sec = 0;

			if (sscanf (PLrcStr, "[ti:%s", ti))
			{
				int i = 0;
				while (*(ti + i) != ']')
				{
					i++;
				}
				*(ti + i) = 0;
			}
			if (sscanf (PLrcStr, "[ar:%s", ar))
			{
				int i = 0;
				while (*(ar + i) != ']')
				{
					i++;
				}
				*(ar + i) = '\0';
			}
			if (sscanf (PLrcStr, "[al:%s", al))
			{
				int i = 0;
				while (*(al + i) != ']')
				{
					i++;
				}
				*(al + i) = '\0';
			}
			if (sscanf (PLrcStr, "[by:%s", by))
			{
				int i = 0;
				while (*(by + i) != ']')
				{
					i++;
				}
				*(by + i) = '\0';
			}

			while (2 == sscanf (PLrcStr, "[%d:%d", &min, &sec))
			{
				HeadInsertLRCNode (&pHeadLRC, min * 60 + sec);
				PLrcStr = PLrcStr + 10;
			}

			if (pCopyLRC != pHeadLRC)
			{
				pCopyLRC = pHeadLRC;

				while (pCopyLRC != NULL)
				{
					if (pCopyLRC->song[0] == 0)
					{
						strcpy (pCopyLRC->song, PLrcStr);
						for(int k = 0; k < 100; k++)
						{
							while (pCopyLRC->song[k] != NULL)
							{
								k++;
							}
							pCopyLRC->song[k - 2] = ' ';
						}
					}
					else
					{
						break;
					}
					pCopyLRC = pCopyLRC->next;
				}
			}
			pCopyLRC = pHeadLRC;
			PLrcStr = LrcStr;
			memset (LrcStr, 0, sizeof (LrcStr));
		}
		fclose (fp);
		SortTimeNodeLink (pHeadLRC);

        clear_screen();
        cusor_get_pos();
        cusor_hide();
        set_fg_color(COLOR_BLUE);
        
        cusor_moveto(36, 2);
        printf ("歌曲:   %s\n", ti);
        cusor_moveto(36, 3);
        printf ("演唱者: %s\n", ar);
        cusor_moveto(36, 4);
        printf ("专辑:   %s\n", al);
        cusor_moveto(36, 5);
        printf ("专辑:   %s\n", by);

		cusor_moveto(24, 11);
		printf ("%s\n", (*pHeadLRC).song);
		cusor_moveto(24, 12);
		printf ("%s\n", (*pHeadLRC).next->song);
		cusor_moveto(24, 13);
		printf ("%s\n", (*pHeadLRC).next->next->song);

		while(systime < 255)
		{
			cusor_moveto(40, 9);
			printf("%02d:%02d\n", systime / 60, systime % 60);
			if(systime == pHeadLRC->time + 1 && (*pHeadLRC).next->next != NULL)
			{
				set_fg_color(COLOR_YELLOW);
				cusor_moveto(24, 11);
				printf ("%s\n", (*pHeadLRC).song);
				set_fg_color(COLOR_BLUE);
				cusor_moveto(24, 12);
				printf ("%s\n", (*pHeadLRC).next->song);
				cusor_moveto(24, 13);
				printf ("%s\n", (*pHeadLRC).next->next->song);
				pHeadLRC = pHeadLRC->next;
			}
			else if(systime == pHeadLRC->time + 1 && (*pHeadLRC).next->next == NULL && (*pHeadLRC).next != NULL)
			{
				cusor_moveto(34, 11);
				printf ("%s\n", (*pHeadLRC).song);
				cusor_moveto(34, 12);
				printf ("%s\n", (*pHeadLRC).next->song);
				pHeadLRC = pHeadLRC->next;
			}
			else if(systime == pHeadLRC->time + 1 && (*pHeadLRC).next == NULL)
			{
				cusor_moveto(34, 11);
				printf ("%s\n", (*pHeadLRC).song);
			}

			sleep(1);
			systime++;
		}
		Free_Link (pHeadLRC);
		pHeadLRC = NULL;
	}
    
	return 0;
}

歌词解析可以去看我的“C 语言_解析 lrc 格式的歌词文件”。

本文为原创文章,转载请注明出处!

注册并通过认证的用户才可以进行评价!

发表评论