我是靠谱客的博主 高挑铅笔,最近开发中收集的这篇文章主要介绍嵌入式linux中mplayer播放视频编程实践,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

    用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 contructedn");
	    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 errorn");
        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: %dn",num);
	if(num < 0)return -1;
	if(num > VIDEO_MAX_NUM)
	{
	    num = VIDEO_MAX_NUM;
	}
    for(i=0;i<num-2;i++)
    {
        strcpy(video_list[i],namelist[i+2]->d_name);
    }
	total_num = num-2;
	return total_num;
	printf("video name:%s n",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 %dn",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 errorn");
        return ;
    }
	
    pid = fork();
	if(pid == 0)
	{
	    char temp[100];
		memset(temp,0,sizeof(temp));
		printf("pid xxx= %dn",getpid());
	    sprintf(temp,"%d",getpid());
		close(pipe_fd[0]);
        if(write(pipe_fd[1],temp,strlen(temp))!=-1)
        printf("child write success!n");
		
	   
	    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 = %dn",video_num);
	                if(video_num >= total_num)
		            {
		                video_num = 0;
						printf("video_num more than total_numn");
	                }
		        }			
		        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!n");
				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 playn");
		            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 n");
                    break;	    
                }	
				printf("end the play pthreadn");
            }
			exit(0);
	    }
		if (waitpid(pid1, NULL, 0) != pid1) 
        {   
            fprintf(stderr,"Waitpid error!n");   
            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 %sn",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("quitn");

	if(write(sock_stop_mplay[1],stop_cmd,strlen(stop_cmd))!=-1)
    printf("write stop cmd success!n");
	//clear_fb();
	printf("kill childs_pid %dn",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播放器就可以实现了。

最后

以上就是高挑铅笔为你收集整理的嵌入式linux中mplayer播放视频编程实践的全部内容,希望文章能够帮你解决嵌入式linux中mplayer播放视频编程实践所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部