execlp("mplayer", "mplayer", "-slave", "-quiet", "-idle", "-input", "file=./cmdfifo", name, NULL);
//cmdfifo是命名管道,当写入命令数据后,mplayer自动读取执行
//name是带路径的歌曲名称
参数:
https://download.csdn.net/download/mrhjlong/9625748
自我批评:
程序应减少使用较多的全局变量,防止函数里重命名就行覆盖,产生问题。
项目整体结构还可以调整地更好、更加清晰明了。
/*************************************************************************
> File Name: mplayer.c
> Author: mrhjlong
> Mail: [email protected]
> Created Time: 2016年07月23日 星期六 15时27分19秒
************************************************************************/
#include "songplay.h"
extern int flag; //显示数据标志 1:显示 0:不显示
extern Song *pnow; //当前歌曲结点指针
extern Song *plast; //最后一个歌曲结点指针(使用的是双向链表,不是双向循环链表,可以改进)
extern int clsthread; //关闭线程标志
extern int flagpause; //暂停标志
extern int fdpp[2]; //无名管道
extern sem_t sem; //信号量
int main(void)
{
List_head *linklist = get_song_list("./");
node_print(linklist);
pnow = linklist->head;
char name[NAMESIZE] = {0};
strcat(name, "./");
strcat(name, pnow->name);
int ret = sem_init(&sem, 0, 1); //信号量初始化
if(ret == -1)
err_sys("sem_init error");
if(access("./cmdfifo", F_OK) == 0) //判断命名管道是否存在,有则删除,重新新建
{
// printf("cmdfifo exist\n");
unlink("./cmdfifo");
mkfifo("./cmdfifo", 0777);
}
else
{
mkfifo("./cmdfifo", 0777);
}
if(pipe(fdpp) < 0)
err_sys("pipe error");
fcntl(fdpp[0], F_SETFL, O_NONBLOCK); //无名管道设为非阻塞
pid_t pid = fork(); //创建进程
if(pid < 0)
err_sys("fork error");
else if(pid == 0) //子进程
{
close(fdpp[0]);
dup2(fdpp[1], 1); //将标准输出定向到无名管道的写入
execlp("mplayer", "mplayer", "-slave", "-quiet", "-idle", "-input", "file=./cmdfifo", name, NULL); //命名管道cmdfifo有命令数据,mplayer会自动读取
}
else //父进程
{
close(fdpp[1]);
sleep(1);
pthread_t get_tid1, get_tid2, get_tid3;
ret = 0;
//创建处理线程
ret = pthread_create(&get_tid1, NULL, getcmd_thread, (List_head *)linklist);
if(ret != 0)
err_sys("pthread_create error");
ret = pthread_create(&get_tid2, NULL, datacmd_thread, NULL);
if(ret != 0)
err_sys("pthread_create error");
//sleep(1);
//char data[1024] = {0};
//read(fd[0], data, 1024); //清除冗余信息
ret = pthread_create(&get_tid3, NULL, read_thread, (List_head *)linklist);
if(ret != 0)
err_sys("pthread_create error");
//等待线程结束
pthread_join(get_tid1, NULL);
pthread_join(get_tid2, NULL);
pthread_join(get_tid3, NULL);
sem_destroy(&sem); //销毁信号量
list_destroy(linklist); //销毁链表
}
//sleep(1);
return 0;
}
/*************************************************************************
> File Name: songplay.h
> Author: mrhjlong
> Mail: [email protected]
> Created Time: 2016年07月24日 星期日 13时08分01秒
************************************************************************/
#ifndef __SONGPLAY_H
#define __SONGPLAY_H
#include
#include"common.h"
#include"songplay.h"
#include
#include
#include
#include
#include
#include
#define NAMESIZE 50
struct song
{
char name[NAMESIZE];
struct song *next;
struct song *prev;
};
struct list_head
{
struct song *head;
int song_num;
};
typedef struct song Song;
typedef struct list_head List_head;
//创建链表头
List_head *head_create(void);
//创建结点
Song *node_create(char *name);
//添加结点到链表尾部
void node_insert_tail(List_head *linklist, Song *pSong);
//打印整张链表
void node_print(List_head *linklist);
//查找结点数据,返回结点地址,失败返回NULL
Song *node_search(List_head *linklist, char *name);
//销毁整张链表
void list_destroy(List_head *linklist);
//获得歌曲链表
List_head *get_song_list(char *pathname);
//带空格的歌曲名转换格式,空格前加"\"
void chgform(char *name);
//切换歌曲
void chgsong(char *name);
//处理线程读取的数据
void deal_data(char *data);
//获取按键输入命令-线程
void *getcmd_thread(void *arg);
//读取数据并处理-线程
void *read_thread(void *arg);
//定时发送命令获取数据-线程
void *datacmd_thread(void *arg);
#endif