main.c
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<time.h>
#include"MusicList.h"
#include"order.h"
int main(){
PNODE music_head = CreateMusicList();
char buf[100];
char data[100];
int cmd;
srand(time(NULL));
while(1){
printf("dai_mplayer#");
memset(buf, 0, sizeof(buf));
memset(data, 0, sizeof(data));
fgets(buf, sizeof(buf), stdin);
cmd = Analysis(buf, data);
printf("cmd:%d\n", cmd);
printf("data:%s\n", data);
order(music_head, cmd, data);
}
}
MusicList.c
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include"MusicList.h"
PNODE CreateMusicList();
void InsertMusicList(PNODE head, const char *name);
static void FreshId(PNODE head, PNODE p);
void DisplayMusicList(PNODE head);
void DeleteMusicList(PNODE head, const int id);
void ClearMusicList(PNODE head);
void DestoryMusicList(NODE **head);
static void ReadMusicList(PNODE head);
void WriteMusicList(PNODE head);
extern char * GetNameMusicList(PNODE head, int id);
extern int JudgeRepitionList(PNODE head, const char *name);
static int IsEmptyList(PNODE head);
PNODE CreateMusicList(){
PNODE head = (PNODE)malloc(sizeof(NODE));
head->name = NULL;
head->id = 0;
head->next = head;
head->prior = head;
ReadMusicList(head);
return head;
}
void InsertMusicList(PNODE head, const char *name){
printf("insertmusiclist\n");
PNODE pnew = (PNODE)malloc(sizeof(NODE));
assert(pnew);
pnew->name = (char *)malloc(strlen(name) + 1);
strcpy(pnew->name, name);
pnew->id = head->id + 1;
head->id++;
pnew->prior = head->prior;
head->prior->next = pnew;
pnew->next = head;
head->prior = pnew;
WriteMusicList(head);
}
void DeleteMusicList(PNODE head, const int id){
PNODE p = head->next;
while(p != head){
if(p->id == id){
FreshId(head,p->next);
p->next->prior = p->prior;
p->prior->next = p->next;
free(p->name);
free(p);
head->id--;
WriteMusicList(head);
return;
}
p = p->next;
}
}
static void FreshId(PNODE head, PNODE p){
while(p != head){
p->id--;
p = p->next;
}
}
void DisplayMusicList(PNODE head){
PNODE p = head->next;
while(p != head){
printf("id:%d\tmusicname:%s\n", p->id, p->name);
p = p->next;
}
return;
}
static int IsEmptyList(PNODE head){
if(head->next == head){
return 1;
}
return 0;
}
void ClearMusicList(PNODE head){
PNODE p = head->next;
while(!IsEmptyList(head)){
p->next->prior = p->prior;
p->prior->next = p->next;
free(p->name);
free(p);
p = head->next;
}
head->id =0;
}
void DestoryMusicList(NODE **head){
ClearMusicList(*head);
free(*head);
*head = NULL;
}
void ReadMusicList(PNODE head){
FILE *fp = fopen("/home/dai/Linux/project/Mplayer/music_list.txt","r");
if(fp == NULL){
return;
}
char buf[200] = {0};
while(fgets(buf, sizeof(buf), fp)){
buf[strlen(buf) - 1] = 0;
InsertMusicList(head, buf);
memset(buf, 0, sizeof(buf));
}
fclose(fp);
}
void WriteMusicList(PNODE head){
FILE *fp = fopen("/home/dai/Linux/project/Mplayer/music_list.txt", "w");
PNODE p = head->next;
while(p != head){
fputs(p->name, fp);
fputs("\n", fp);
p = p->next;
}
fclose(fp);
}
extern char * GetNameMusicList(PNODE head, int id){
PNODE p = head->next;
while(p != head){
if(p->id == id){
return p->name;
}
p = p->next;
}
return NULL;
}
extern int JudgeRepitionList(PNODE head, const char *name){
PNODE p = head->next;
while(p != head){
if(strcmp(p->name, name) == 0){
return 0;
}
p = p->next;
}
return 1;
}
MusicList.h
#ifndef _MUSICLIST_H_
#define _MUSICLIST_H_
typedef struct node{
char *name;
int id;
struct node *next;
struct node *prior;
}NODE, *PNODE;
extern PNODE CreateMusicList();
extern void InsertMusicList(PNODE head, const char *name);
extern void DisplayMusicList(PNODE head);
extern void DeleteMusicList(PNODE head, const int id);
extern void ClearMusicList(PNODE head);
extern void DestoryMusicList(NODE **head);
extern char * GetNameMusicList(PNODE head, int id);
extern int JudgeRepitionList(PNODE head, const char *name);
extern void WriteMusicList(PNODE head);
#endif
order.c
#include<string.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<dirent.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<assert.h>
#include"order.h"
#include"MusicList.h"
enum PlayStatus playstatus = STOP;
enum PlayMode playmode = LOOP;
int playindex = 0;
float music_len = 0;
float playpos = 0.0;
static void SendCmd(char *cmd);
static void AddMusic(PNODE head, char *src);
void InsertMp3(PNODE head, const char *src);
extern int Analysis(char *buf, char *src){
buf[strlen(buf) - 1] = 0;
char *p = NULL;
if(buf == NULL){
return -1;
}
if((p = strchr(buf, ' ')) != NULL){
*p = 0;
strcpy(src, p+1);
}
if(strcmp(buf, "help") == 0){
return 1;
}
else if(strcmp(buf, "list") == 0){
return 2;
}
else if(strcmp(buf, "quit") == 0){
return 3;
}
else if(strcmp(buf, "addmusic") == 0){
return 4;
}
else if(strcmp(buf, "addmusicdir") == 0){
return 5;
}
else if(strcmp(buf, "play") == 0){
if(src == NULL){
printf("music is empty\n");
return 0;
}
else{
return 6;
}
}
else if(strcmp(buf, "volume") == 0){
return 7;
}
else if(strcmp(buf, "mute") == 0){
return 8;
}
else if(strcmp(buf, "pause") == 0){
return 9;
}
else if(strcmp(buf, "seek") == 0){
return 10;
}
else if(strcmp(buf, "model") == 0){
return 11;
}
else if(strcmp(buf, "next") == 0){
return 12;
}
else if(strcmp(buf, "delete") == 0){
return 13;
}
else if(strcmp(buf, "front") == 0){
return 14;
}
else{
printf("please input help\n");
}
}
static void SendCmd(char *cmd){
if(access("fifo", F_OK)){
mkfifo("fifo", 0666);
}
printf("%s\n", cmd);
int fd = open("fifo", O_WRONLY);
write(fd, cmd, strlen(cmd));
close(fd);
}
static void AddMusic(PNODE head, char *src){
InsertMusicList(head, src);
printf("Insert Success\n");
}
void AddMusicDir(PNODE head, const char *src){
struct stat st;
int ret = stat(src, &st);
if(ret < 0){
return;
}
if(S_ISDIR(st.st_mode)){
char newname[300];
DIR *dir = opendir(src);
if(dir == NULL){
return;
}
struct dirent *ent;
while((ent = readdir(dir)) != NULL){
if(strcmp(ent->d_name, ".") ==0 || strcmp(ent->d_name, "..") == 0){
continue;
}
strcpy(newname, src);
strcat(newname, "/");
strcat(newname, ent->d_name);
AddMusicDir(head, newname);
}
}
InsertMp3(head, src);
}
void InsertMp3(PNODE head, const char *src){
char buf[10];
char *p;
if((p = strchr(src, '.')) != NULL){
strcpy(buf, p+1);
}
if(strcmp(buf, "mp3") ==0){
if(JudgeRepitionList(head, src) == 1)
InsertMusicList(head, src);
}
return;
}
void Slice(PNODE head){
char buf[200];
char *p;
if(playmode == RAND){
playindex = rand() %head->id + 1;
}
else if(playmode == LOOP){
playindex++;
if(playindex > head->id){
playindex = 1;
}
}
sprintf(buf, "loadlife %s\n", GetNameMusicList(head, playindex));
SendCmd(buf);
}
void *revicems(void *arg){
int fd = ((TT *)arg)->fd;
PNODE head = ((TT *)arg)->head;
free(arg);
char buf[200] = {0};
int ret;
char *p;
while((ret = read(fd, buf, sizeof(buf))) > 0){
if(p = strstr(buf, "ANS_LENGTH") ){
sscanf(p, "ANS_LENGTH=%f", &music_len);
printf("A:%.1f\n", music_len);
SendCmd("get_time_pos\n");
}
if(p = strstr(buf, "ANS_TIME_POSITION")){
sscanf(p, "ANS_TIME_POSITION=%f", &playpos);
printf("B:%.1f\n", playpos);
if(playstatus != PAUSE){
usleep(100000);
SendCmd("get_time_pos\n");
}
if(playstatus == SLICE){
continue;
}
if(playpos+0.2 > music_len && music_len > 0.5){
playstatus = SLICE;
Slice(head);
SendCmd("get_time_length\n");
}
}
}
}
void PlayMusic(PNODE head, char *buf){
int id =atoi(buf);
playindex = id;
char *p = NULL;
char musicname[100];
p = GetNameMusicList(head, id);
if(playstatus == STOP){
static int Pfd[2];
playstatus = PLAY;
pipe(Pfd);
pid_t pid = vfork();
if(pid < 0){
return;
}
else if(pid == 0){
if(access("fifo", F_OK)){
mkfifo("fifo", 0666);
}
close(Pfd[0]);
dup2(Pfd[1], 1);
close(2);
execl("/usr/bin/mplayer","mplayer","-slave","-idle","-quiet","-input","file=./fifo",p,NULL);
}
else{
SendCmd("get_time_length\n");
pthread_t tid1;
pthread_t tid2;
TT *p = (TT *)malloc(sizeof(TT));
assert(p);
p->fd = Pfd[0];
p->head = head;
pthread_create(&tid1, NULL, revicems, p);
}
}
else{
char cmd[100] = {0};
sprintf(cmd, "loadfile %s\n", p);
SendCmd(cmd);
SendCmd("get_time_length\n");
}
}
void VolumeMusic(char *cmd){
char buf[20];
sprintf(buf, "volume %s 1\n", cmd);
SendCmd(buf);
}
void MuteMusic(char *cmd){
char buf[10];
sprintf(buf, "mute %s\n", cmd);
SendCmd(buf);
}
void SetPlayMode(char *cmd){
int flag = atoi(cmd);
if(flag == 1){
playmode = SINGLE;
}
else if(flag == 2){
playmode = LOOP;
}
else if(flag == 3){
playmode = RAND;
}
}
void NextMusic(PNODE head){
int num = head->id;
if(playmode == LOOP || playmode == SINGLE){
playindex++;
if(playindex > num){
playindex = 1;
}
}
else{
playindex = rand() % num +1;
}
char *p =GetNameMusicList(head, playindex);
char buf[100];
sprintf(buf, "loadfile %s\n", p);
SendCmd(buf);
SendCmd("get_time_length\n");
}
void FrontMusic(PNODE head){
int num = head->id;
if(playmode == LOOP || playmode == SINGLE){
playindex--;
if(playindex == 0){
playindex = num;
}
}
else{
playindex = rand() % num +1;
}
char *p =GetNameMusicList(head, playindex);
char buf[100];
sprintf(buf, "loadfile %s\n", p);
SendCmd(buf);
SendCmd("get_time_length\n");
}
void StopMusic(){
if(playstatus == PLAY){
playstatus = PAUSE;
}
else if(playstatus == PAUSE){
playstatus = PLAY;
SendCmd("get_time_pos\n");
}
usleep(100000);
printf("AAA\n");
SendCmd("pause\n");
}
void SeekMusic(char *data){
if(music_len <= 0){
return;
}
int pos = atoi(data);
float playtime = music_len * (pos / 100.0);
float p = playtime - playpos;
char buf[50] = {0};
sprintf(buf, "seek %.1f", p);
SendCmd(buf);
}
int order(PNODE head, int cmd, char *data){
switch(cmd){
case 0:
printf("please input music name\n");
break;
case 1:
printf("help:帮助解释命令使用\nlist:查看歌曲");
break;
case 2:
DisplayMusicList(head);
break;
case 3:
if(playstatus != STOP){
SendCmd("quit\n");
}
WriteMusicList(head);
DestoryMusicList(&head);
exit(0);
case 4:
AddMusic(head, data);
break;
case 5:
AddMusicDir(head, data);
break;
case 6:
PlayMusic(head, data);
break;
case 7:
VolumeMusic(data);
break;
case 8:
MuteMusic(data);
break;
case 9:
StopMusic();
break;
case 10:
SeekMusic(data);
break;
case 11:
SetPlayMode(data);
break;
case 12:
NextMusic(head);
break;
case 13:
break;
case 14:
FrontMusic(head);
break;
}
}
order.h
#ifndef _ORDER_
#define _ORDER_
#include"MusicList.h"
enum PlayStatus{
STOP,
PLAY,
PAUSE
};
enum PlayMode{
SINGLE,
LOOP,
RAND,
SLICE
};
typedef struct T{
int fd;
PNODE head;
}TT;
extern int Analysis(char *buf, char *src);
extern int order(PNODE head, int cmd, char *data);
#endif