linux中利用mpg123 - 实现无界面MP3播放功能

功能:暂停播放、继续播放、下一首、上一首

代码

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

void fun(int sig);

int num=0;			//记录播放到第几首
pid_t pid=0;		//定义pid全局变量,记录子进程pid
glob_t mp3= {0};	//glob_t *pglob:储存查到的信息到结构体中

int main()
{
	system("clear");

	glob("/home/xyd/music/*.mp3", 0,NULL,&mp3);	//获取指定目录下的指定格式的文件名:根据关键字查找指定的文件: *.mp3

	for(int i=0;i<mp3.gl_pathc;i++)				//mp3.gl_pathc:查到的文件的个数
	{
		printf("%d  %s\n",i,mp3.gl_pathv[i]); 	//输出查到的文件的文件名(所有的音乐名字)
	}

	pid= fork();  	//创建第一个子进程
	if(pid == 0)    //子进程中运行(第一次播放)	//默认循环播放
	{
		printf("*******************begin**************************\n");
		printf("输入:0.暂停、1.继续播放、2.下一首、3.上一首、4.退出\n");
		printf("正在播放%s 这首音乐\n",mp3.gl_pathv[num]);
		printf("********************end***************************\n");
		//alarm(20);
		execlp("mpg123", "mpg123","-q",mp3.gl_pathv[num],NULL);    //在一个进程中,执行其他的可执行程序(播放音乐)
	}

	signal(17,fun);	//检测到子进程状态发生改变,就调用fun()函数
	if(pid>0)   	//父进程中运行
	{
		while(1)	//父进程始终在while(1)中运行,当子进程状态改变时会触发中断,让其去执行fun函数,然后回来刚才位置继续向下运行
		{
			char val= '0';
			scanf("%c",&val);
			while(getchar()!='\n');


			switch(val)
			{
				case '0':		//0.暂停
					kill(pid,19);
					break;
				case '1':		//1.继续播放
					kill(pid,18);
					break;
				case '2':		//2.下一首
					num++;
					if(num== mp3.gl_pathc)	//到最后一首音乐之后就回到第一首
					{
						num=0;
					}
					kill(pid,9);
					break;
				case '3':		//3.上一首
					num-=1;
					if(num< 0)	//播放到第一首歌曲时
					{
						num=mp3.gl_pathc-1;	//回到最后一首歌曲
					}
					kill(pid,9);
					break;
				
				case '4':		//退出
					signal(17,SIG_IGN);		//解除17号信号的构造
					kill(pid,9);
					system("stty echo");	//终端回显
					printf("\033[?25h");	//显示光标
					exit(0);				//杀死父进程
					break;
				default:
					printf("input err!\n");
					break;
			}
		}
	}

    return 0;
}

void fun(int sig)
{
    int p=0;
    pid_t ret= waitpid(pid,&p,WNOHANG);	//进程等待函数:等待 pid 对应的子进程退出,并返回其pid
	if(ret == pid)				//如果杀死进程的pid与全局变量记录的pid一样的话,再进行新的子进程的创建
	{							//防止暂停等其它操作-使子进程状态改变时,就创建新的子进程
		if(WIFEXITED(p))		//正常退出时执行:循环播放
        {
            num++;
			if(num== mp3.gl_pathc)	//到最后一首音乐之后就回到第一首,进行循环播放(退出:exit(0);)
			{
				num=0;
			}
        }
		pid= fork();  			//创建新的子进程
		if(pid == 0)   		 	//子进程中运行
		{
			system("clear");
			for(int i=0;i<mp3.gl_pathc;i++)	//打印曲目
			{
				printf("%d  %s\n",i,mp3.gl_pathv[i]); 	
			}

		printf("*******************begin**************************\n");
		printf("输入:0.暂停、1.继续播放、2.下一首、3.上一首、4.退出\n");
		printf("正在播放%s 这首音乐\n",mp3.gl_pathv[num]);
		printf("********************end***************************\n");
		execlp("mpg123", "mpg123","-q",mp3.gl_pathv[num],NULL);    //在一个进程中,执行其他的可执行程序(播放音乐)
		}
	}
    
}

运行结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值