2020.3.13

前几天在千锋做了一个歌词歌曲同步的项目,今天我分享出来

main.c中

/* ************************************************************************
 *       Filename:  main.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2020年03月09日 20时18分38秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (), 
 *        Company:  
 * ************************************************************************/

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <unistd.h>
#include"main.h"
#include"vd.h"
void test(LRC*head);
int main(int argc, char *argv[])
{
    char *file_data=NULL;
    long file_len = 0;
    FILE *fp = NULL;
    fp = fopen("简单爱.lrc","r");
    if(fp == NULL)
    {
        perror("fopen");
        return;
    }

    //需求:一次性的将文件数据 读取到 内存中
    //1、得到文件的总大小
    //a、使用fseek 将文件指针 定位到文件尾部
    fseek(fp, 0,  2);
    //b、使用ftell计算文件的偏移量 == 文件的总大小
    file_len = ftell(fp);
    //c、使用rewind复位文件流指针
    rewind(fp);

    //2、根据文件的总大小 合理申请 内存空间
    file_data = (char *)calloc(1,file_len+1);//+1的目的 内存末尾存放'\0'
    if(file_data == NULL)
    {
        fclose(fp);
        return;
    }

    //3、一次性 将文件数据 读入到 内存空间
    fread(file_data, file_len, 1, fp);

    //4、遍历读取到的文件内容
    //printf("file_len=%ld\n", file_len);
    //printf("%s\n", file_data);

    char *ar2[128] = {NULL};//定义一个数组来存放分割好的函数
    int i=0;
    ar2[i]=strtok(file_data ,"\r\n");//第一次分割

    int m=0;
    while(ar2[i]!=NULL)//第二次以后的分割
    {
        i++;
        ar2[i]=strtok(NULL,"\r\n");
        m=i;
    }
    //printf("%d\n",m);
/*
    i=0;
    while(ar2[i] != NULL)
    {
        printf("%s\n",ar2[i]);
        i++;
    }
*/
    int n=0;
    int t=0;

    LRC tmp;

    LRC *head={NULL};

    char *p[4]={"歌名","歌手","专辑","制作"};
    for(n=0;n<4;n++)
    {
        char tmp[128]="";
       sscanf(ar2[n],"%*[^:]:%[^]]",tmp);//ppp‐‐简单
       cusor_moveto(15,n+1);
       printf("%s:%s\n",p[n],tmp);
       //cusor_moveto(20,n);
       //printf("%s\n",ppp);
    }
    n=4;
    for(n=4;n<m;n++)
    {
        char *str_lrc = ar2[n];
        while(*str_lrc == '[')
        str_lrc +=10;   

        char *str_time = ar2[n];
        while(*str_time == '[')
      {
        int m = 0,s = 0;

        int time = 0;

        sscanf(str_time,"[%d:%d.64]", &m,&s);

        time =m*60+s;//以秒为单位


        //将时间 和 歌词 一一对应 放入 结构体
        tmp.time = time;

        strcpy(tmp.lrc, str_lrc);

        //printf("%d,%s\n",time,str_lrc);

        //调用链表的有序插入函数
        head = insert_link(head,tmp);

        //分析下一个时间
        str_time += 10;
      }
    }
    test(head);
    return 0;  
}
void test(LRC*head)
{
    char buf1[128]="";
    char buf2[128]="";
    char buf3[128]="";
    char buf4[128]="";
    //启动maplayer(见后面)
    mplayer_play("简单爱.mp3");
    int i=0;
    while(1)
    {
         cusor_moveto(20,3);
         printf("\r%02d:%02d",i/60,i%60);
         fflush(stdout);
         //到链表查询 

         LRC *ret = search_link(head,i);
         if(ret != NULL)
         {
             //滚起来
            strcpy(buf1,buf2);
            strcpy(buf2,buf3);
            strcpy(buf3,buf4);
            strcpy(buf4, ret->lrc);

            cusor_moveto(15,6);
            printf("%s", buf1);

            cusor_moveto(15,7);
            printf("%s", buf2);

            cusor_moveto(15,8);
            printf("%s", buf3);

            cusor_moveto(15,9);
            set_fg_color(COLOR_RED);
            printf("%s", buf4);//当前歌词
            set_fg_color(COLOR_BLACK);
            fflush(stdout);
             
            //printf("%s\n", ret->lrc);
         }

         sleep(1);//休眠1s
         i++;
    }
}


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

main.h中

/* ************************************************************************
 *       Filename:  main.h
 *    Description:  
 *        Version:  1.0
 *        Created:  2020年03月09日 21时04分53秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (), 
 *        Company:  
 * ************************************************************************/
#ifndef __MAIN_H__
#define __MAIN_H__
typedef struct stu  //名字是stu
{
    int time;

    char lrc[128];    

    struct stu *next;
}LRC;//类型是LRC

#endif
extern void mplayer_play(char * song_path);
extern LRC *insert_link(LRC*head,LRC ccc);
extern LRC *search_link(LRC*head,int k);

vd.c中

/* ************************************************************************
 *       Filename:  vd.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2020年03月11日 11时16分57秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (), 
 *        Company:  
 * ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "vd.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);
}

vd.h中

/* ************************************************************************
 *       Filename:  vd.h
 *    Description:  
 *        Version:  1.0
 *        Created:  2020年03月11日 11时17分17秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (), 
 *        Company:  
 * ************************************************************************/
#ifndef  _VD_H_
#define  _VD_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    //_VD_H_


vs.c中

/* ************************************************************************
 *       Filename:  vs.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2020年03月09日 21时05分41秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:  YOUR NAME (), 
 *        Company:  
 * ************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <unistd.h>
#include"main.h"

LRC *search_link(LRC*head,int i);
void mplayer_play(char * song_path);

LRC *insert_link( LRC*head,LRC ccc)
{
    //1.给待插入的节点pi申请对空间
    LRC *pi=(LRC*)calloc(1,sizeof(LRC));
    if(pi == NULL)
    {
        perror("calloc");
        return head;        
    }
    //2.将ccc 的内容 赋值给*pi
    *pi = ccc;//有点疑问-------
    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;
        }
    }
}
LRC *search_link(LRC *head,  int k)
{
    //1、判断链表是否存在
    if(head == NULL)//不存在
    {
        printf("link not found\n");
    }
    else//链表存在
    {
        LRC *pb = head;
        do
        {
          if(pb->time==k)
            {
                return pb;
            }
            else
            {
                pb=pb->next;
            }
        } while (pb->next!=NULL);
    }
    return NULL;
}
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
    ;
}


 

发布了12 篇原创文章 · 获赞 0 · 访问量 73

猜你喜欢

转载自blog.csdn.net/weixin_41604325/article/details/104850671