Linux系统下制作有界面的mp3

接上一篇文章(没有界面的mp3)这次使他添加了界面操控,使操纵更加简单

首先要用GUI工具,我用的是GUI-guider如下图

设计界面根据自己的想法来设计就好具体操作就略过重点放在代码实现

设计好自己的界面后代码生成后试运行成功后就可以进入下一步

进入播放器生成的代码文件中用code打开工程

这是我的工程目录

根据上一篇的代码基础移植到此工程即可

具体步骤如下

1.添加所需要的头文件

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <glob.h>
#include <signal.h>
#include <dirent.h>
#include <sys/stat.h>

2.创建全局变量(子进程要用)和fun函数的移植和退出函数的移植

extern int i=0;//播放歌曲的序号
extern glob_t mp3={0};
extern pid_t pid=0;
extern int flag=0;//暂停和播放的标志位

void fun (int a)
{
	if(i<0)
	{
		printf("此歌序号为最小\n");
		i=0;
	}
	if(i>=mp3.gl_pathc)
	{
		printf("此歌序号为最大\n");
		i=mp3.gl_pathc-1;
	}
	int num=0;
	pid_t p=waitpid(pid,&num,WNOHANG);//判断子进程是否是正常退出
	if(p==pid)
	{
		if(WIFEXITED(num))//正常退出,播放下一首
		{
			i++;
			if(i>=mp3.gl_pathc)
			{
				printf("已经达到最后一首歌,即将从头播放\n");
				i=0;
			}
			pid=fork();
			if(pid==0)
			{
				execlp("mpg123","mpg123",mp3.gl_pathv[i],NULL);
			}
		}
		else//不正常退出
		{
			pid=fork();
			if(pid==0)
			{
				execlp("mpg123","mpg123",mp3.gl_pathv[i],NULL);
			}
		}
	}
}
void tuichu (void)
{
	signal(17,SIG_IGN);//取消信号改造函数
	kill(pid,9);//结束进程
	system("stty echo");
	printf("\033[?25h");//回显
}

把上次无界面mp3中的主函数稍作修改插入进main函数中

int main(int argc, char ** argv)
{
    (void) argc;    /*Unused*/
    (void) argv;    /*Unused*/

    /*Initialize LittlevGL*/
    lv_init();

    /*Initialize the HAL (display, input devices, tick) for LittlevGL*/
    hal_init();

    /*Create a GUI-Guider app */
	setup_ui(&guider_ui);
    events_init(&guider_ui);
    custom_init(&guider_ui);
//从这里开始插入!!!!!!!!!!!!!!!!!!!!
	atexit(tuichu);//设置系统退出函数
	glob("/home/ping/音乐/mp3文件/*.mp3",0,NULL,&mp3);//获取mp3文件
	for(int i=0;i<mp3.gl_pathc;i++)
	{
		printf("%d\t%s\n",i,mp3.gl_pathv[i]);//打印这个目录下所有的mp3文件名
	}
	pid=fork();//创建子进程
	if(pid>0)
	{
		signal(17,fun);//信号改造函数
	}
	if(pid==0)
	{
		kill(getpid(),19);
		execlp("mpg123","mpg123",mp3.gl_pathv[i],NULL);//播放mp3音乐
		
	}
//插到这里结束!!!!!!!!!!!!!!!!!!!!!!!
    while(1) {
        /* Periodically call the lv_task handler.
         * It could be done in a timer interrupt or an OS task too.*/
        lv_task_handler();
        usleep(5 * 1000);

#ifdef SDL_APPLE
        SDL_Event event;

        while(SDL_PollEvent(&event)) {
#if USE_MOUSE != 0
            mouse_handler(&event);
#endif

#if USE_KEYBOARD
            keyboard_handler(&event);
#endif

#if USE_MOUSEWHEEL != 0
            mousewheel_handler(&event);
#endif
        }
#endif
    }

    return 0;
}

然后可以利用搜索找到你的按钮文件中进行具体操作(别忘了在此之前引用主函数的头文件和全局变量)

/*
 * Copyright 2024 NXP
 * SPDX-License-Identifier: MIT
 */

#include "events_init.h"
#include <stdio.h>
#include "lvgl/lvgl.h"
#include <stdio.h>
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <glob.h>
#include <signal.h>
#include <dirent.h>
#include <sys/stat.h>


extern int i;
extern glob_t mp3;
extern pid_t pid;
extern int flag;


void events_init(lv_ui *ui)
{
}

static void screen_imgbtn_2event_handler(lv_obj_t * obj, lv_event_t event)
{
	switch (event)
	{
	case LV_EVENT_PRESSED:
	{
		
		if(flag==0)
		{
			flag=1;
			kill(pid,18);
			printf("播放\n");
			break;
		}
		else if (flag==1)
		{
			flag=0;
			kill(pid,19);
			printf("暂停\n");
			break;
		}
	}
		break;
	default:
		break;
	}
}

static void screen_imgbtn_3event_handler(lv_obj_t * obj, lv_event_t event)
{
	switch (event)
	{
	case LV_EVENT_PRESSED:
	{
		i++;
		kill(pid,14);
		printf("下一曲\n");
		break;
	}
		break;
	default:
		break;
	}
}

static void screen_imgbtn_4event_handler(lv_obj_t * obj, lv_event_t event)
{
	switch (event)
	{
	case LV_EVENT_PRESSED:
	{
			i--;
			kill(pid,14);
			printf("上一曲\n");
			break;
	}
		break;
	default:
		break;
	}
}

void events_init_screen(lv_ui *ui)
{
	lv_obj_set_event_cb(ui->screen_imgbtn_2, screen_imgbtn_2event_handler);
	lv_obj_set_event_cb(ui->screen_imgbtn_3, screen_imgbtn_3event_handler);
	lv_obj_set_event_cb(ui->screen_imgbtn_4, screen_imgbtn_4event_handler);
}

然后在该项目这个路径下使用自带的make文件来编译此项目

出现Linking simulator之后表示编译完成生成文件然后在这个路径下启动

执行效果如下图所示

因为有设置了退出函数所以直接关闭界面也可以自动杀死子进程不会出现父进程退出子进程还在放歌的局面

  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值