Linux下使用被动模式调用MPlayer

Linux下使用被动模式调用MPlayer

  首先说明,虽然我已经成功地做到了调用MPlayer并给它发送命令然后读取结果,但是具体的过程细节到底是怎样的我还不是很清楚。同样是因为这样的原因,我在文中的叙述可能有技术上的错误,欢迎指正

popen()函数用于打开一个进程,返回结果是一个FILE*类型,这个返回值根据打开方式的不同,分别指向使用popen()打开的程序的输入流或输出流,可以直接当成一个普通文件来使用。

popen()的第一个函数是命令行,就是要执行的程序的命令,第二个参数可以是"r“或"w",这和fopen是差不多的,一个是读取,这时候返回结果可以当成打开的进程的输出流,另一个w就是输入,返回结果可以当成打开进程的输入流

popen()函数实际上是一个封装好的用于进程间管道通信的函数,可惜的是它的第二个参数不能是"rw",只能是r或w。因为我们要从MPlayer的输出流读取返回的信息,所以这里要使用"r“参数。

这样我们就不能直接从标准输入给MPlayer输入指令了。不过没关系,MPlayer提供了被动模式,可以从一个FIFO文件中给MPlayer输入指令。只要在调用MPlayer的时候使用 -slave -input file=path 参数就可以了

因为 -input file=path 里面的path是一个FIFO文件,所以我们必须先创建一个这样的管道。使用unlink()和mkfifo()函数就可以做到。这里我们使用/tmp/cmd作为FIFO文件,代码如下

  1. unlink("/tmp/cmd");  
  2. mkfifo("/tmp/cmd", 0777);  

之后就可以使用popen()来打开MPlayer了,代码如下

  1. FILE* mp;  
  2. mp = popen("mplayer '/home/xx/video.mkv' -quiet -slave -input file=/tmp/cmd""r");  

其中的-quiet参数是让MPlayer以静默模式运行,不要输出太多的信息,这样方便我们获取输入指令后返回的结果

MPlayer提供了一些指令,利用这些指令我们可以得到当前播放的信息和控制播放器,这些指令可以在终端中输入下面的指令查看

mplayer -input cmdlist

接下来就应该给MPlayer输入指令了。刚才已经使用mkfifo建立了管道,现在我们就把指令输入到这个管道里面,这样MPlayer就能收到指令,并输入结果了。结果我们可以在mp这个变量中通过普通的文件操作来读取出来。

在终端中输入 echo command > /tmp/cmd ,这样就可以将command写入/tmp/cmd这个FIFO文件。我们要在程序中进行写入,可以使用system()函数。现在我想给MPlayer发送一个get_time_pos指令,这个指令可以获取当前影片的播放时间,代码如下

  1. system("echo \"get_time_pos\" > /tmp/cmd");  

这样指令就发送给MPlayer了,之后我们就可以从通过mp变量这个文件指针读出MPlayer的返回信息。因为MPlayer可能返回其他不相关的播放信息,我们要精确获取get_time_pos指令返回的结果,所以不能直接就把mp中的内容读取出来,这里需要做一些判断。在终端中调用MPlayer以后试着输入get_time_pos指令,可以看到返回的结果是 ANS_TIME_POSITION=%f 这样的形式,于是代码就可以这样写

  1. double timepos;  
  2. char buf[1000];  
  3. do{  
  4.     fgets(buf, 1000, mp);  
  5. }while((strncmp(buf, "ANS_TIME_POSITION=", strlen("ANS_TIME_POSITION=")) != 0);  
  6. timepos = atof(buf + strlen("ANS_TIME_POSITION="));  

这样就完成了被动调用MPlayer,并给MPlayer发送指令然后读取信息。

实际上这就是我正在开发的字幕软件ytsub所用的方法。

最后完整的代码如下,这段代码很简单,只实现了使用被动模式调用MPlayer,然后输出当前的播放时间。头文件我忘记要包含哪些了,这里就省略了。

  1. FILE* mp;  
  2. char buf[1000];  
  3. float timepos;  
  4.   
  5. unlink("/tmp/cmd");  
  6. mkfifo("/tmp/cmd", 0777);  
  7. popen("mplayer -quiet -slave -input file=/tmp/cmd '/home/gs/test.mkv'");  
  8. //这里可能要停顿一下等待MPlayer开始播放,可以利用sleep()函数,我就不停顿了,直接输入命令了  
  9.   
  10. system("echo \"get_time_pos\" > /tmp/cmd");  
  11. do{  
  12.     fgets(buf, 1000, mp);  
  13. }while((strncmp(buf, "ANS_TIME_POSITION=", strlen("ANS_TIME_POSITION=")) != 0);  
  14. timepos = atof(buf + strlen("ANS_TIME_POSITION="));  
  15.   
  16. printf("%lf\n", timepos);  

好吧我连main()都省略了……好孩子别学我这样子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值