1. 程式人生 > >Linux c實現音樂播放器(madplay)

Linux c實現音樂播放器(madplay)

/*

     專案需求:

            1.實現音樂基本功能:播放,暫停及繼續,下一首,上一首,退出。

            2.自動生成歌曲列表檔案。(重定向)

            3. 實現單曲迴圈。

     思路:

            1.由於學了fork(),exec函式,想到在程序裡建立一個子程序來播放音樂。

            2.暫停及繼續,我們可以使用訊號來控制。

            3.上一首和下一首切換,用雙鏈表是最好的選擇,簡單方便。

            4.注意:一定要關閉當前的音樂播放,再放下一首,要不然會出現裝置繁忙。

*/

#include "doublelist.h"

int main()
{
	//同一個標準輸入 控制輸入
	int choose=0;
	pid_t pid;
	int flag=0; //0 停止 1 播放 2 暫停
	char pathname[]="../music/";
	char buf[50]={0};
	autofile();
	pstu head,pstr,p;
	head=LoadInfo();
	head->prev;
	pstr=head->next;
	pstr->prev=head;
	
	while(1)
    {
		system("clear");
		print_Node(head);
		printf("\t\t\t\t\t\t  ***************************************\n");
	        printf("\t\t\t\t\t\t\t          音樂播放器                \n");
	        printf("\t\t\t\t\t\t  ***************************************\n");
		printf("\t\t\t\t\t\t\t          主介面\n\n");
		printf("\t\t\t\t\t\t\t   1 播放     2 暫停/繼續\n\n");
		printf("\t\t\t\t\t\t\t   3 下一首   4 上一首\n\n");
		printf("\t\t\t\t\t\t\t   5 退出\n");
		printf("\t\t\t\t\t\t  ***************************************\n");
		scanf("%d",&choose);
		switch(choose)
		{
			 case 1:
			   {
			     //播放
				 
				 flag=1;
				 pid =fork();
				 if(pid==0)
				 {
					 close(0); 	
                                         sprintf(buf,"../music/%s",pstr->name);	
					 execlp("madplay","madplay",buf,"-r",NULL);
					 perror("execlp");
                                         exit(0);
				 }
				 
			     break;
			   }
				
			 case 2:
			     if(flag==1)
				 {
					 kill(pid,19);
					 flag=2;
				 }
				 else if(flag==2)
				 {
					 kill(pid,18);
					 flag=1;
				 }
			     break;
			 case 3:
			    {
				 kill(pid,9);
			     p=Find_DownNode(pstr);
				 if(p==NULL)
				 {
					p=head->next;
				 }
				 pstr=p;
				 flag=1;
				 pid =fork();
				 if(pid==0)
				 {
					 close(0);       //關閉標準輸入
					 sprintf(buf,"../music/%s",p->name);
					 execlp("madplay","madplay",buf,NULL);
					 perror("execlp");
					 exit(0);
				 }
			     break;
			    }
			 case 4:
			    {
				 kill(pid,9);
			     p=Find_UpNode(pstr);
				 if(p==head)
				 {
					p=head->next;
				 }
				 pstr=p;
				 flag=1;
				 pid =fork();
				 if(pid==0)
				 {
					 close(0);       //關閉標準輸入
					 sprintf(buf,"../music/%s",p->name);
					 execlp("madplay","madplay",buf,NULL);
					 perror("execlp");
					 exit(0);
				 }
			     break;
			    }
			 case 5:
			 
			     kill(pid,9);
			     exit(0);
			 default:
			 
			     printf("輸入錯誤\n");
		}
		sleep(1);
	}
	
	return 0;
}
#include "lib.h"

typedef struct node
{
	 char name[20];
	 struct node *prev;
	 struct node *next;
}stu,*pstu;

#define SIZE sizeof(stu)

pstu LoadInfo();
void print_Node(pstu head);
pstu Find_DownNode(pstu head);
pstu Find_UpNode(pstu head);
void autofile();
#include "doublelist.h"

//自動生成音樂目錄集
void autofile()
{
	system("ls ../music > ../songname");   	
}
//載入資料
pstu LoadInfo()
{
	char name[20];
	char filename[]="../songname";
	FILE *fp;
	pstu head,ptr,tmp;
	
	//建立標頭檔案
	head=calloc(1,SIZE);
	ptr=head;
	ptr->next=NULL;
	if((fp=fopen(filename,"r"))==NULL)
	{
		perror("fopen");
		exit(0);
	}
	tmp=(pstu)calloc(1,SIZE);
	
	while(fscanf(fp,"%s\n",name)!=EOF)
	{	
		strcpy(tmp->name, name);	
		ptr->next=tmp;
		tmp->prev=ptr;
		ptr = tmp;
		tmp = (pstu)calloc(1,SIZE);	
	}
        free(tmp);
	fclose(fp);  //關閉檔案,已得到儲存data資訊的連結串列head
	return head;
}
pstu Find_DownNode(pstu head)
{
	pstu p;
	p=head->next;
	return p;
}
pstu Find_UpNode(pstu head)
{
	pstu p;
	p=head->prev;
	
	return p;
}
void print_Node(pstu head)
{
	pstu ptr=head;
	pstu p=ptr->next;
	printf("\t\t\t\t\t\t\t\t 歌   單\n\n");
	printf("\t\t\t\t\t\t\t\t============== \n");
	while(p!=NULL)
	{
		printf("\t\t\t\t\t\t\t\t %s\n",p->name);		
		p=p->next;
	}	
	printf("\t\t\t\t\t\t\t\t============== \n\n");
}

 截圖:

      

 專案總結:

        做過一個單鏈表的學生管理系統和雙鏈表的音樂播放器,有個小技巧想和大家分享一下,就是在建立頭節點的時候,我一般傾向於建立一個空的頭節點,後續新增的節點直接放在頭的後面。這樣做的好處是省了對頭節點的判斷,思路簡單。