嵌入式linux中mplayer播放视频编程实践

2019-07-13 00:47发布

    用android或是QT来开发视频播放程序相对来说比较简单,如果是在linux用纯C语言来进行开发,就显得比较麻烦,好在现在有很多开源项目能够帮助我们做什么事情,mplayer就是音视频播放开源项目中典型的例子。     首先需要去mplayer官方网站mplayer下载地址下载源代码,然后使用你的交叉编译工具进行编译,编译完成后会生成一个mplayer执行程序,在命令行执行mplayer就可以进行播放了。     但是,用c语言编程来实现mplayer的播放功能怎么实现呢,本文就来讲讲一个简单的mplayer播放器的实现。 一 、 创建一个管道,进行进程间通信 int fd_fifo; int g_sock_pair[2]; //全双工管道标识符 int sock_stop_mplay[2]; char video_list[VIDEO_MAX_NUM][30]; void mplayer_init(void) { int sockID; sockID=socketpair(AF_UNIX, SOCK_STREAM, 0, g_sock_pair);//建立全双工管道 if(sockID) { printf("the pipe is not contructed "); exit(0); } else { IfPlay = FALSE;//设置标识符初始状态 IfStop = TRUE; IfPause = FALSE; IfQuit = TRUE; video_over = FALSE; } if(pipe(sock_stop_mplay)<0) { printf("stop mplay pipe create error "); return ; } }
二 、 获得视频播放目录的文件个数 int mplayer_get_video_name(void) { int i; int num; int total_num; struct dirent **namelist; char *filepath = "usr/video/"; memset(&video_list,0,sizeof(video_list)); num = scandir(filepath,&namelist,0,alphasort); printf("the video num is: %d ",num); if(num < 0)return -1; if(num > VIDEO_MAX_NUM) { num = VIDEO_MAX_NUM; } for(i=0;id_name); } total_num = num-2; return total_num; printf("video name:%s ",video_list[0]); } 三 、 mplayer播放器的实现 void video_play(void) { pid_t pid; pid_t pid1; FILE * fp; char buf[1024]; int mark = 0; //播放标志 printf("the pid is %d ",getpid()); mplayer_init(); unlink("/usr/my_fifo"); //如果管道存在,则先删除 mkfifo("/usr/my_fifo",O_CREAT|0666); perror("mkfifo"); fd_fifo=open("/usr/my_fifo",O_RDWR); int pipe_fd[2]; //用于进程ID通信 int r_num; char pipe_buf[100]; memset(pipe_buf,0,100); if(pipe(pipe_fd)<0) { printf("pipe create error "); return ; } pid = fork(); if(pid == 0) { char temp[100]; memset(temp,0,sizeof(temp)); printf("pid xxx= %d ",getpid()); sprintf(temp,"%d",getpid()); close(pipe_fd[0]); if(write(pipe_fd[1],temp,strlen(temp))!=-1) printf("child write success! "); if((pid1=fork())==0) { //close(g_sock_pair[0]); //dup2(g_sock_pair[1],1); //将子进程的标准输出重定向到管道的写端 int video_num = 0; char *videoname; int total_num; char stop_cmd[20]; total_num = mplayer_get_video_name(); while(1) { if(mark) { video_num++; printf("video_num = %d ",video_num); if(video_num >= total_num) { video_num = 0; printf("video_num more than total_num "); } } videoname = video_list[video_num]; char videopath[50] = "/storage/unit_app/video/"; char sPlay[100]="mplayer -ao alsa -vo fbdev -vc on28190 -fs -slave -quiet -input file=/storage/my_fifo "; strcat(videopath,videoname); strcat(sPlay,videopath); mplayer_background_pic(); memset(stop_cmd,0,20); printf("begin play the video! "); fp = popen(sPlay, "r"); if(fp ==NULL) { perror("popen"); exit(-1); } else { while(fgets(buf, sizeof(buf), fp)) { printf("%s", buf); } printf("one video end play "); pclose(fp); mark = 1; } usleep(30000); fcntl(sock_stop_mplay[0], F_SETFL, O_NONBLOCK); read(sock_stop_mplay[0],stop_cmd,20); if(strcmp(stop_cmd,"stop")==0) { mark = 0; printf("rev the stop cmd "); break; } printf("end the play pthread "); } exit(0); } if (waitpid(pid1, NULL, 0) != pid1) { fprintf(stderr,"Waitpid error! "); exit(-1); } exit(0); } else if(pid >0) { close(pipe_fd[1]); usleep(30000); if((r_num=read(pipe_fd[0],pipe_buf,100))>0) { printf("%d numbers read from be pipe is %s ",r_num,pipe_buf); childs_pid = atoi(&pipe_buf); } } }
四、 mplayer的结束程序 void video_stop(void) { pid_t pid; char cmd[100]; memset(cmd,0,100); sprintf(cmd,"kill -9 %d",childs_pid); char stop_cmd[20]; memset(stop_cmd,0,20); sprintf(stop_cmd,"stop"); mplayer_send_cmd("quit "); if(write(sock_stop_mplay[1],stop_cmd,strlen(stop_cmd))!=-1) printf("write stop cmd success! "); //clear_fb(); printf("kill childs_pid %d ",childs_pid); system(cmd); mplayer_del(); }
void mplayer_send_cmd(char *cmd)
{
    write(fd_fifo,cmd,strlen(cmd));
}
void mplayer_del(void)
{
    close(g_sock_pair[0]);//关闭管道
    close(g_sock_pair[1]);
    close(sock_stop_mplay[0]);
    close(sock_stop_mplay[2]);
    wait(NULL);//收集子进程信息
}
OK,只要实现上述代码,基本的mplayer播放器就可以实现了。