用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播放器就可以实现了。