⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 final_mp3.c

📁 MP3播放器项目
💻 C
字号:
#include <stdio.h>#include <unistd.h>#include <dirent.h>#include <sys/types.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/select.h>#include <sys/time.h>#include <signal.h>#include <sys/wait.h>#include <sys/shm.h>#include <sys/ipc.h>#define MAX 40#define WORD 40typedef struct list_node{    char s_name[WORD];    struct list_node *next;    struct list_node *prev;}node,*pnode;struct share{	long id_tmp;	char name_tmp[WORD];}; /* 创建双向循环链表,将歌曲添加入链表中 */ pnode create_list(char para[][40],int n)                                                      {	int i;	pnode head = NULL;	pnode new = NULL;             	pnode tmp = NULL;        head = (pnode)malloc(sizeof(node));                                               if(head == NULL){        perror("malloc");                                                                 exit(EXIT_FAILURE);                                                                    }                                                                             		head->next = NULL;                                                                    head->prev = NULL;                                                           	strcpy(head->s_name,para[0]);		tmp = head;	for(i=1; i<n; i++){		new = (pnode)malloc(sizeof(node));		if(new == NULL){			perror("malloc");			exit(EXIT_FAILURE);  		}		strcpy(new->s_name,para[i]);		tmp->next = new;		new->prev = tmp;		new->next = NULL;		tmp = new;	}	head->prev = tmp;	tmp->next = head;    return head;                                                                  }/* 遍历链表,返回当前播放歌曲所对应的节点 */pnode search_list(pnode head,char para[]){	pnode tmp = NULL;	tmp = head->next;		if(strcmp(head->s_name,para) == 0){		return head;	}	else{			while(tmp != head)		{				if (strcmp(tmp->s_name, para) == 0){				return tmp; 					}			else {				tmp= tmp->next;			}		}	}	return NULL;}/* 打印双向链表每个节点的值 */void print_list(pnode head){	pnode tmp = head->next;	printf("\nThe song of Current directory:\n\n");	printf("head:%s\n",head->s_name);	while(tmp != head){		printf("node:%s\n",tmp->s_name);		tmp = tmp->next;	}}void play(int mem_id,pnode para){	pnode node_tmp;	void *shmadd=(void *)0;	struct share *share_para;		node_tmp = para->prev;	while(1)	{		node_tmp = node_tmp->next;		if(fork() == 0){			/* 映射共享内存 */			if ((shmadd = shmat(mem_id, (void *)0, 0)) == NULL){				if (shmctl(mem_id, IPC_RMID, NULL) == -1)					perror("Failed to  remove memory segment");				exit(EXIT_FAILURE);			}				/* 将ID和歌曲名信息存入共享内存 */			share_para = (struct share *)shmadd;			strcpy(share_para->name_tmp, node_tmp->s_name);			share_para->id_tmp = getpid();						if(execlp("madplay","madplay",node_tmp->s_name,NULL)<0)				perror("execlp ");		}		else			wait(NULL);	}	}int main(int argc, char *argv[]){	int buttons_fd;  	char cwd_buf[80];	  	DIR *dir;	struct dirent *ptr;        char *p=NULL;	int i=0;	char name[MAX][WORD];  	  	pnode head;		fd_set rds;	int ret;		int key_value[6];	int key_tmp;	int key_count=1;	int id_test;	char next_name[WORD];	char prev_name[WORD];	struct share *share_tmp;	int memory_id;	pnode node_tmp;	void *shmadd=(void *)0;			buttons_fd = open("/dev/button", 0);	if (buttons_fd < 0) {		perror("open device buttons");		exit(EXIT_FAILURE);  	}		/* 获取当前目录 */  	getcwd(cwd_buf,sizeof(cwd_buf));  	  	if((dir = opendir(cwd_buf)) == NULL){  		perror("opendir");  		exit(EXIT_FAILURE);    	}		/* 遍历整个目录 */  	while((ptr = readdir(dir)) != NULL){	       /*查找后缀名为mp3的普通文件  */		if((ptr->d_type == 8) && (p=strstr(ptr->d_name,".mp3")) != NULL)			{      				strcpy(name[i++],ptr->d_name);			}	}		head = create_list(name,i);		print_list(head);		/* 父进程中使用共享内存,获取孙子进程中记录的进程ID和当前歌曲名 */	if ((memory_id = shmget(IPC_PRIVATE, sizeof(struct share), IPC_CREAT|0666)) == -1){		perror("Failed to create shared memory segment");		exit(EXIT_FAILURE);	}		if ((shmadd = shmat(memory_id, (void *)0, 0)) == NULL){		perror("shmat");		if (shmctl(memory_id, IPC_RMID, NULL) == -1)			perror("Failed to  remove memory segment");		exit(EXIT_FAILURE);	}		share_tmp = (struct share *)shmadd;		printf("\nOperations Description \n");	printf("K1 --------start play\n");	printf("K2 --------pause\n");	printf("K3 --------continue to play\n");	printf("K4 --------previous one\n");	printf("K5 --------next one\n");		for (;;) {				FD_ZERO(&rds);		FD_SET(buttons_fd, &rds);		/* 监测按键的变化 */		ret = select(buttons_fd + 1, &rds, NULL, NULL, NULL);		if (ret < 0) {			perror("select");			exit(EXIT_FAILURE);  		}		if (ret == 0) {			printf("Timeout.\n");		}		else if (FD_ISSET(buttons_fd, &rds)) {						/* 读取按键的值到数组中 */			ret = read(buttons_fd, &key_value, sizeof(key_value));			if(ret != sizeof(key_value)){				if(errno != EAGAIN){					printf("read button device failed!\n");				}				continue;			}			else{							for(i=0; i<6; i++){					if(key_value[i] == 0){						/* 记录按键值 */						key_tmp = i+1;					}				}			}		}							/*--------------------------------------start------------------------------------*/				if(key_tmp == 1){			printf("\nk1 down start\n");			if(key_count){					key_count = 0;				id_test = fork();								//该子进程控制循环播放,当一首歌曲播放完成后,创建一个新的孙子进程来播放 				if(id_test == 0){					play(memory_id,head);				}				else if(id_test >0){									}			}			else{				;			}		}       /*--------------------------------------------------------------------------------*/				if(key_tmp == 2){   //pause			printf("\nk2 down pause\n");			kill(share_tmp->id_tmp, SIGSTOP);		}				if(key_tmp == 3){   //continue			printf("\nk3 down continue\n");			kill(share_tmp->id_tmp,SIGCONT);				}       /*--------------------------------------next------------------------------------*/				if(key_tmp == 4){   //next				printf("\nk4 down next\n");			/* kill 原来的子进程和孙子进程 */			kill(share_tmp->id_tmp,SIGKILL);			kill(id_test,SIGKILL);						strcpy(next_name, share_tmp->name_tmp);			/* 获取原孙子进程歌曲名在链表中的位置 */			node_tmp = search_list(head,next_name);			if(node_tmp == NULL){				printf("only one song \n");			}				else{				/* 节点后移一位 */				node_tmp = node_tmp->next;			}			id_test = fork();						if(id_test == 0){				 play(memory_id,node_tmp);			}			else if(id_test >0){			}		}       /*------------------------------------------------------------------------------*/										/*------------------------------------------------------------------------------*/				if(key_tmp == 5){  //prev			printf("\nk5 down prev\n");			kill(share_tmp->id_tmp,SIGKILL);				kill(id_test,SIGKILL);			strcpy(prev_name,share_tmp->name_tmp);			 			node_tmp = search_list(head, prev_name);			if(node_tmp == NULL){				printf("only one song \n");			}				else{				/* 节点前移一位 */				node_tmp = node_tmp->prev;			}			id_test=fork();			if(id_test == 0){				                   play( memory_id,node_tmp);			}			else if(id_test > 0){			}		}		}	/*------------------------------------------------------------------------------*/			close(buttons_fd);  	closedir(dir);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -