设计目标:
1 实现基本的音乐播放器功能
2 显示播放列表
3 实现进度条控制音乐
4 歌词显示
功能描述:
列表选歌
播放暂停,快进快退,上下切歌
设置播放模式,播放速度
调节音量、进度条
设计方案:
多线程、互斥锁、条件变量、信号
界面效果:
文章来源:https://www.toymoban.com/news/detail-533752.html
源码文章来源地址https://www.toymoban.com/news/detail-533752.html
#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>
extern pthread_mutex_t mutex_lv;//lvgl线程锁
static char local_music_path[]="/root/player/music";//音乐路径
static char local_pic_path[]="/root/player/picture";//图片路径
static char local_words_path[]="/root/player/words";//歌词路径
static char music_path[100][1024];//音乐路径
static char pic_path[100][1024];//图片路径
static char words_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 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 *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后缀保存到数组
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.jpg", local_pic_path, name);
sprintf(words_path[music_num], "%s/%s.lrc", local_words_path, name);
//拼接图片与歌词路径↑
music_num++;
puts(music_path[music_num - 1]);
}
}
printf("检索歌单完成 共%d\n",music_num);
}
//检索本地图片
void get_pic_path()
{
//读目录,图片后缀保存到数组
DIR *dirp = opendir(local_pic_path);
if(dirp==NULL)
{
perror(local_pic_path);
return;
}
struct dirent* msg;
int pic_num=0;
while(1)
{
msg = readdir(dirp);
if(msg == NULL)break;
if(msg->d_name[0]=='.')continue;
if(strstr(msg->d_name,".png")||strstr(msg->d_name,".jpg"))
{
sprintf(pic_path[pic_num++], "S:%s/%s", local_pic_path, msg->d_name);
puts(pic_path[pic_num - 1]);
}
}
printf("检索图片完成 共%d\n",pic_num);
}
//检索歌词
void get_words_paht()
{
//读目录,lrc后缀保存到数组
DIR *dirp = opendir(local_words_path);
if(dirp==NULL)
{
perror(local_words_path);
return;
}
struct dirent* msg;
int words_num=0;
while(1)
{
msg = readdir(dirp);
if(msg == NULL)break;
if(msg->d_name[0]=='.')continue;
if(strstr(msg->d_name,".lrc"))
{
sprintf(words_path[words_num++], "%s/%s", local_words_path, msg->d_name);
puts(words_path[words_num - 1]);
}
}
printf("检索歌词完成 共%d\n",words_num);
}
//初始化字体风格
void init_font_style()
{
/*创建字体*/
static lv_ft_info_t info;
info.name = "/font/simhei.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(lv_scr_act());
//取消滚动
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 init_title_obj()
{
//在屏幕中创建一个对象
lv_obj_t * title = lv_obj_create(lv_scr_act());
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, 20);
//标题标签
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(lv_scr_act());
lv_obj_add_style(words_label, &font_style, 0);
lv_obj_align(words_label,LV_ALIGN_CENTER,0,70);
lv_label_set_text(words_label,"歌词");
}
//信号任务
void signal_10_task(int arg)
{
if (arg == 10)
{
printf("收到信号 %d 线程任务(读取mplayer)暂停\n", arg);
pthread_kill(tid_write,12); //停止写
pthread_c
到了这里,关于基于lvgl与mplayer音乐播放器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!