音乐播放器之源码解析五
来源:互联网 发布:mysql 5.6.25.tar.gz 编辑:程序博客网 时间:2024/06/10 04:33
音乐播放器同步歌词源码解析
歌词lyric.h头文件
#ifndef LRC_H#define LRC_Hint LyricInit(char *lrcpath);int LyricDestroy();char *GetLyricByStartTime(int startTime);char *GetLyricByPos(int pos);int GetLyricTotalLine();#endif
传入歌词路径调用LyricInit函数初始化歌词,不再使用后调用LyricDestroy销毁歌词,通过GetLyricByStartTime获取对应时间的歌词。
typedef struct LineLyric LineLyric;struct LineLyric{int startTime; // second millisecondchar szLrc[LRC_LEN_MAX];LineLyric *next;};LineLyric *g_lineLyricHead = NULL;LineLyric *g_lineLyricTail = NULL;int g_lineLyricCount = 0;
存储歌词使用单链表及g_lineLyricHead和g_lineLyricTail指向歌词头和末尾行。没一行歌词项保存有歌词的开始时间及歌词。
LyricInit函数
初始化歌词
int LyricInit(char *lrcpath){FILE *fp = NULL;char buf[LRC_LEN_MAX] = {0};WCHAR wbuf[LRC_LEN_MAX] = {0};char *p;fp = fopen(lrcpath, "r");if (fp == NULL){printf("lyric init open %s error(%d)\n", lrcpath, GetLastError());return -1;}while ((p = fgets(buf, LRC_LEN_MAX, fp)) != NULL){char *tok = "[";char *tmpval = NULL;if (*p == '\n'){continue;}tmpval = strchr(p, '[');if (tmpval == NULL){continue;}tmpval++;if (strnicmp(tmpval, "ar", 2) == 0) //!< 艺人名{}else if (strnicmp(tmpval, "ti", 2) == 0) //!< 曲名{}else if (strnicmp(tmpval, "al", 2) == 0) //!< 专辑名{}else if (strnicmp(tmpval, "by", 2) == 0) //!< 编者{}else if (strnicmp(tmpval, "offset", 6) == 0)//!< 时间补偿值{}else{char *lrc;LineLyric *llnode = NULL;float mi= 0.0;float ss = 0.0;int startTime= 0;char *left = p;char *right;lrc = strrchr(buf, ']');lrc++;do {char tmp[128] = {0};left = strchr(left, '[');if (left == NULL){break;}left++;right = strchr(left, ':');memcpy(tmp, left, right - left);mi = (float)atof(tmp);left = right+1;right = strchr(left, ']');memcpy(tmp, left, right - left);ss = (float)atof(tmp);startTime = (int)(mi*60+ss);llnode = malloc(sizeof(LineLyric));memset(llnode, 0, sizeof(LineLyric));llnode->startTime = startTime;strcpy(llnode->szLrc, lrc);llnode->next = NULL;if (g_lineLyricHead == NULL){g_lineLyricHead = llnode;g_lineLyricTail = llnode;}else{LineLyric *llprev = g_lineLyricHead;LineLyric *llnext = llprev->next;if (llnode->startTime < llprev->startTime){llnode->next = llprev;g_lineLyricHead = llnode;}else{while (llnext && llnext->startTime <= llnode->startTime){llprev = llnext;llnext = llnext->next;}llnode->next = llnext;llprev->next = llnode;if (llnext == NULL){g_lineLyricTail = llnode;}}}g_lineLyricCount++;left = right+1;} while (1);}}return 0;}
lyric歌词格式见http://baike.baidu.com/view/239396.htm解析每一行歌词并排序存储至歌词链表中。
LyricDestroy函数
销毁歌词
int LyricDestroy(){LineLyric *llnode;if (g_lineLyricHead == NULL){return 0;}llnode = g_lineLyricHead;while (llnode){LineLyric *llnext = llnode->next;free(llnode);llnode = llnext;}g_lineLyricHead = NULL;g_lineLyricTail = NULL;g_lineLyricCount = 0;return 0;}
释放歌词链表项。
GetLyricByStartTime函数
通过开始时间获取对应的歌词字符串
char *GetLyricByStartTime(int startTime){LineLyric *llnode;char *szLrc = NULL;if (g_lineLyricHead == NULL){return NULL;}llnode = g_lineLyricHead;while (llnode){if (llnode->startTime == startTime){if (szLrc == NULL){szLrc = malloc(strlen(llnode->szLrc)+1);memset(szLrc, 0, strlen(llnode->szLrc)+1);strcat(szLrc, llnode->szLrc);}else{szLrc = realloc(szLrc, strlen(szLrc)+strlen(llnode->szLrc)+2);strcat(szLrc, " ");strcat(szLrc, llnode->szLrc);}}llnode = llnode->next;}return szLrc;}
至此主要功能已经实现。
下一篇音乐播放器命令行界面实现源码解析
- 音乐播放器之源码解析五
- 音乐播放器之源码解析一
- 音乐播放器之源码解析二
- 音乐播放器之源码解析三
- 音乐播放器之源码解析四
- 音乐播放器之源码解析六
- android源码解析------Music 音乐播放器
- 音乐播放器源码
- android音乐播放器源码
- 音乐播放器源码下载
- android音乐播放器源码
- 小程序(之音乐播放器源码实现)
- android之音乐播放器
- html之音乐播放器
- Android之音乐播放器
- 音乐播放器之--在线音乐播放
- 新手向!开源音乐播放器JamsMusicPlayer源码解析<1>
- OS音频开发之音乐播放器 - 后台播放音乐
- HDU1506------据说是DP,我更觉得是简单的枚举
- java面试题一
- Tomcat 的三种(bio,nio.apr) 高级 Connector 运行模式
- 利用游标进行数据库数据备份
- 中国“天河二号”成为全球最快超级计算机
- 音乐播放器之源码解析五
- poj 2533 LCS
- 使用xjc生成java类
- 2013java面试题2(答案会更新)
- Ascii utf8 Unicode 字符串转换
- C++基本数据类型
- Android之Button
- 黑马程序员_关于System.Object
- Hadoop安全云盘开发(第2篇)