粤嵌GEC6818,基于LVGL和mplayer的音视频播放器

#include <myplay.h>

pthread_mutex_t mutex_lv;//lvgl线程锁

static char local_music_path[]="/tmp/newwork/8.30big_project/music";//音乐路径

static char local_pic_path[]="/tmp/newwork/photo";//图片路径

static char local_words_path[]="/tmp/newwork/words";//歌词路径

static char local_video_path[]="/tmp/newwork/tv";//视频路径

static char music_path[100][1024];//音乐路径

static char pic_path[100][1024];//图片路径

static char words_path[100][1024];//歌词路径

static char video_path[100][1024];//视频路径

static char words_buf[5*1024]={0};//放歌词的数组

static FILE *fp_mplayer=NULL;   //播放器传回的管道,接收播放进度

static FILE *fp_words=NULL;     //歌词文件

static int fd_mplayer = 0;      //定义管道文件描述符,发送指令给mplayer

static int music_num=0;         //音乐数量

static int music_index=-1;      //当前音乐的下标值,用于寻找上下首

static int video_index=-1;      //当前视频的下标值,用于寻找上下首

static int video_num=0;         //视频的数量

static int percent_pos;         //当前播放百分比

static float time_length;       //歌曲长度

static float time_pos;          //当前播放进度

static bool list_flag=1;    //开关列表

static bool words_flag=1;    //歌词列表

static bool play_flag=0;    //播放音乐开关

static bool start=0;        //启动,线程读mplayer返回信息

static lv_style_t font_style;   //中文

static lv_obj_t *play_mode;     //下拉列表对象,播放模式

static lv_obj_t *speed_obj;     //下拉列表对象,播放速度

static lv_obj_t * music_list;   //音乐列表对象

static lv_obj_t *pic_obj;       //图片对象

static lv_obj_t * volume_slider;  //音量滑条对象

static lv_obj_t * play_slider;  //播放进度条对象

static lv_obj_t * cont;         //音乐盒的背景对象

static lv_obj_t * video_list;   //视频列表对象

static lv_obj_t *title_label;     //图片信息标签

static lv_obj_t *words_label;     //歌词标签

static lv_obj_t * volume_label; //音量标签

static lv_obj_t *time_length_label; //时长标签

static lv_obj_t *time_pos_label; //当前时间标签

static lv_obj_t *words_list;     //歌词标签  

pthread_cond_t cond;        //条件变量,用于暂停读取mplayer

pthread_cond_t cond1;

pthread_mutex_t mutex;

pthread_mutex_t mutex1;

pthread_t tid_read;         //读mplayer的线程id

pthread_t tid_write;        //写mplayer的线程id

//这里为音乐播放器部分

//获取音乐的路径,检测本地歌单

void get_music_path()

{

    //读目录,mp3后缀保存到数组

    music_num =0;

    DIR *dirp = opendir(local_music_path);

    if(dirp==NULL)

    {

        perror(local_music_path);

        exit(0);

    }

    struct dirent* msg;

    while(1)

    {

        msg = readdir(dirp);

        if(msg == NULL)break;

        if(msg->d_name[0]=='.')continue;

        if(strstr(msg->d_name,".mp3"))

        {

            sprintf(music_path[music_num], "%s/%s", local_music_path, msg->d_name);

            //拼接图片与歌词路径↓

            char name[100]={0};

            strcpy(name,strtok(msg->d_name,"."));

            sprintf(pic_path[music_num], "S:%s/%s.png", local_pic_path, name);

            sprintf(words_path[music_num], "%s/%s.txt", local_words_path, name);

            //拼接图片与歌词路径↑

            music_num++;

            puts(music_path[music_num - 1]);

            puts(pic_path[music_num - 1]);

            puts(words_path[music_num - 1]);

        }

    }

    printf("检索歌单完成 共%d\n",music_num);

}

//初始化字体风格

void init_font_style()

{

    /*创建字体*/

    static lv_ft_info_t info;

    info.name = "/font/simkai.ttf";//字体位置

    info.weight = 18;//大小

    info.style = FT_FONT_STYLE_NORMAL;//风格

    info.mem = NULL;

    if(!lv_ft_font_init(&info)) {

        LV_LOG_ERROR("create failed.");

    }

    /*给字体设置样式*/

   

    lv_style_init(&font_style);

    lv_style_set_text_font(&font_style, info.font);

    lv_style_set_text_align(&font_style, LV_TEXT_ALIGN_CENTER);

    //lv_obj_add_style(label, &style, 0);

}

//初始化图片的父对象,即图片都在这个对象中显示

void init_pic_parent_obj()

{

    //在屏幕中创建一个对象

    lv_obj_t * img = lv_obj_create(cont);

    //取消滚动

    lv_obj_clear_flag(img, LV_OBJ_FLAG_SCROLLABLE);

    lv_obj_set_size(img, 200, 200);

    lv_obj_align(img, LV_ALIGN_CENTER, 0, -60);

    // lv_obj_set_style_pad_all

    //图片对象

    pic_obj = lv_img_create(img);

    lv_obj_center(pic_obj);  

}

//信号任务

void signal_10_task(int arg)

{

    if (arg == 10)

    {

        printf("收到信号 %d 线程任务(读取mplayer)暂停\n", arg);

        pthread_kill(tid_write,12); //停止写

        pthread_cond_wait(&cond, &mutex);   //停止读

        pthread_cond_signal(&cond1);//唤醒获取时间

        puts("继续工作,读mplayer");

        return;

    }

}

//信号任务

void signal_12_task(int arg)

{

    //printf("收到信号 %d\n",arg);

    printf("收到信号 %d 线程任务(get_time_pos)暂停\n", arg);

    pthread_cond_wait(&cond1, &mutex1);

    puts("继续工作,写mplayer");  

    return;

}

static char words_line[1024]={0};

//初始化歌曲信息的父对象

void init_title_obj()

{

    // //在屏幕中创建一个对象

   

    lv_obj_t * title = lv_obj_create(cont);

    lv_obj_clear_flag(title, LV_OBJ_FLAG_SCROLLABLE);//禁用滚动

    lv_obj_set_size(title, 200, 50);

    lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 10);

   

    //标题标签

    title_label = lv_label_create(title);

   


 

    //添加字体

    lv_obj_add_style(title_label, &font_style, 0);

    lv_obj_center(title_label);

    lv_label_set_text(title_label, "开启音乐之旅");

    //歌词标签

    words_label = lv_label_create(cont);

   

    lv_obj_align(words_label,LV_ALIGN_CENTER,0,70);

    lv_obj_add_style(words_label, &font_style, 0);

    lv_label_set_text(words_label,"歌词");

}

//找歌词

void *find_words_task(void *arg)

{  

    char *p=strstr(words_buf,(char *)arg);//寻找这个时间有没有歌词

    if(p!=NULL)                 //和歌词相同时间

    {            

        char buf[1024]={0};

        sscanf(p,"%s",buf);

        char *q = strrchr(buf,']');

        sscanf(++q,"%s",buf);  

        if(strcmp(buf,words_line))//不相同

        {

            strcpy(words_line,buf);

           

            //puts(words_line);  

            //**********歌词标签

            //lv_label_set_text(words_label,words_line);

           

            pthread_mutex_lock(&mutex_lv);//上锁

            lv_label_set_text(words_label,words_line);

            pthread_mutex_unlock(&mutex_lv);

        }    

    }

}

//线程任务 读播放器返回内容

static char show_time_buf[100]={0};

void *read_mplayer_task(void *arg)

{

   

    //注册一个信号

    signal(10, signal_10_task);//收到10就暂停

    char line[1024]={0};                //返回信息

    char *p;

    while (1)

    {

        memset(line, 0, 1024);

        fgets(line,1024,fp_mplayer);  //读取进程返回的内容

        //printf("返回 %s",line);      

        if(strstr(line,"ANS_TIME_POSITION"))//当前播放秒数

        {

            p=strrchr(line,'=');

            p++;    

            sscanf(p,"%f",&time_pos);

            printf("歌曲播放时间 %.2f\n",time_pos);

            char tmp[100]={0};

            int tmp_time=time_pos;

            sprintf(tmp,"%02d:%02d",tmp_time/60,tmp_time % 60);

            if(strcmp(show_time_buf,tmp))//不相同

            {

                strcpy(show_time_buf,tmp);

                //lv_label_set_text(time_pos_label,show_time_buf); //设置标签

                pthread_mutex_lock(&mutex_lv);//上锁

                lv_label_set_text(time_pos_label,show_time_buf);

                pthread_mutex_unlock(&mutex_lv);//解锁

            }

            puts(tmp);//打印时间  00:00

            //*********开启线程找歌词**********//

            pthread_t tid;

            pthread_create(&tid,NULL,find_words_task,tmp);

            pthread_detach(tid);    

            //*******************//

        }

        if(strstr(line,"ANS_PERCENT_POSITION"))//播放百分比

        {

             p=strrchr(line,'=');//p++;    

            int percent=0;

            sscanf(++p,"%d",&percent);

            printf("播放百分比 %d\n",percent_pos);

             if(percent!=percent_pos)

            {

            percent_pos=percent;

            //lv_slider_set_value(play_slider,percent_pos,LV_ANIM_OFF);//设置进度条值

            pthread_mutex_lock(&mutex_lv);//上锁

            lv_slider_set_value(play_slider,percent_pos,LV_ANIM_OFF);

            pthread_mutex_unlock(&mutex_lv);

            }

            if(percent_pos>=99)//播完了

            {

                lv_label_set_text(time_pos_label,"0:00");

                //播放模式

                int mod = lv_dropdown_get_selected(play_mode);

                switch (mod)

                    {

                        case 0:{

                                pthread_kill(tid_read,10);//停止读写mplayer

                                break;

                                }

                        case 1://循环播放

                                break;          

                        case 2://列表循环

                                {

                                if(++music_index >= music_num)music_index=0;

                                play_one_music();

                                break;

                                }

                        case 3://随机播放

                                {

                                srand((unsigned)time(NULL));

                                music_index = (music_index+rand())%music_num;

                                play_one_music();

                                break;

                                }              

                        default:

                                break;

                    }


 

            }

        }

        if(strstr(line,"ANS_LENGTH"))//歌曲长度

        {

            p=strrchr(line,'=');p++;    

            sscanf(p,"%f",&time_length);

            printf("歌曲长度 %.2f\n",time_length);

            char time_buf[100]={0};

            int length=time_length;

            sprintf(time_buf,"%02d:%02d",length/60,length % 60);

            puts(time_buf);

            pthread_mutex_lock(&mutex_lv);//上锁

            lv_label_set_text(time_length_label,time_buf); //设置标签

            pthread_mutex_unlock(&mutex_lv);//解锁

       

        }


 

    }

   

}

//线程任务 发送命令给mplayer

void *write_mplayer_task(void *arg)

{

    //注册一个信号

    signal(12, signal_12_task);//收到12就暂停

    char cmd1[1024]="get_time_pos\n";

    char cmd[1024]="get_percent_pos\n";

    while(1)

    {

        write(fd_mplayer,cmd1,strlen(cmd1));//发送获取时间命令

        usleep(400*1000);

        write(fd_mplayer,cmd,strlen(cmd));//发送获取百分比

        usleep(400*1000);

        //sleep(1);      

    }

}

//线程任务 创建子进程播放音乐

void *play_music_task(void *arg)

{    

    printf("---- %ld线程任务------------------\n",pthread_self());

    //拼接命令

    char cmd[1024]="mplayer -slave -quiet -input file=/pipe";

    sprintf(cmd,"%s %s",cmd,music_path[music_index]);

   

    //puts(cmd);  

    //播放音乐

    fp_mplayer = popen(cmd, "r");

    if (fp_mplayer == NULL)perror("popen fail:");

    puts("----线程任务(启动播放音乐)完成 -----------------------\n");

    strcpy(cmd,"get_time_length\n");    //获取长度

    write(fd_mplayer,cmd,strlen(cmd));

    strcpy(cmd,"get_time_pos\n");    //发送获取时间命令

    write(fd_mplayer,cmd,strlen(cmd));

    pthread_exit(NULL);//线程结束

}

//播放一首音乐

void play_one_music()

{  

    if(play_flag != 0)//看看有没有线程在使用播放器

    {

        system("killall -9 mplayer");

    }

    play_flag=1;

    printf("音乐索引%d\n", music_index);

    //开启线程播放音乐

    pthread_t tid;

    int pt = pthread_create(&tid, NULL, play_music_task, NULL);

    if(pt != 0)

    {

        perror("创建进程失败");

        return -1;

       

    }

    pthread_detach(tid);//分离属性,自动回收

    if(!start)

    {

        sleep(1);

        //读取mplayer的内容

        pthread_create(&tid_read, NULL, read_mplayer_task, NULL);//新建线程

        pthread_detach(tid_read);//分离属性,自动回收

        //发送获取时间命令

        pthread_create(&tid_write, NULL, write_mplayer_task, NULL);

        pthread_detach(tid_write);//分离属性,自动收回

        printf("tid_read %ld  tid_write %ld\n",tid_read,tid_write);

        start=1;

    }

    pthread_cond_signal(&cond);//唤醒线程读取mplayer返回的内容

    //***************************************************************//

    char tmp[100]={0};

   

    char *p = strrchr(music_path[music_index],'/');

    strcpy(tmp,++p);

   

    lv_label_set_text(title_label,strtok(tmp,"."));

    lv_label_set_text(words_label,strtok(tmp,"."));

   

    //显示音乐图片

    lv_img_set_src(pic_obj,pic_path[music_index]);

     //打开歌词文件

    FILE *fp = fopen(words_path[music_index],"r");

    memset(words_buf,0,sizeof(words_buf));

    if(fp!=NULL)

    {

        fread(words_buf,5*1024,4,fp);

    }

    fclose(fp);

    //设置播放属性

    int ret = lv_dropdown_get_selected(speed_obj);

    //音量

    int volume=(int)lv_slider_get_value(volume_slider);

    char cmd[1024]={0};

    sprintf(cmd,"volume %d 1\n",volume);

    write(fd_mplayer,cmd,strlen(cmd));

    //修改播放速度

    switch (ret)

    {

        case 0:{

                char cmd[1024]={"speed_set 1\n"};

                write(fd_mplayer,cmd,strlen(cmd));

                break;

                }

        case 1:{      

                char cmd[1024]={"speed_set 1.25\n"};

                write(fd_mplayer,cmd,strlen(cmd));  

                break;    

                }

        case 2:{      

                char cmd[1024]={"speed_set 1.5\n"};

                write(fd_mplayer,cmd,strlen(cmd));

                break;

                }

        case 3:{      

                char cmd[1024]={"speed_set 2\n"};        

                write(fd_mplayer,cmd,strlen(cmd));        

                break;

        }          

        default:        

                break;

    }

    //播放模式

    int mod = lv_dropdown_get_selected(play_mode);

    switch (mod)

    {

        case 0:{

                char cmd[1024]={"loop -1\n"};

                write(fd_mplayer,cmd,strlen(cmd));

                break;

                }

        case 1:{

                char cmd[1024]={"loop -1\n"};

                write(fd_mplayer,cmd,strlen(cmd));

                strcpy(cmd,"loop 1\n");write(fd_mplayer,cmd,strlen(cmd));        

                break;

                }

        case 2://列表循环

                {        

                break;    

                }

        case 3://随机播放

                {      

                break;

                }          

        default:        

                break;

    }



 

}

//列表处理函数,播放列表中的音乐

static lv_event_cb_t event_handler_music_list(lv_event_t * e)

{

    //获取事件码

    lv_event_code_t code = lv_event_get_code(e);

    //获取事件对象,这里是按钮

    lv_obj_t * obj = lv_event_get_target(e);

    //如果点击按钮

    if(code == LV_EVENT_CLICKED)

    {

        //打印按钮中的文本

        //LV_LOG_USER("Clicked: %s", lv_list_get_btn_text(music_list, obj));

        printf("Clicked  %s\n", lv_list_get_btn_text(music_list, obj));

       

        //当前播放中的音乐下标更新为点击列表的下标

        music_index = lv_event_get_user_data(e);

        play_one_music();        

    }

}      

//显示歌单列表

static void show_list()

{

    //创建列表文本框

    music_list = lv_list_create(cont);

    //添加风格

    lv_obj_add_style(music_list, &font_style, 0);

    lv_obj_set_size(music_list, 180, 300);

    //列表位置

    //lv_obj_center(music_list);

    lv_obj_align(music_list, LV_ALIGN_RIGHT_MID, -20, -80);

    //添加文本

    lv_list_add_text(music_list, "Music list");

    /*在列表中添加按钮*/

    lv_obj_t *btn;

    for(int i = 0; i < music_num; i++)

    {

        char tmp[100]={0};

        char *p = music_path[i];

        p = strrchr(p,'/');

        strcpy(tmp,++p);//裁剪到只剩音乐名字  music.mp3

        //参数:列表对象,图标宏,按钮名

        btn = lv_list_add_btn(music_list, NULL,strtok(tmp,"."));

        //列表按钮风格

        lv_obj_add_style(music_list, &font_style, 0);

        //触发事件,把下标传递

        lv_obj_add_event_cb(btn, event_handler_music_list, LV_EVENT_CLICKED, i);

    }

}

//按钮事件

static void btn_handler(lv_event_t * e)

{

    lv_event_code_t code = lv_event_get_code(e);

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);

    if(code == LV_EVENT_CLICKED) //点击按钮

    {

        if(strcmp(msg,"pause") == 0)

        {

            if(!start)return;

            pthread_kill(tid_read,10);//暂停读mplayer返回内容      

            system("killall -19 mplayer");

        }

        if(strcmp(msg,"play") == 0)

        {

            if(!start)return;

            system("killall -18 mplayer");//播放器继续

            pthread_cond_signal(&cond);//唤醒读写mplayer

            usleep(1000);

            pthread_cond_signal(&cond);//防止被再次暂停

        }

        if(strcmp(msg,"forward") == 0)

        {

            if(!start)return;

            usleep(1000);

            char  cmd[1024]={"seek +10\n"};

            write(fd_mplayer,cmd,strlen(cmd));  

            strcpy(cmd,"get_percent_pos\n");

            write(fd_mplayer,cmd,strlen(cmd));//发送获取时间命令    

        }

        if(strcmp(msg,"back") == 0)

        {

            if(!start)return;

            usleep(10000);

            char  cmd[1024]={"seek -10\n"};

            write(fd_mplayer,cmd,strlen(cmd));  

            strcpy(cmd,"get_percent_pos\n");

            write(fd_mplayer,cmd,strlen(cmd));//发送获取时间命令  

        }

        if(strcmp(msg,"next_music") == 0)

        {

            usleep(1000);

            //播放模式

            int mod = lv_dropdown_get_selected(play_mode);

            switch (mod)

            {

            case 1:

            {

                play_one_music();break;

            }

            case 0:

            case 2://列表循环

            {

                if(++music_index >= music_num)music_index=0;

                play_one_music();

                break;

            }

            case 3://随机播放

            {

                srand((unsigned)time(NULL));

                music_index = (music_index+rand())%music_num;

                printf("music_index %d\n",music_index);

                play_one_music();

                break;

            }              

            default:

                break;

            }

        }

        if(strcmp(msg,"prev_music") == 0)

        {

            usleep(1000);

            //播放模式

            int mod = lv_dropdown_get_selected(play_mode);

            switch (mod)

            {

            case 1://循环播放

            { char cmd[1024]={"loop -1\n"};write(fd_mplayer,cmd,strlen(cmd));

            strcpy(cmd,"loop 1\n");write(fd_mplayer,cmd,strlen(cmd));play_one_music();break;}

            case 0://单曲

            case 2://列表循环

            {

                if(--music_index <= 0)music_index=music_num-1;

                play_one_music();

                break;

            }

            case 3://随机播放

            {

                srand((unsigned)time(NULL));

                music_index = (music_index+rand())%music_num;

                play_one_music();

                break;

            }              

            default:

                break;

            }

        }

        if(strcmp(msg,"show_list") == 0)

        {

            list_flag=!list_flag;

            if(list_flag)

                lv_obj_clear_flag(music_list,LV_OBJ_FLAG_HIDDEN);        

            else

                lv_obj_add_flag(music_list, LV_OBJ_FLAG_HIDDEN);

        }

    }

}

//显示按钮

void show_button()

{

    //风格设置

    static lv_style_t btn_style;

    lv_style_init(&btn_style);

    /*Set a background color and a radius*/

    lv_style_set_radius(&btn_style,90);

    lv_style_set_bg_opa(&btn_style, LV_OPA_COVER);

    lv_style_set_bg_color(&btn_style, lv_palette_lighten(LV_PALETTE_BLUE, 1));//按钮色

    /*Add a shadow*/

    lv_style_set_shadow_width(&btn_style, 55);

    lv_style_set_shadow_color(&btn_style, lv_palette_main(LV_PALETTE_BLUE));//背景色

    //按钮的标签

    lv_obj_t *label;

    //暂停按钮

    lv_obj_t *btn_pause = lv_btn_create(cont);

    //按钮事件

    lv_obj_add_event_cb(btn_pause, btn_handler, LV_EVENT_ALL,"pause");  

    //位置

    lv_obj_align(btn_pause, LV_ALIGN_BOTTOM_MID,40,-20);

    //大小

    lv_obj_set_size(btn_pause,60,60);

    //图标

    lv_obj_set_style_bg_img_src(btn_pause,LV_SYMBOL_PAUSE,0);

    //添加风格

    lv_obj_add_style(btn_pause,&btn_style,0);

    //播放按钮

    lv_obj_t *btn_play = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_play, btn_handler, LV_EVENT_ALL,"play");  

    lv_obj_align(btn_play, LV_ALIGN_BOTTOM_MID,-40,-20);

    lv_obj_set_size(btn_play,60,60);

    lv_obj_set_style_bg_img_src(btn_play,LV_SYMBOL_PLAY,0);

    lv_obj_add_style(btn_play,&btn_style,0);

    //快进

    lv_obj_t *btn_forward = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_forward, btn_handler, LV_EVENT_ALL,"forward");

    lv_obj_set_size(btn_forward,60,60);

    lv_obj_align(btn_forward, LV_ALIGN_BOTTOM_MID,120,-20);

    lv_obj_set_style_bg_img_src(btn_forward,LV_SYMBOL_RIGHT LV_SYMBOL_RIGHT,0);

    lv_obj_add_style(btn_forward,&btn_style,0);

    //快退

    lv_obj_t *btn_back = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_back, btn_handler, LV_EVENT_ALL,"back");

    lv_obj_set_size(btn_back,60,60);

    lv_obj_align(btn_back, LV_ALIGN_BOTTOM_MID,-120,-20);

    lv_obj_set_style_bg_img_src(btn_back,LV_SYMBOL_LEFT LV_SYMBOL_LEFT,0);

    lv_obj_add_style(btn_back,&btn_style,0);

    //下一首

    lv_obj_t *btn_next = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_next, btn_handler, LV_EVENT_ALL,"next_music");

    lv_obj_set_size(btn_next,60,60);

    lv_obj_align(btn_next, LV_ALIGN_BOTTOM_MID,200,-20);

    lv_obj_set_style_bg_img_src(btn_next,LV_SYMBOL_NEXT,0);

    lv_obj_add_style(btn_next,&btn_style,0);

    //上一首

   

    lv_obj_t *btn_prev = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_prev, btn_handler, LV_EVENT_ALL,"prev_music");

    lv_obj_set_size(btn_prev,60,60);

    lv_obj_align(btn_prev, LV_ALIGN_BOTTOM_MID,-200,-20);

    lv_obj_set_style_bg_img_src(btn_prev,LV_SYMBOL_PREV,0);

    lv_obj_add_style(btn_prev,&btn_style,0);

    //显示,隐藏  歌单列表

    //风格设置

    static lv_style_t style;

    lv_style_init(&style);

    /*设置背景颜色和半径*/

    lv_style_set_radius(&style, 5);

    lv_style_set_bg_opa(&style, LV_OPA_COVER);

    lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1));

    /*添加一个影子*/

    lv_style_set_shadow_width(&style, 55);

    lv_style_set_shadow_color(&style, lv_palette_main(LV_PALETTE_BLUE));

    //歌单列表

    lv_obj_t *btn_list = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_list, btn_handler, LV_EVENT_ALL,"show_list");

    lv_obj_set_size(btn_list,60,60);

    lv_obj_align(btn_list, LV_ALIGN_BOTTOM_RIGHT,-20,-90);

    label = lv_label_create(btn_list);

    lv_obj_add_style(label, &font_style, 0);

    lv_label_set_text(label, "menu");

    lv_obj_center(label);

    lv_obj_add_style(btn_list, &style, 0);

}

//下拉列表事件

static void dd_handler(lv_event_t * e)

{

    //获取事件码

    lv_event_code_t code = lv_event_get_code(e);

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);  

    if(code == LV_EVENT_VALUE_CHANGED)//值被修改

    {

        if(strcmp(msg,"speed")==0)

        {

            //获取事件对象

            //lv_obj_t *speed = lv_event_get_target(e);

            int ret = lv_dropdown_get_selected(speed_obj);

            //printf("ret = %d\n",ret);

            //修改播放速度

            switch (ret)

            {

            case 0:

            {

                char  cmd[1024]={"speed_set 1\n"};

                write(fd_mplayer,cmd,strlen(cmd));  

                break;

            }

            case 1:

            {

                char  cmd[1024]={"speed_set 1.25\n"};

                write(fd_mplayer,cmd,strlen(cmd));

                break;

            }

            case 2:

            {

                char  cmd[1024]={"speed_set 1.5\n"};

                write(fd_mplayer,cmd,strlen(cmd));

                break;

            }

            case 3:

            {

                char  cmd[1024]={"speed_set 2\n"};

                write(fd_mplayer,cmd,strlen(cmd));

                break;

            }          

            default:

                break;

            }

        }

        if(strcmp(msg,"play_mode")==0)

        {

            //播放模式

            int mod = lv_dropdown_get_selected(play_mode);

            switch (mod)

            {

            case 0:{char cmd[1024]={"loop -1\n"};write(fd_mplayer,cmd,strlen(cmd));break;}

            case 1:

            { char cmd[1024]={"loop -1\n"};write(fd_mplayer,cmd,strlen(cmd));

            strcpy(cmd,"loop 1\n");write(fd_mplayer,cmd,strlen(cmd));        break;}

            case 2://列表循环

            {        break;    }

            case 3://随机播放

            {       break;

            }          

            default:        break;

            }

        }

    }

}

//显示下拉列表

static void show_drop_down()

{

    static const char * opts = "x1\n"

                               "x1.25\n"

                               "x1.5\n"

                               "x2";

    static const char * opts1 = "single\n"

                               "circle\n"

                               "list\n"

                               "random";                          

    //播放速度 创建一个对象

    speed_obj = lv_dropdown_create(cont);

    //lv_dropdown_set_text(speed_obj, "Speed");

    //触发事件

    lv_obj_add_event_cb(speed_obj,dd_handler,LV_EVENT_ALL,"speed");

    //添加选项

    lv_dropdown_set_options_static(speed_obj, opts);

    //大小

    lv_obj_set_size(speed_obj,80,40);

    //位置

    lv_obj_align(speed_obj, LV_ALIGN_BOTTOM_RIGHT, -60, -20);

    //箭头位置,现在由低朝上

    lv_dropdown_set_dir(speed_obj, LV_DIR_BOTTOM);

    //列表弹出方向

    lv_dropdown_set_symbol(speed_obj, LV_SYMBOL_UP);

    //标签

    lv_obj_t *speed_label = lv_label_create(cont);

    lv_obj_add_style(speed_label, &font_style, 0);

    lv_label_set_text(speed_label, "speed");

    lv_obj_align_to(speed_label, speed_obj, LV_ALIGN_OUT_TOP_MID, 0, 0);

    //播放模式

    play_mode = lv_dropdown_create(cont);

    //添加字体

    //lv_obj_add_style(play_mode, &font_style, 0);

    lv_obj_add_event_cb(play_mode,dd_handler,LV_EVENT_ALL,"play_mode");

    lv_dropdown_set_options_static(play_mode, opts1);

    lv_obj_set_size(play_mode,100,40);

    //位置

    lv_obj_align(play_mode, LV_ALIGN_BOTTOM_LEFT, 40, -20);

    lv_dropdown_set_dir(play_mode, LV_DIR_BOTTOM);

    lv_dropdown_set_symbol(play_mode, LV_SYMBOL_UP);

    lv_obj_t *mode_label = lv_label_create(cont);

    lv_obj_add_style(mode_label, &font_style, 0);

    lv_label_set_text(mode_label, "mode");

    lv_obj_align_to(mode_label, play_mode, LV_ALIGN_OUT_TOP_MID, 0, 0);

}

//滑动条事件

static void slider_event_cb(lv_event_t * e)

{

    if(!start)return;

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);

    //puts(msg);

    if(strcmp(msg,"volume")==0)

    {  

        lv_obj_t * slider = lv_event_get_target(e);//获取事件对象

        char buf[8];

        int volume=(int)lv_slider_get_value(slider);//获取值

        lv_snprintf(buf, sizeof(buf), "%d",volume);

        lv_label_set_text(volume_label, buf);           //更新音量标签值

        lv_obj_align_to(volume_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

        usleep(100);            //修改音量值

        char cmd[1024]={0};

        sprintf(cmd,"volume %d 1\n",volume);

        write(fd_mplayer,cmd,strlen(cmd));  

    }  

    if(strcmp(msg,"play")==0)

    {

        puts("松开了");

        if(start)//启动就先暂停

        {pthread_kill(tid_read,10);//暂停读mplayer返回内容      

        system("killall -19 mplayer");}

        int rate = (int)lv_slider_get_value(play_slider);//获取值

        float new_time = time_length * rate * 0.01;

        int seek_time = new_time - time_pos;

        char  cmd[1024]={0};

        sprintf(cmd,"seek %d\n",seek_time);

        //puts(cmd);

        write(fd_mplayer,cmd,strlen(cmd));

        system("killall -18 mplayer");//播放器继续

        pthread_cond_signal(&cond);//唤醒读写mplayer

        usleep(1000);

        pthread_cond_signal(&cond);//防止被再次暂停

    }

}

//显示滑动条

static void show_slider(void)

{      //音量    

    volume_slider = lv_slider_create(cont);

    lv_obj_align(volume_slider,LV_ALIGN_LEFT_MID,20,20);//位置    

    lv_obj_add_event_cb(volume_slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, "volume");//事件    

    lv_obj_set_size(volume_slider,18,180);//大小

    lv_slider_set_value(volume_slider,100,LV_ANIM_OFF);//初始值  

    /*标签 音量大小 */

    volume_label = lv_label_create(cont);

    lv_label_set_text(volume_label, "100");

    lv_obj_align_to(volume_label, volume_slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

    lv_obj_t *label = lv_label_create(cont);

    lv_obj_add_style(label, &font_style, 0);

    lv_label_set_text(label, "volume");

    lv_obj_align_to(label, volume_label, LV_ALIGN_OUT_TOP_MID, 0, -210);

    //播放进度条

    play_slider = lv_slider_create(cont);

    lv_obj_align(play_slider,LV_ALIGN_CENTER,0,120);//位置  

    lv_obj_set_width(play_slider,400);//宽度

    lv_obj_add_event_cb(play_slider, slider_event_cb, LV_EVENT_RELEASED , "play");//事件    

    lv_slider_set_value(play_slider,0,LV_ANIM_OFF);//初始值

    lv_slider_set_range(play_slider, 0, 100);//范围

    /*在滑条下创建标签*/

    time_length_label = lv_label_create(cont);

    lv_label_set_text(time_length_label, "0:00");

    lv_obj_align_to(time_length_label, play_slider, LV_ALIGN_OUT_RIGHT_BOTTOM,0,20);

    time_pos_label = lv_label_create(cont);

    lv_label_set_text(time_pos_label, "0:00");

    lv_obj_align_to(time_pos_label, play_slider, LV_ALIGN_OUT_LEFT_BOTTOM,0,20);

}

//----------属于返回按钮的函数

void Back_btn(lv_event_t * e)

{

    system("killall -9 mplayer");

    lv_obj_del(lv_obj_get_parent((lv_obj_t *)(e->user_data)));  

}

//显示界面

static void display_interface()

{

   

    //创建背景cont,所有显示基于背景

    cont = lv_obj_create(lv_scr_act());//声明一个背景

    lv_obj_set_size(cont, 800, 480);//设置背景的范围

    lv_obj_set_style_bg_color(cont, lv_palette_main(LV_PALETTE_LIGHT_BLUE), 0);

    lv_obj_set_style_bg_grad_color(cont, lv_palette_main(LV_PALETTE_LIGHT_GREEN), 0);

    lv_obj_set_style_bg_grad_dir(cont, LV_GRAD_DIR_VER, 0);

    //基于cont背景创新返回按钮的对象

    lv_obj_t * btn_back = lv_btn_create(cont);

    lv_obj_t* lab6 = lv_label_create(btn_back);

    lv_label_set_text(lab6, "x");

    lv_obj_center(lab6);

    lv_obj_set_style_radius(btn_back,5,0);//设置对象边角为圆角 角度自己调整中间值

    lv_obj_set_size(btn_back, 30, 30);

    lv_obj_set_pos(btn_back, 0, 0);

    lv_obj_add_event_cb(btn_back, Back_btn, LV_EVENT_PRESSED, btn_back); //传入按钮父对象的父对象

   


 

    //初始化图片父对象

    init_pic_parent_obj();

    init_title_obj();

    //显示歌单列表

    show_list();

    //显示按钮

    show_button();

    //显示下拉列表

    show_drop_down();

    //显示滑动条

    show_slider();

}

//*********************************//

//下面是视频的函数

//获取视频的路径,检测本地节目单

void get_video_path()

{

    //读目录,avi后缀保存到数组

    video_num =0;

    DIR *dirp = opendir(local_video_path);

    if(dirp==NULL)

    {

        perror(local_video_path);

        exit(0);

    }

    struct dirent* msg;

    while(1)

    {

        msg = readdir(dirp);

        if(msg == NULL)break;

        if(msg->d_name[0]=='.')continue;

        if(strstr(msg->d_name,".avi"))

        {

            sprintf(video_path[video_num], "%s/%s", local_video_path, msg->d_name);

            video_num++;

            puts(video_path[video_num - 1]);

        }

    }

    printf("检索歌单完成 共%d\n",video_num);

}

//线程任务 创建子进程播放视频

void *play_video_task(void *arg)

{

    printf("---- %ld线程任务------------------\n",pthread_self());

    //拼接命令

    char cmd[1024]="mplayer -quiet -slave -zoom -x 670 -y 350 -geometry 60:0 -input file=/pipe";

    sprintf(cmd,"%s %s",cmd,video_path[video_index]);

    printf("命令:%s\n", cmd);

   

    fp_mplayer = popen(cmd, "r");

    if (fp_mplayer == NULL)

    perror("popen fail:");

    puts("----线程任务(启动播放视频)完成 -----------------------\n");

   

    strcpy(cmd,"get_time_length\n");    //获取长度

    write(fd_mplayer,cmd,strlen(cmd));

    strcpy(cmd,"get_time_pos\n");    //发送获取时间命令

    write(fd_mplayer,cmd,strlen(cmd));

   

    pthread_exit(NULL);//线程结束

}

//播放一个视频

void play_one_video()

{  

    if(play_flag != 0)//看看有没有线程在使用播放器

    {

        system("killall -9 mplayer");

    }

    play_flag=1;

    printf("视频索引%d\n", video_index);

    //打开线程播放视频

    pthread_t tid;

    int pt = pthread_create(&tid, NULL, play_video_task, NULL);

    if(pt != 0)

    {

        perror("创建进程失败");

        return -1;

       

    }

   

    pthread_detach(tid);//分离属性,自动回收

   

    if(!start)

    {

        sleep(1);

        //读取mplayer的内容

        pthread_create(&tid_read, NULL, read_mplayer_task, NULL);//新建线程

        pthread_detach(tid_read);//分离属性,自动回收

        //发送获取时间命令

        pthread_create(&tid_write, NULL, write_mplayer_task, NULL);

        pthread_detach(tid_write);//分离属性,自动收回

        printf("tid_read %ld  tid_write %ld\n",tid_read,tid_write);

        start=1;

    }

   pthread_cond_signal(&cond);//唤醒线程读取mplayer返回的内容

   // *******************************************************************//

    //音量

    int volume=(int)lv_slider_get_value(volume_slider);

    char cmd[1024]={0};

    sprintf(cmd,"volume %d 1\n",volume);

    write(fd_mplayer,cmd,strlen(cmd));

   

}

   

//视频按键事件(没写)

static void btn_handler2(lv_event_t * e)

{

    lv_event_code_t code = lv_event_get_code(e);

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);

    if(code == LV_EVENT_CLICKED) //点击按钮

    {

        if(strcmp(msg,"pause") == 0)

        {

            if(!start)return;

            pthread_kill(tid_read,10);//暂停读mplayer返回内容      

            system("killall -19 mplayer");

        }

        if(strcmp(msg,"play") == 0)

        {

            if(!start)return;

            system("killall -18 mplayer");//播放器继续

            pthread_cond_signal(&cond);//唤醒读写mplayer

            usleep(1000);

            pthread_cond_signal(&cond);//防止被再次暂停

        }

        if(strcmp(msg,"forward") == 0)

        {

            if(!start)return;

            usleep(1000);

            char  cmd[1024]={"seek +10\n"};

            write(fd_mplayer,cmd,strlen(cmd));  

            strcpy(cmd,"get_percent_pos\n");

            write(fd_mplayer,cmd,strlen(cmd));//发送获取时间命令    

        }

        if(strcmp(msg,"back") == 0)

        {

            if(!start)return;

            usleep(10000);

            char  cmd[1024]={"seek -10\n"};

            write(fd_mplayer,cmd,strlen(cmd));  

            strcpy(cmd,"get_percent_pos\n");

            write(fd_mplayer,cmd,strlen(cmd));//发送获取时间命令  

        }

        if(strcmp(msg,"next_music") == 0)

        {

            usleep(1000);

            if(++video_index >= video_num)video_index=0;

                play_one_video();

        }

        if(strcmp(msg,"prev_music") == 0)

        {

            usleep(1000);

            if(--video_index <= 0)video_index=video_num-1;

                play_one_video();

        }

        if(strcmp(msg,"music_show_list") == 0)

        {

            list_flag=!list_flag;

            if(list_flag)

                lv_obj_clear_flag(video_list,LV_OBJ_FLAG_HIDDEN);        

            else

                lv_obj_add_flag(video_list, LV_OBJ_FLAG_HIDDEN);

        }

       

    }

}

//显示视频按钮

static void show_button_tv()

{

    static lv_style_t btn_style;

    lv_style_init(&btn_style);

    lv_style_set_radius(&btn_style,90);

    lv_style_set_bg_opa(&btn_style, LV_OPA_COVER);

    lv_style_set_bg_color(&btn_style, lv_palette_lighten(LV_PALETTE_BLUE, 1));//按钮色

    //Add a shadow

    lv_style_set_shadow_width(&btn_style, 55);

    lv_style_set_shadow_color(&btn_style, lv_palette_main(LV_PALETTE_BLUE));//背景色

    //按钮的标签

    lv_obj_t *label;

    //暂停按钮

    lv_obj_t *btn_pause = lv_btn_create(cont);

    //按钮事件

    lv_obj_add_event_cb(btn_pause, btn_handler2, LV_EVENT_ALL,"pause");  

    //位置

    lv_obj_align(btn_pause, LV_ALIGN_BOTTOM_MID,40,0);

    //大小

    lv_obj_set_size(btn_pause,60,60);

    //图标

    lv_obj_set_style_bg_img_src(btn_pause,LV_SYMBOL_PAUSE,0);

   

    //播放按钮

    lv_obj_t *btn_play = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_play, btn_handler2, LV_EVENT_ALL,"play");  

    lv_obj_align(btn_play, LV_ALIGN_BOTTOM_MID,-40,0);

    lv_obj_set_size(btn_play,60,60);

    lv_obj_set_style_bg_img_src(btn_play,LV_SYMBOL_PLAY,0);

   

     //快进

    lv_obj_t *btn_forward = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_forward, btn_handler2, LV_EVENT_ALL,"forward");

    lv_obj_set_size(btn_forward,60,60);

    lv_obj_align(btn_forward, LV_ALIGN_BOTTOM_MID,120,0);

    lv_obj_set_style_bg_img_src(btn_forward,LV_SYMBOL_RIGHT LV_SYMBOL_RIGHT,0);

   

    //快退

    lv_obj_t *btn_back = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_back, btn_handler2, LV_EVENT_ALL,"back");

    lv_obj_set_size(btn_back,60,60);

    lv_obj_align(btn_back, LV_ALIGN_BOTTOM_MID,-120,0);

    lv_obj_set_style_bg_img_src(btn_back,LV_SYMBOL_LEFT LV_SYMBOL_LEFT,0);

   

    //下一首

    lv_obj_t *btn_next = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_next, btn_handler2, LV_EVENT_ALL,"next_music");

    lv_obj_set_size(btn_next,60,60);

    lv_obj_align(btn_next, LV_ALIGN_BOTTOM_MID,200,0);

    lv_obj_set_style_bg_img_src(btn_next,LV_SYMBOL_NEXT,0);

   

    //上一首

   

    lv_obj_t *btn_prev = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_prev, btn_handler2, LV_EVENT_ALL,"prev_music");

    lv_obj_set_size(btn_prev,60,60);

    lv_obj_align(btn_prev, LV_ALIGN_BOTTOM_MID,-200,0);

    lv_obj_set_style_bg_img_src(btn_prev,LV_SYMBOL_PREV,0);

   

    //显示,隐藏  歌单列表

    //风格设置

    static lv_style_t style;

    lv_style_init(&style);

    //设置背景颜色和半径

    lv_style_set_radius(&style, 5);

    lv_style_set_bg_opa(&style, LV_OPA_COVER);

    lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1));

    //添加一个影子

    lv_style_set_shadow_width(&style, 55);

    lv_style_set_shadow_color(&style, lv_palette_main(LV_PALETTE_BLUE));

    //视频单列表

    lv_obj_t *btn_list = lv_btn_create(cont);

    lv_obj_add_event_cb(btn_list, btn_handler2, LV_EVENT_ALL,"music_show_list");

    lv_obj_set_size(btn_list,60,60);

    lv_obj_align(btn_list, LV_ALIGN_BOTTOM_RIGHT,-20,0);

    label = lv_label_create(btn_list);

    lv_obj_add_style(label, &font_style, 0);

    lv_label_set_text(label, "menu");

    lv_obj_center(label);

   

}

//视频滑动条事件

static void slider_event_cb2(lv_event_t * e)

{

    if(!start)return;

    //获取传递的参数

    char *msg = lv_event_get_user_data(e);

    //puts(msg);

    if(strcmp(msg,"volume")==0)

    {  

        lv_obj_t * slider = lv_event_get_target(e);//获取事件对象

        char buf[8];

        int volume=(int)lv_slider_get_value(slider);//获取值

        lv_snprintf(buf, sizeof(buf), "%d",volume);

        lv_label_set_text(volume_label, buf);           //更新音量标签值

        lv_obj_align_to(volume_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

        usleep(100);            //修改音量值

        char cmd[1024]={0};

        sprintf(cmd,"volume %d 1\n",volume);

        write(fd_mplayer,cmd,strlen(cmd));  

    }  

    if(strcmp(msg,"play")==0)

    {

        puts("松开了");

        if(start)//启动就先暂停

        {

            pthread_kill(tid_read,10);//暂停读mplayer返回内容      

            system("killall -19 mplayer");

        }

        int rate = (int)lv_slider_get_value(play_slider);//获取值

        float new_time = time_length * rate * 0.01;

        int seek_time = new_time - time_pos;

        char  cmd[1024]={0};

        sprintf(cmd,"seek %d\n",seek_time);

        //puts(cmd);

        write(fd_mplayer,cmd,strlen(cmd));

        system("killall -18 mplayer");//播放器继续

        pthread_cond_signal(&cond);//唤醒读写mplayer

        usleep(1000);

        pthread_cond_signal(&cond);//防止被再次暂停

    }

}

//视频显示滑动条

static void show_slider_tv(void)

{      //音量    

    volume_slider = lv_slider_create(cont);

    lv_obj_align(volume_slider,LV_ALIGN_LEFT_MID,0,20);//位置    

    lv_obj_add_event_cb(volume_slider, slider_event_cb2, LV_EVENT_VALUE_CHANGED, "volume");//事件    

    lv_obj_set_size(volume_slider,18,180);//大小

    lv_slider_set_value(volume_slider,100,LV_ANIM_OFF);//初始值  

    //标签 音量大小

    volume_label = lv_label_create(cont);

    lv_label_set_text(volume_label, "100");

    lv_obj_align_to(volume_label, volume_slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);

    lv_obj_t *label = lv_label_create(cont);

    lv_obj_add_style(label, &font_style, 0);

    lv_label_set_text(label, "volume");

    lv_obj_align_to(label, volume_label, LV_ALIGN_OUT_TOP_MID, 0, -210);

    //播放进度条

    play_slider = lv_slider_create(cont);

    lv_obj_align(play_slider,LV_ALIGN_CENTER,0,135);//位置  

    lv_obj_set_width(play_slider,600);//宽度

    lv_obj_add_event_cb(play_slider, slider_event_cb2, LV_EVENT_RELEASED , "play");//事件    

    lv_slider_set_value(play_slider,0,LV_ANIM_OFF);//初始值

    lv_slider_set_range(play_slider, 0, 100);//范围

    //在滑条下创建标签

    time_length_label = lv_label_create(cont);

    lv_label_set_text(time_length_label, "0:00");

    lv_obj_align_to(time_length_label, play_slider, LV_ALIGN_OUT_RIGHT_BOTTOM,0,20);

    time_pos_label = lv_label_create(cont);

    lv_label_set_text(time_pos_label, "0:00");

    lv_obj_align_to(time_pos_label, play_slider, LV_ALIGN_OUT_LEFT_BOTTOM,0,20);

}

//列表处理函数,播放列表中的视频(没写)

static lv_event_cb_t event_handler_video_list(lv_event_t * e)

{

   //获取事件码

    lv_event_code_t code = lv_event_get_code(e);

    //获取事件对象,这里是按钮

    lv_obj_t * obj = lv_event_get_target(e);

    //如果点击按钮

    if(code == LV_EVENT_CLICKED)

    {

        printf("Clicked  %s\n", lv_list_get_btn_text(video_list, obj));

        //当前播放中的video下标更新为点击列表的下标

        video_index = lv_event_get_user_data(e);

        play_one_video();

    }

}

//显示节目单列表

static void show_list2()

{

    //创建列表文本框

    video_list = lv_list_create(cont);

    //添加风格

    lv_obj_add_style(video_list, &font_style, 0);

    lv_obj_set_size(video_list, 75, 300);

    //列表位置

    //lv_obj_center(music_list);

    lv_obj_align(video_list, LV_ALIGN_RIGHT_MID, 5, -80);

    //添加文本

    lv_list_add_text(video_list, "list");

    //在列表中添加按钮

    lv_obj_t *btn;

    for(int i = 0; i < video_num; i++)

    {

        char tmp[100]={0};

        char *p = video_path[i];

        p = strrchr(p,'/');

        strcpy(tmp,++p);//裁剪

        // 参数:列表对象,图标宏,按钮名

        btn = lv_list_add_btn(video_list, NULL,strtok(tmp,"."));

        //列表按钮风格

        lv_obj_add_style(video_list, &font_style, 0);

        // 触发事件,把下标传递

        lv_obj_add_event_cb(btn, event_handler_video_list, LV_EVENT_CLICKED, i);

    }


 

}

static void k(lv_event_t *e)

{

    system("killall -9 mplayer");

}

//视频显示界面

static void display_interface2()

{

    //创建背景cont,所有显示基于背景

    cont = lv_obj_create(lv_scr_act());//声明一个背景

    lv_obj_set_size(cont, 800, 480);//设置背景的范围

    lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);

    //基于cont背景创新返回按钮的对象

    lv_obj_t *btn_back = lv_btn_create(cont);

    lv_obj_t *lab6 = lv_label_create(btn_back);

    lv_label_set_text(lab6, "x");

    lv_obj_center(lab6);

    lv_obj_set_style_radius(btn_back,5,0);//设置对象边角为圆角 角度自己调整中间值

    lv_obj_set_size(btn_back, 30, 30);

    lv_obj_set_pos(btn_back, 0, 0);

    lv_obj_add_event_cb(btn_back, Back_btn, LV_EVENT_PRESSED, btn_back); //传入按钮父对象的父对象

    //整一个杀视频的按钮

   

    lv_obj_t* btn01 = lv_btn_create(cont);

    lv_obj_align(btn01, LV_ALIGN_BOTTOM_LEFT, 0, 0);

    lv_obj_t* label01 = lv_label_create(btn01);

    lv_label_set_text(label01, "kill");

    lv_obj_center(label01);

    lv_obj_add_event_cb(btn01, k, LV_EVENT_CLICKED, NULL);//按键事件

    //初始化视频内容

    get_video_path();

    // //显示视频列表

   

    // //显示按钮

     show_button_tv();

   

    // //显示歌单列表

     show_list2();

   

    // //显示滑动条

     show_slider_tv();

   

}

//---------------------------------------------------下面是开始界面的函数

//视频播放器的main

static void video_playback(lv_event_t* e) {

    if(access("/pipe", F_OK))

    {

        mkfifo("/pipe", 0644);

    }

    fd_mplayer = open("/pipe", O_RDWR);

    if(fd_mplayer < 0)

    {

        perror("打开管道文件失败");

        exit(0);

    }

    display_interface2();

}

//音乐播放器的main

static void music_player(lv_event_t* e)

{

    if(access("/pipe" ,F_OK))

    {

        mkfifo("/pipe", 0644);

    }

   

    fd_mplayer = open("/pipe", O_RDWR);

    if(fd_mplayer < 0)

    {

        perror("打开管道文件失败");

        exit(0);

    }

    //检索本地歌单

    get_music_path();

    //初始化字体

    init_font_style();

   

   

    //显示见面函数

    display_interface();

   

    return 0;

}

//开始函数我的main

void Video_music_player()

{

//视频播放器的按钮

    lv_obj_t* btn01 = lv_btn_create(lv_scr_act());

    lv_obj_align(btn01, LV_ALIGN_CENTER, 0, -40);

    lv_obj_t* label01 = lv_label_create(btn01);

    lv_label_set_text(label01, "video");

    lv_obj_align(btn01, LV_ALIGN_CENTER,0,-50);

    lv_obj_center(label01);

    lv_obj_add_event_cb(btn01, video_playback, LV_EVENT_CLICKED, NULL);//按键事件


 

//音乐播放器的按钮

    lv_obj_t* btn02 = lv_btn_create(lv_scr_act());

    lv_obj_align(btn02, LV_ALIGN_CENTER, 0, -40);

    lv_obj_t* label02 = lv_label_create(btn02);

    lv_label_set_text(label02, "music");

    lv_obj_align(btn02, LV_ALIGN_CENTER,0, 50);

    lv_obj_center(label02);

    lv_obj_add_event_cb(btn02, music_player, LV_EVENT_CLICKED, NULL);



 

   

    return 0;

}

-----------------------------------------------------------------------------------------------------------------------------这是.h文件

#ifndef _MYPLAY_H_

#define _MYPLAY_H_

#include "lvgl/examples/lv_examples.h"

#include <stdlib.h>

#include <string.h>

#include <dirent.h>

#include <stdio.h>

#include <pthread.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <signal.h>

#include<time.h>

#include <semaphore.h>

#define FIFO "/tmp/fifo4test"

extern void Video_music_player();//我的main


 

#endif

--------------------------------------------------------------------------------------------------------------------------main.c

#include "lvgl/lvgl.h"

#include "lvgl/demos/lv_demos.h"

#include "lv_drivers/display/fbdev.h"

#include "lv_drivers/indev/evdev.h"

#include <unistd.h>

#include <pthread.h>

#include <time.h>

#include <sys/time.h>

#define DISP_BUF_SIZE (480 * 1024)


 

int main(void)

{

    /*lvgl初始化*/

    lv_init();


 

    /*输出设备初始化及注册*/

    fbdev_init();

    /*A small buffer for LittlevGL to draw the screen's content*/

    static lv_color_t buf[DISP_BUF_SIZE];

    /*Initialize a descriptor for the buffer*/

    static lv_disp_draw_buf_t disp_buf;

    lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);

    /*Initialize and register a display driver*/

    static lv_disp_drv_t disp_drv;

    lv_disp_drv_init(&disp_drv);

    disp_drv.draw_buf   = &disp_buf;

    disp_drv.flush_cb   = fbdev_flush;

    disp_drv.hor_res    = 800;

    disp_drv.ver_res    = 480;

    lv_disp_drv_register(&disp_drv);

    //输入设备初始化及注册

    evdev_init();

    static lv_indev_drv_t indev_drv_1;

    lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/

    indev_drv_1.type = LV_INDEV_TYPE_POINTER;

    /*This function will be called periodically (by the library) to get the mouse position and state*/

    indev_drv_1.read_cb = evdev_read;

    lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);


 

    //官方demo---可以换为自己的demo

    //lv_demo_widgets();

    //lv_example_switch_1();

    //lv_example_btn_1();

    // lv_example_png_1();

    //lv_example_bmp_1();

    //lv_example_freetype_1();

   

    Video_music_player();

   

// system("pwd");

    /*事物处理及告知lvgl节拍数*/

    while(1) {

        lv_timer_handler();//事务处理

        lv_tick_inc(5);//节拍累计

        usleep(5000);

    }

    return 0;

}


 

/*用户节拍获取*/

uint32_t custom_tick_get(void)

{

    static uint64_t start_ms = 0;

    if(start_ms == 0) {

        struct timeval tv_start;

        gettimeofday(&tv_start, NULL);

        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;

    }

    struct timeval tv_now;

    gettimeofday(&tv_now, NULL);

    uint64_t now_ms;

    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;

    return time_ms;

}

  • 7
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
首先,您需要了解LVGL(Light and Versatile Graphics Library)是一个用于嵌入式系统的开源图形库,它提供了一套丰富的图形界面组件。要实现一个简易计算器,您可以按照以下步骤进行: 1. 设计界面:使用LVGL提供的组件,如按钮、文本框等,设计一个计算器界面。 2. 处理用户输入:通过按钮点击或键盘输入等方式获取用户输入的数字和操作符。 3. 执行计算:根据用户输入的操作符和数字,进行相应的计算操作,得到结果。 4. 显示结果:将计算结果显示在界面上的文本框或标签中。 下面是一个简单的示例代码,演示了如何使用LVGL实现一个简易计算器: ```c #include "lvgl/lvgl.h" // 计算器界面 void create_calculator(lv_obj_t* parent) { // 创建文本框用于显示输入和结果 lv_obj_t* input_text = lv_ta_create(parent, NULL); lv_obj_t* result_text = lv_label_create(parent, NULL); // 创建数字按钮 for (int i = 0; i <= 9; i++) { char btn_label[2]; sprintf(btn_label, "%d", i); lv_obj_t* btn = lv_btn_create(parent, NULL); lv_obj_t* btn_label = lv_label_create(btn, NULL); lv_label_set_text(btn_label, btn_label); } // 创建操作符按钮(如加、减、乘、除等) // ... // 设置按钮点击事件处理函数,用于获取用户输入并进行计算 // ... } int main(void) { // 初始化LVGL lv_init(); // 创建显示屏(实际情况根据硬件平台不同可能有所差异) lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); lv_disp_drv_register(&disp_drv); // 创建主界面 lv_obj_t* main_screen = lv_obj_create(NULL, NULL); create_calculator(main_screen); lv_scr_load(main_screen); // 进入LVGL主循环 while (1) { lv_task_handler(); // 其他操作 } return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值