这是以前得课程设计内容,很长时间了。需要安装一个库
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <linux/input.h>
#include <linux/soundcard.h>
#define START 1
#define PAUSE 0
#define YES 1
#define NO 0
int remind() /*提示界面*/
{
printf("************Mp3 Player***********\n");
printf("_______remind information______\n");
printf(" 1.play\n");
printf(" 2.stop/continue\n");
printf(" 3.next\n");
printf(" 4.prev\n");
printf(" 5.exit\n");
printf("____________________________\n");
}
struct song /*歌曲结构体*/
{
pid_t id;
char music_name[50]; /* 文件名 */
struct song *next; /* 下一首 */
struct song *prior; /* 上一首 */
};
struct song *p1,*p2,*head;
struct song *shm_buf; /*共享内存的buffer*/
int shmid; /*共享内存 ID */
int NameLen;
pid_t ChildPid; /*子进程ID*/
int ContinuePauseFlag = PAUSE; /*暂停*/
struct tm *ptr;
time_t t; /*获取时间*/
void *shm_memory = (void *)0;
/************************************************************************
Function : song *create_mp3_list
Description : 创建歌曲链表
Call : fopen(),strcpy()
Call by : main()
***********************************************************************/
struct song *create_mp3_list(void)
{
FILE *list_fd; /* 文件指针 */
size_t size; /*读取文件中信息成功的返回值*/
size_t len;
struct song *p;
char *line = NULL;
system("ls /home/hk/music > /home/hk/slist.txt");
/* 打开文件 并做出错判断 */
if((list_fd = fopen("/home/hk/slist.txt","r")) == NULL)
{
perror("open song list failure!\n");
exit(1);
}
/* 为p1分配内存 */
p1 = (struct song *)malloc(sizeof(struct song));
if(NULL == p1) /*进行分配检查*/
{
printf("malloc error!\n");
exit(0);
}
/* 将文件中的len个字符传到字符指针中 一行一行的读取*/
size = getline(&line,&len,list_fd);
/* 将line复制到p1的music_name中 */
strncpy(p1->music_name,line,strlen(line));
head = p1;
/* 陆续的从文件中读取数据将其插入到歌曲链表中 双向循环链表*/
while((size =getline(&line,&len,list_fd)) != -1)
{
p2 = p1;
p1 = (struct song *)malloc(sizeof(struct song));
strncpy(p1->music_name,line,strlen(line));
p2->next = p1;
p1->prior = p2;
}
p1->next = head;
head->prior = p1;
p1 = NULL;
p2 = NULL;
return head; /* 返回双向循环链表的头结点 */
}
/********************************************************************
Function : mp3_continue_pause
Description : 实现歌曲的暂停和继续播放
Call : memcpy()
Call by : main()
**********************************************************************/
void mp3_continue_pause(struct song *CurrentMusic)
{
pid_t GrandPid;
memcpy(&GrandPid,&CurrentMusic->id,sizeof(pid_t));
if(ContinuePauseFlag == 0) /*暂停*/
{
kill(ChildPid,SIGSTOP); /*停止子进程*/
kill(GrandPid,SIGSTOP); /*停止孙子进程*/
ContinuePauseFlag = 1; /*标志位设为START*/
}
else if(ContinuePauseFlag == 1)
{
kill(ChildPid,SIGCONT);
kill(GrandPid,SIGCONT);
ContinuePauseFlag = 0;
}
}
/*****************************************************************
Function : mp3_play
Description : 歌曲的播放方法
Call : strcat()
Call by : main() :
*****************************************************************/
void mp3_play(struct song *CurrentMusic)
{
char *dir;
char dirname[40] ="/home/hk/music/"; /*歌曲路径*/
strcat(dirname,CurrentMusic->music_name); /* 在音乐文件名前加上绝对路径名 */
dir=dirname;
NameLen = strlen(dir);
dirname[NameLen - 1] = '\0'; /*在最后加结束符 \n */
execlp("madplay","madplay","-q",dirname,NULL);
perror("execlp");
}
/****************************************************************
Function : mp3_start
Description : 实现歌曲的播放
Call : mp3_play()
Call by : main()
****************************************************************/
void mp3_start(struct song *CurrentMusic)
{
pid_t GrandsonPid;
struct song *nextmusic;
memcpy(shm_buf,CurrentMusic,sizeof(struct song)); /*把current music拷到shmbuf*/
ChildPid = fork(); /*创建子进程用来控制播放列表*/
if(ChildPid < 0)
{
perror("fork failure!\n");
exit(1);
}
if(ChildPid == 0) /*子进程自动播放列表*/
{
while(1)
{
GrandsonPid = fork(); /*创建孙子进程用于播放*/
if(GrandsonPid < 0)
{
perror("create Grandson process fail!\n");
exit(1);
}
else
{
if(GrandsonPid == 0) /*孙子进程播放*/
{
t = time(NULL);
printf("%s\n",ctime(&t));
printf("Prior song is: %s\n",(shm_buf->prior)->music_name);
printf("Now is playing: %s\n",shm_buf->music_name);
printf("Next song is: %s\n",(shm_buf->next)->music_name);
mp3_play(shm_buf); /*播放*/
}
else /*父进程*/
{
shm_memory = shmat(shmid,(void *)0,0);
if(shm_memory == (void *)-1)
{
perror("shmat fail!\n");
exit(1);
}
shm_buf = (struct song *)shm_memory;
memcpy(&shm_buf->id,&GrandsonPid,sizeof(pid_t));
wait(&GrandsonPid); /*阻塞孙子进程*/
}
}
}
}
}
/********************************************************************
Function : mp3_next
Description : 实现歌曲切换到下一曲
Call : memcpy()
Call by : main()
**********************************************************************/
void mp3_next(struct song *CurrentMusic)
{
struct song *NextMusic;
pid_t GrandPid;
memcpy(&GrandPid,&CurrentMusic->id,sizeof(pid_t));
kill(ChildPid,SIGKILL);
kill(GrandPid,SIGKILL);
NextMusic = CurrentMusic;
NextMusic = NextMusic->next;
wait(NULL);
printf("the next song is %s\n",NextMusic->music_name);
mp3_start(NextMusic);
}
/*******************************************************************
Function : mp3_prior
Description : 实现歌曲切换到上一曲
Call : memcpy()
Call by : main()
********************************************************************/
void mp3_prior(struct song *CurrentMusic)
{
pid_t GrandPid;
struct song *PriorMusic;
memcpy(&GrandPid,&CurrentMusic->id,sizeof(pid_t));
kill(ChildPid,SIGKILL);
kill(GrandPid,SIGKILL);
PriorMusic = CurrentMusic;
PriorMusic = PriorMusic->prior;
wait(NULL);
mp3_start(PriorMusic);
}
/********************************************************************
Function : mp3_exit
Description : 实现exit()
Call : memcpy()
Call by : main()
**********************************************************************/
void mp3_exit(struct song *CurrentMusic)
{
pid_t GrandPid;
memcpy(&GrandPid,&CurrentMusic->id,sizeof(pid_t));
kill(ChildPid,SIGKILL);
kill(GrandPid,SIGKILL);
}
int main(void)
{
shmid = shmget(IPC_PRIVATE,sizeof(struct song),0666 | IPC_CREAT);
if(shmid < 0)
{
printf("create messge queue fail!\n");
exit(1);
}
shm_memory = shmat(shmid,(void *)0,0);
if(shm_memory == (void *)-1)
{
perror("shmat fail!\n");
exit(1);
}
shm_buf = (struct song *)shm_memory;
head = create_mp3_list(); /*回到表头*/
while(1)
{
char current_buttons[6];
int a;
remind();
printf("please enter your choose:\n");
scanf("%d",&a);
int iLevel;
switch(a)
{
case 1:
mp3_start(head);
break;
case 2:
mp3_continue_pause(shm_buf);
printf("continue/pause finished\n");
break;
case 3:
mp3_next(shm_buf);
break;
case 4:
mp3_prior(shm_buf);
break;
case 5:
mp3_exit(shm_buf);
exit(0);
}
}
return 0;
}