1. 前期准备
ubuntu系统 myplayer 单向链表 mp3歌曲 与歌曲对应的lrc歌词文件
注意:系统安装请自行查阅。本项目使用C语言开发
安装解码器
sudo apt-get install mplayer
krc转lrc文件转换器可在源码库中查找
定义存放歌词的结构体, 根据结构体创建链表操作函数 lrc.h
#ifndef __LRC_H__
#define __LRC_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
typedef struct
{
// 表示日期时间的数据结构
char minute;
char second;
} TIME;
typedef struct lrc
{
int time; // 歌词时间点
char lrc_buf[200]; // 歌词内容
int lrc_cur_num; // 第几句歌词
struct lrc *next; // 指向链表中的下一个节点
} LRC;
extern char *read_src_file(char *file_name); // 读取文件内容
extern int strtok_lrc_buf(char *src, char ***dest); // 切割文件内容
extern LRC *lrc_head_resolve(char ***data, int *len); // 处理前几行数据 生成链表头
extern LRC *lrc_resolve(char ***data, int head_len, int len, LRC *head); // 处理头之外的数据
extern void print_song_head(LRC *head, int head_len); // 打印歌曲头信息
extern void lrc_printf(LRC *start_point, LRC *pb, int head_len); // 打印歌词
extern LRC *link_search(LRC *head, int m_time); // 查找节点位置
extern LRC *insert_double_link(LRC *head, LRC src); // 有序插入链表
extern void link_free(LRC *head); // 释放链表
extern void time_printf(TIME tm, int head_len); // 打印时间
extern void m_clock(TIME *p_m_time); // 计算时间
extern void print_space(TIME m_time, int head_len); // 打印进度条
#endif // !__LRC_H__
项目使用makefile进行编译工作
CC=gcc
TARGET=main # 主程序
OBJ=main.o lrc.o tools.o my_player.o
CFLAGS=-Wall
$(TARGET):$(OBJ)
@$(CC) $^ -o $@
@./$(TARGET)
$.o:$.c
@$(CC) -c $< -o $@
.PHONY:clean
clean:
rm $(TARGET) $(OBJ)
参考答案讲解:
- 功能(歌曲播放、歌曲信息显示、时钟显示变化、歌词滚动显示、歌词高亮)
- 分析源码(先整体后部分)
- 1 目录结构: ./lrc 歌词文件 ./tools 光标定位及颜色的c文件 ./song 歌曲文件 Makefile 编译规则 main.c 主文件 lrc.c/lrc.h 分文件歌词处理
- my_player.c/my_player.h 分文件播放歌曲
2.2 Makefile 编译规则:
- 明确main.c my_player.c ....参与编译
2.3 main.c
main函数
开始:
read_src_file读出歌词文件内容并保存到返回值
---->strtok_lrc_buf将读出歌词文件内容切割成一行一行并保存到指针数组,返回值为行数。
---- >lrc _head_resolve处理前四行歌词
[ti:简单爱]------>简单爱(song_msg[0])
[ar:周杰伦]------>周杰伦(song _msg[1])
[al:范特西]------>范特西(song_msg[2])
[by:大脸猫]------>大脸猫(song_msg[3])
----->lrc_resolve处理带时间的歌词
[00:04.41]周杰伦Chow,Jay Jou---->双向链表中的一个节点
[02:04.94][00:36.09]我想大声宣布对你依依不舍----》双向链表中的两个节点
---》free回收使用完的内存。
---》print_song _message打印前四行歌词
---》time_printf打印时间
---》Irc_printf打印前五句歌词,无高亮
----》mplayer_play播放歌曲
循环:
时钟每隔1s+1并显现
find_start_point和lrc_printf保证了歌词一直显示5行,且第一个参数是5行的起始节点,第二个高亮的节点
清理:
link_free(head);//释放链表
song_msg_free(song_msg);//释放歌曲信息
cusor_show();//显示光标
源码路径 https://gitee.com/YiZhiLuGuoDeXiaoMaNong/terminal-song-playback
效果截图