200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 使用进程 mplayer命令实现媒体播放器

使用进程 mplayer命令实现媒体播放器

时间:2019-04-20 11:37:29

相关推荐

使用进程 mplayer命令实现媒体播放器

本期分享的是使用进程、mplayer应用使用mplayer命令实现一个媒体播放器的功能,本次使用到的主要有进程间通信(pipe),字符串的操作,多函数功能整合等。

功能主流程图如下:

各个分支模块的流程图如下:

这个就是主流程图以及各个分支函数的细节流程图;

头文件如下:

#ifndef __HEAD_H#define __HEAD_H#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/wait.h>#include <fcntl.h>#include <unistd.h>#include <time.h>#include <dirent.h>#include <stdlib.h>#include <pthread.h>#include <signal.h>/* mplayer 媒体列表 */typedef struct __media_list__{char medialist[100][128];//播放歌曲曲目int curmedialist;//目录下歌曲个数}MediaList_t;/* mplayer 播放状态 */typedef enum __mplayer_stat__{MPLAYER_STAT_FREE,MPLAYER_STAT_PLAY,MPLAYER_STAT_PAUSE,}MplayerStat_en;/* mplayer 播放速度 */typedef enum __mplayer_speed__{MPLAYER_SPEED_ONE,MPLAYER_SPEED_TWO,MPLAYER_SPEED_FOUR,}MplayerSpeed_en;/* mplayer 播放模式 */typedef enum __mplayer_mode__{MPLAYER_MODE_SINGLE,MPLAYER_MODE_ORDER,MPLAYER_MODE_RANDOM,}MplayerMode_en;/* mplayer 当前工作状态 */typedef struct __media_stat__{MplayerStat_en curstat;MplayerSpeed_en curspeed;MplayerMode_en curmode;int curmedianum;}MediaStat_t;extern void handler(int signo);extern int showTerminal(void);extern int choiceMode(void);extern int loadMediaFile(const char *direntname);extern int listOfMusicFile(void);extern int Pause(void);extern int playMedia(char *pMediaPath);extern int playPause(void);extern int pthreadOfWork();extern int Stop(void);extern int preMusic(void);extern int nextMusic(void);extern int addSpeed(void);extern int seekPosition(void);extern int changeModeOfWork(void);extern int openLogFile(void);extern int writeLogFile(const char *errbuf);extern int closeLogFile(void);#endif

日志文件的主要实现过程:

#include "head.h"FILE *fp = NULL;int openLogFile(void){fp = fopen("./log.txt", "a");if (NULL == fp){perror("fail to fopen");return -1;}return 0;}int writeLogFile(const char *errbuf){char tmpbuf[1024] = {0};time_t t;struct tm *pp = NULL;time(&t);pp = localtime(&t);sprintf(tmpbuf, "[%d-%d-%d %02d:%02d:%02d]:%s\n", pp->tm_year+1900, pp->tm_mon+1, pp->tm_mday, pp->tm_hour, pp->tm_min, pp->tm_sec, errbuf);fwrite(tmpbuf, 1, strlen(tmpbuf), fp);return 0;}int closeLogFile(void){fclose(fp);return -1;}

所有的功能代码如下:

#include "head.h"pid_t pid;MediaList_t MediaList;//媒体列表结构体MediaStat_t MplayerStat;//媒体状态结构体//打印媒体播放器菜单int showTerminal(void){printf("============= 媒体播放器 =============\n");printf("1.查看播放列表\n");printf("2.开始/暂停\n");printf("3.停止\n");printf("4.上一曲\n");printf("5.下一曲\n");printf("6.快进\n");printf("7.定位\n");printf("8.播放方式\n");printf("9.退出\n");printf("======================================\n");return 0;}//循环打印媒体播放器菜单并进行模式选择int choiceMode(void){int n = -1;while (1){showTerminal();//显示终端printf("请选择:");scanf("%d", &n);//输入需要选择的功能序号switch (n)//条件分支进行选择执行相应功能{case 1: listOfMusicFile();break;case 2: playPause();break;case 3:Stop();break;case 4:preMusic();break;case 5: nextMusic();break;case 6: addSpeed();break;case 7: seekPosition();break;case 8: changeModeOfWork();break;case 9: exit(0);break;}}return 0;}//判断一个文件是否为媒体文件int isMediaFile(const char *filename){while (filename)//找到文件后缀的点{if (*filename == '.'){break;}filename++;}if (!strcmp(filename, ".mp3") || !strcmp(filename, ".mp4") || !strcmp(filename, ".flv") || !strcmp(filename, ".avi")){return 1;}return 0;}//加载媒体文件,使得媒体文件存入二维数组中int loadMediaFile(const char *direntname){DIR *dp = NULL;struct dirent *pp = NULL;MplayerStat.curmode = MPLAYER_MODE_ORDER;//起初初始化为顺序播放MplayerStat.curstat = MPLAYER_STAT_FREE;//起初状态设置为空闲状态MplayerStat.curmedianum = 0;//当前曲目为0dp = opendir(direntname);//打开文件夹if (NULL == dp){writeLogFile("fail to opendir");return -1;}while (1){pp = readdir(dp);//读取文件夹下的文件名if (NULL == pp)//读到没有文件时结束{break;}if (pp->d_name[0] == '.')//忽略隐藏文件{continue;}if (isMediaFile(pp->d_name))//判断是否为媒体文件{if (MediaList.curmedialist < 100){strcpy(MediaList.medialist[MediaList.curmedialist], pp->d_name);//储存该媒体文件printf("%s\n", MediaList.medialist[MediaList.curmedialist]);MediaList.curmedialist++;//媒体文件个数 +1}else{printf("播放列表加载歌曲超过100首\n");//最多存储100首break;}}}closedir(dp);return 0;}//列出目录下的所有媒体文件int listOfMusicFile(void){int n = -1;printf("============= 音乐列表 =============\n");for (n = 0;n < MediaList.curmedialist;++n){puts(MediaList.medialist[n]);}printf("====================================\n");while (1){printf("请选择(按0返回上一级):");scanf("%d", &n);if (n == 0){break;}if (MplayerStat.curstat != MPLAYER_STAT_FREE){kill(pid, SIGKILL);}playMedia(MediaList.medialist[n - 1]);MplayerStat.curmedianum = n -1;}return 0;}//实现mplayer停止功能int Pause(void){int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "pause\n", 6);close(fd);MplayerStat.curstat = MPLAYER_STAT_PAUSE;return 0;}//实现继续播放功能int Continue(void){int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "pause\n", 6);close(fd);MplayerStat.curstat = MPLAYER_STAT_PLAY;return 0;}//播放指定的媒体文件int playMedia(char *pMediaPath){printf("pMediaPath = %s\n", pMediaPath);pid = fork();if (pid < 0){writeLogFile("fail to fork");return -1;}if (pid == 0){close(1);//关闭stdoutclose(2);//关闭stderrexeclp("mplayer", "mplayer", "-slave", "-input", "file=/tmp/myfifo", pMediaPath, NULL);}MplayerStat.curstat = MPLAYER_STAT_PLAY;MplayerStat.curspeed = MPLAYER_SPEED_ONE;//wait(NULL);return 0;}//开始或者暂停播放int playPause(void){printf("进入playPause了\n");if (MplayerStat.curstat == MPLAYER_STAT_FREE){//printf("1");if (MplayerStat.curmode == MPLAYER_MODE_SINGLE){printf("当前单曲循环\n");playMedia(MediaList.medialist[MplayerStat.curmedianum]);}else if (MplayerStat.curmode == MPLAYER_MODE_ORDER){printf("当前顺序播放\n");playMedia(MediaList.medialist[MplayerStat.curmedianum + 1]);MplayerStat.curmedianum++;}else if (MplayerStat.curmode == MPLAYER_MODE_RANDOM){printf("当前随机播放\n");int ret = -1;srand(time(NULL));ret = rand() % 2;playMedia(MediaList.medialist[ret]);MplayerStat.curmedianum = ret;}}else if (MplayerStat.curstat == MPLAYER_STAT_PLAY){printf("1");Pause();}else if (MplayerStat.curstat == MPLAYER_STAT_PAUSE){printf("1");Continue();}return 0;}//停止播放int Stop(void){int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "quit\n", 5);close(fd);kill(pid, SIGKILL);MplayerStat.curstat = MPLAYER_STAT_FREE;return 0;}//切换下一曲int nextMusic(void){kill(pid, SIGKILL);playMedia(MediaList.medialist[MplayerStat.curmedianum + 1]);MplayerStat.curmedianum++;return 0;}//切换上一曲int preMusic(void){kill(pid, SIGKILL);playMedia(MediaList.medialist[MplayerStat.curmedianum - 1]);MplayerStat.curmedianum--;return 0;}//加速视频播放int addSpeed(void){int fd = -1;char cmdbuf[128] = {0};int n = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}printf("请输入你需要设置的视频速度:");scanf("%d", &n);getchar();sprintf(cmdbuf, "speed_set %d\n", n);write(fd, cmdbuf, strlen(cmdbuf));printf("当前播放%d倍速!\n", n);if (1 == n){MplayerStat.curspeed = MPLAYER_SPEED_ONE;}else if (2 == n){MplayerStat.curspeed = MPLAYER_SPEED_TWO;}else if (4 == n){MplayerStat.curspeed = MPLAYER_SPEED_FOUR;}close(fd);return 0;}//定位视频播放的位置(秒计时)int seekPosition(void){int fd = -1;char cmdbuf[128] = {0};int n = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}printf("请输入你需要跳转的位置:");scanf("%d", &n);getchar();sprintf(cmdbuf, "seek %d 2\n", n);write(fd, cmdbuf, strlen(cmdbuf));close(fd);return 0;}//切换视频的播放状态int changeModeOfWork(void){if (MplayerStat.curmode == MPLAYER_MODE_RANDOM){MplayerStat.curmode = MPLAYER_MODE_SINGLE;printf("当前单曲循环\n");}else if (MplayerStat.curmode == MPLAYER_MODE_SINGLE){MplayerStat.curmode = MPLAYER_MODE_ORDER;printf("当前顺序播放\n");}else if (MplayerStat.curmode == MPLAYER_MODE_ORDER){MplayerStat.curmode = MPLAYER_MODE_RANDOM;printf("当前随机播放\n");}return 0;}//信号处理函数void handler(int signo){int status = 0;wait(&status);//获取进程状态if (WIFSIGNALED(status))//判断进程是否被信号杀死{return;}else if (WIFEXITED(status))//判断进程是否正常结束(如果是则按照当前的播放模式继续播放下一首){MplayerStat.curstat = MPLAYER_STAT_FREE;MplayerStat.curspeed = MPLAYER_SPEED_ONE;playPause();}return;}

主函数如下:

#include "head.h"pid_t pid;MediaList_t MediaList;//媒体列表结构体MediaStat_t MplayerStat;//媒体状态结构体//打印媒体播放器菜单int showTerminal(void){printf("============= 媒体播放器 =============\n");printf("1.查看播放列表\n");printf("2.开始/暂停\n");printf("3.停止\n");printf("4.上一曲\n");printf("5.下一曲\n");printf("6.快进\n");printf("7.定位\n");printf("8.播放方式\n");printf("9.退出\n");printf("======================================\n");return 0;}//循环打印媒体播放器菜单并进行模式选择int choiceMode(void){int n = -1;while (1){showTerminal();//显示终端printf("请选择:");scanf("%d", &n);//输入需要选择的功能序号switch (n)//条件分支进行选择执行相应功能{case 1: listOfMusicFile();break;case 2: playPause();break;case 3:Stop();break;case 4:preMusic();break;case 5: nextMusic();break;case 6: addSpeed();break;case 7: seekPosition();break;case 8: changeModeOfWork();break;case 9: exit(0);break;}}return 0;}//判断一个文件是否为媒体文件int isMediaFile(const char *filename){while (filename)//找到文件后缀的点{if (*filename == '.'){break;}filename++;}if (!strcmp(filename, ".mp3") || !strcmp(filename, ".mp4") || !strcmp(filename, ".flv") || !strcmp(filename, ".avi")){return 1;}return 0;}//加载媒体文件,使得媒体文件存入二维数组中int loadMediaFile(const char *direntname){DIR *dp = NULL;struct dirent *pp = NULL;MplayerStat.curmode = MPLAYER_MODE_ORDER;//起初初始化为顺序播放MplayerStat.curstat = MPLAYER_STAT_FREE;//起初状态设置为空闲状态MplayerStat.curmedianum = 0;//当前曲目为0dp = opendir(direntname);//打开文件夹if (NULL == dp){writeLogFile("fail to opendir");return -1;}while (1){pp = readdir(dp);//读取文件夹下的文件名if (NULL == pp)//读到没有文件时结束{break;}if (pp->d_name[0] == '.')//忽略隐藏文件{continue;}if (isMediaFile(pp->d_name))//判断是否为媒体文件{if (MediaList.curmedialist < 100){strcpy(MediaList.medialist[MediaList.curmedialist], pp->d_name);//储存该媒体文件printf("%s\n", MediaList.medialist[MediaList.curmedialist]);MediaList.curmedialist++;//媒体文件个数 +1}else{printf("播放列表加载歌曲超过100首\n");//最多存储100首break;}}}closedir(dp);return 0;}//列出目录下的所有媒体文件int listOfMusicFile(void){int n = -1;printf("============= 音乐列表 =============\n");for (n = 0;n < MediaList.curmedialist;++n){puts(MediaList.medialist[n]);}printf("====================================\n");while (1){printf("请选择(按0返回上一级):");scanf("%d", &n);if (n == 0){break;}if (MplayerStat.curstat != MPLAYER_STAT_FREE){kill(pid, SIGKILL);}playMedia(MediaList.medialist[n - 1]);MplayerStat.curmedianum = n -1;}return 0;}//实现mplayer停止功能int Pause(void){int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "pause\n", 6);close(fd);MplayerStat.curstat = MPLAYER_STAT_PAUSE;return 0;}//实现继续播放功能int Continue(void){int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "pause\n", 6);close(fd);MplayerStat.curstat = MPLAYER_STAT_PLAY;return 0;}//播放指定的媒体文件int playMedia(char *pMediaPath){printf("pMediaPath = %s\n", pMediaPath);pid = fork();if (pid < 0){writeLogFile("fail to fork");return -1;}if (pid == 0){close(1);//关闭stdoutclose(2);//关闭stderrexeclp("mplayer", "mplayer", "-slave", "-input", "file=/tmp/myfifo", pMediaPath, NULL);}MplayerStat.curstat = MPLAYER_STAT_PLAY;MplayerStat.curspeed = MPLAYER_SPEED_ONE;//wait(NULL);return 0;}//开始或者暂停播放int playPause(void){printf("进入playPause了\n");if (MplayerStat.curstat == MPLAYER_STAT_FREE){//printf("1");if (MplayerStat.curmode == MPLAYER_MODE_SINGLE){printf("当前单曲循环\n");playMedia(MediaList.medialist[MplayerStat.curmedianum]);}else if (MplayerStat.curmode == MPLAYER_MODE_ORDER){printf("当前顺序播放\n");playMedia(MediaList.medialist[MplayerStat.curmedianum + 1]);MplayerStat.curmedianum++;}else if (MplayerStat.curmode == MPLAYER_MODE_RANDOM){printf("当前随机播放\n");int ret = -1;srand(time(NULL));ret = rand() % 2;playMedia(MediaList.medialist[ret]);MplayerStat.curmedianum = ret;}}else if (MplayerStat.curstat == MPLAYER_STAT_PLAY){printf("1");Pause();}else if (MplayerStat.curstat == MPLAYER_STAT_PAUSE){printf("1");Continue();}return 0;}//停止播放int Stop(void){int fd = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}write(fd, "quit\n", 5);close(fd);kill(pid, SIGKILL);MplayerStat.curstat = MPLAYER_STAT_FREE;return 0;}//切换下一曲int nextMusic(void){kill(pid, SIGKILL);playMedia(MediaList.medialist[MplayerStat.curmedianum + 1]);MplayerStat.curmedianum++;return 0;}//切换上一曲int preMusic(void){kill(pid, SIGKILL);playMedia(MediaList.medialist[MplayerStat.curmedianum - 1]);MplayerStat.curmedianum--;return 0;}//加速视频播放int addSpeed(void){int fd = -1;char cmdbuf[128] = {0};int n = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}printf("请输入你需要设置的视频速度:");scanf("%d", &n);getchar();sprintf(cmdbuf, "speed_set %d\n", n);write(fd, cmdbuf, strlen(cmdbuf));printf("当前播放%d倍速!\n", n);if (1 == n){MplayerStat.curspeed = MPLAYER_SPEED_ONE;}else if (2 == n){MplayerStat.curspeed = MPLAYER_SPEED_TWO;}else if (4 == n){MplayerStat.curspeed = MPLAYER_SPEED_FOUR;}close(fd);return 0;}//定位视频播放的位置(秒计时)int seekPosition(void){int fd = -1;char cmdbuf[128] = {0};int n = -1;fd = open("/tmp/myfifo", O_RDWR);if (-1 == fd){writeLogFile("open myfifo failed!fail to pause!");return -1;}printf("请输入你需要跳转的位置:");scanf("%d", &n);getchar();sprintf(cmdbuf, "seek %d 2\n", n);write(fd, cmdbuf, strlen(cmdbuf));close(fd);return 0;}//切换视频的播放状态int changeModeOfWork(void){if (MplayerStat.curmode == MPLAYER_MODE_RANDOM){MplayerStat.curmode = MPLAYER_MODE_SINGLE;printf("当前单曲循环\n");}else if (MplayerStat.curmode == MPLAYER_MODE_SINGLE){MplayerStat.curmode = MPLAYER_MODE_ORDER;printf("当前顺序播放\n");}else if (MplayerStat.curmode == MPLAYER_MODE_ORDER){MplayerStat.curmode = MPLAYER_MODE_RANDOM;printf("当前随机播放\n");}return 0;}//信号处理函数void handler(int signo){int status = 0;wait(&status);//获取进程状态if (WIFSIGNALED(status))//判断进程是否被信号杀死{return;}else if (WIFEXITED(status))//判断进程是否正常结束(如果是则按照当前的播放模式继续播放下一首){MplayerStat.curstat = MPLAYER_STAT_FREE;MplayerStat.curspeed = MPLAYER_SPEED_ONE;playPause();}return;}

以上就是所有的媒体播放器的相关实现过程,主要的收获有以下几个:

(1)自定义结构体与共用体的区别:结构体每个变量可以自主进行定义开辟空间,但是共用体内部变量共用一个空间,这个变量的值只能是共用体中的一个;

(2)信号处理函数的使用,当收到一个这个样的信号时该如何进行后续业务流程的处理;

以下是本项目的所有相关文件;链接:/s/1jAWbshZpsStZmbuwJ8fYIg?pwd=gsic 提取码:gsic

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。