Chinaunix首页 | 论坛 | 博客
  • 博客访问: 191076
  • 博文数量: 49
  • 博客积分: 2065
  • 博客等级: 大尉
  • 技术积分: 413
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-08 17:04
文章分类

全部博文(49)

文章存档

2012年(2)

2010年(17)

2009年(30)

我的朋友

分类:

2009-09-16 14:04:29

Gtk中调用Mplayer

一、Mplayer

1.         什么是Mplayer
Mplayer是Linux下的多媒体播放器,它使用简单,对常见的视频、音乐格式都支持得不错。

2.         为什么使用Mplayer
Linux下的多媒体播放器主要用xine, mplayer, gstreamer,它们各有常处

1)        mplayer安装使用都很方便,一般通过命令行调用,然后通过按键控制(空格是暂停,左右键是seek等),它自带的图形界面不是很好用

2)        xine包括lib和ui两部分(两个安装包版本需一致),一般用户通过xine-ui播放媒体,lib部分提供了完善的接口,便于二次开发,库的使用相对比较复杂

3)        gstreamer是一个播放框架加一些解码库,据说结构很好,但是普通人安装、使用和开发都比较麻烦

3.         如何使用mplayer

1)        播放普通文件
$ mplayer xxx.mp3
$ mplayer xxx.avi

2)        播放管道文件
$ mkfifo /tmp/media      // 建立管道文件
$ cat xxx.mpeg > /tmp/media &    // 把媒体文件数据写入管道一端
$ mplayer /tmp/media –cache 3000      // mplayer在缓充3M数据后开始播放
注意必须建立缓充,以支持读取数据时的小范围索引
以此类推,可以实现流媒体的播放(比如从服务上收到媒体数据写入管道一端,另一端用mplayer读取并播放)

3)        slave模式播放
slave模式时Mplayer不再按受按键控制,可使用管道向mplayer发送控制命令
它常用于mplayer被另一程序调用,在后台播放的情况
$ mkfifo /tmp/cmd
$ mplayer –slave –quiet –input file=/tmp/cmd xxx.mpeg &
$ echo “pause” > /tmp/cmd
用以下命令查看可用的控制命令
$ mplayer –input cmdlist

MPlayer 1.0rc2-4.1.2 (C) 2000-2007 MPlayer Team
CPU: SGI MIPS
Creating config file: //.mplayer/config
seek                 Float [Integer]
edl_mark           
audio_delay          Float [Integer]
speed_incr           Float
speed_mult           Float
speed_set            Float
quit                 [Integer]
pause              
frame_step         
pt_step              Integer [Integer]
pt_up_step           Integer [Integer]
alt_src_step         Integer
loop                 Integer [Integer]
sub_delay            Float [Integer]
sub_step             Integer [Integer]
osd                  [Integer]
osd_show_text        String [Integer] [Integer]
osd_show_property_te String [Integer] [Integer]
volume               Float [Integer]
balance              Float [Integer]
use_master         
mute                 [Integer]
contrast             Integer [Integer]
gamma                Integer [Integer]
brightness           Integer [Integer]
hue                  Integer [Integer]
saturation           Integer [Integer]
frame_drop           [Integer]
sub_pos              Integer [Integer]
sub_alignment        [Integer]
sub_visibility       [Integer]
sub_load             String
sub_remove           [Integer]
vobsub_lang          [Integer]
sub_select           [Integer]
sub_log            
sub_scale            Float [Integer]
get_percent_pos    
get_time_pos       
get_time_length    
get_file_name      
get_video_codec    
get_video_bitrate  
get_video_resolution
get_audio_codec    
get_audio_bitrate  
get_audio_samples  
get_meta_title     
get_meta_artist    
get_meta_album     
get_meta_year      
get_meta_comment   
get_meta_track     
get_meta_genre     
switch_audio         [Integer]
tv_start_scan      
tv_step_channel      Integer
tv_step_norm       
tv_step_chanlist   
tv_set_channel       String
tv_last_channel    
tv_set_freq          Float
tv_step_freq         Float
tv_set_norm          String
tv_set_brightness    Integer [Integer]
tv_set_contrast      Integer [Integer]
tv_set_hue           Integer [Integer]
tv_set_saturation    Integer [Integer]
forced_subs_only     [Integer]
dvb_set_channel      Integer Integer
switch_ratio         [Float]
vo_fullscreen        [Integer]
vo_ontop             [Integer]
file_filter          Integer
vo_rootwin           [Integer]
vo_border            [Integer]
screenshot           [Integer]
panscan              Float [Integer]
switch_vsync         [Integer]
loadfile             String [Integer]
loadlist             String [Integer]
run                  String
change_rectangle     Integer Integer
get_vo_fullscreen  
get_sub_visibility 
key_down_event       Integer
set_property         String String
get_property         String
step_property        String [Float] [Integer]
seek_chapter         Integer [Integer]
set_mouse_pos        Integer Integer

4.         Mplayer相关的GUI

1)        Gmplayer:Mplayer自带的GUI
一般用rpm包安装的Mplayer不带gmplayer
想使用gmplayer需要下载源码,然后在编译时加入选项 —enable-gui,编译安装后就产生了可执行程序gmplayer
想要正常运行gmplayer,还需要安装皮肤
gmplayer的控制界面和播放界面分别在两个窗口,也不是很好用

2)        Kmplayer:基于mplayer程序的播放软件
控制界面和播放界面在同一窗口中实现,看起来就像暴风影音
它只支持mplayer的部分功能,比如像设置cache的功能,这就无法实现
有局限性,代码又多,不便修改和加入自己想要的功能

3)        自己动手实现Mplayer GUI的好处

a)         做最简单的mplayer GUI:我们可以用不到200行的代码,使用gtk图形界面,给Mplayer做一个简单GUI(pause/seek/vol等功能),控制界面和播放界面在同一窗口

b)        它可以支持mplayer的所有参数及功能

c)        它可以与你自已做的应用软件结合紧密

d)        不用编译和修改mplayer的源码

二、Gtk中调用Mplayer
Mplayer可以和很多图形界面工具结合(包括framebuffer)我们以gtk为例,是因为gtk实现比较简单(qt、X、framebuffer同理)

1.         与gtk窗口结合

1)        Mplayer播放的媒体在指定窗口中显示
Mplayer的slave模式中,参数-wid可以使视频输出到指定窗体(需指明xwindowID,在XWindow桌面系统中,每个窗口创建时都被分配有唯一的ID号,它相当于一个指针)
以下代码能取得gtk窗口的xwindowID号
window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(window1);
xid = gdk_x11_drawable_get_xid(window1->window);
在播放时指在-wid后面加上十进制的xid号

2)        Mplayer播放的媒体与其它gtk控件并存
用上面的方法虽然可以指定mplayer显示窗口,但无法设置视频在该窗口中显示的位置,使得视频在整个窗口中播放,若想在屏幕中同时显示控件就会出现问题,我们用darwingarea控件来解决这个问题
drawingarea控件虽然也布局在gtkwindow窗口中的某个部分,却与gtkwindow有着不同的xwindowID, 我们用以下方法,使Mplayer显示在窗口的局部(10, 10, 200, 150)
window1 = gtk_window_new(GTK_WINDOW_TOPLEVL);
fixed1 = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window1), fixed1);
drawingarea1 = gtk_drawing_area_new();
gtk_fixed_put(GTK_FIXED(fixed1), drawingarea1, 10, 10);
gtk_widget_set_size_request(drawingarea1, 200, 150);
gtk_widget_show(drawingarea1);
gtk_widget_show(fixed1);
gtk_widget_show(window1);
xid = gtk_x11_drawable_get_xid(drawingarea1->window);

2.         命令控制Mplayer
上面提到的slave模式可以让程序通过管道控制Mplayer的播放,在程序中利用system函数运行shell命令,例如暂停
system(“echo pause >/tmp/cmd”);

3.         获取Mplayer进度信息
控制命令get_percent_pos可以让Mplayer打印出当前进度(当前进度 是Mplayer的输出信息),以ANS_PERCENT_POSITION开头,我们可以用popen的read方式来运行mplayer,从而取得 mplayer的输出信息,并做出分析,形如
if ((pp = popen(“mplayer –wid xxxx –slave –input file=/tmp/cmd”, “r”)) != NULL)
{
  while(!feof(pp))
  {
    data = gets(str, 256, pp);
    if (strncmp(str, “ANS_PERCENT_POSITION=”, 21) == 0)
    {
      pos = atoi(str+21) / 100.0;
      // 设置进度条
    }
  }
  pclose(pp);
}
这种方法不断读取可能需要使用线程,你也可以使用io_channel的方法分析mplayer输出
同时启动一个定时器,每秒执行一次以下代码,使每秒得到一次进度信息
system(“echo get_percent_pos >/tmp/cmd”);

4.         注意

1)        向mplayer发送控制命令时需要注意,任何命令都会打断当前的pause状态

2)        注意捕捉SIGPIPE信号,由于程序通过管道与Mplayer通信,当Mplayer退出时程序可能会收到SIGPIPE信号,如果不做处理,可能引起你程序的不正常退出

3)        若运行mplayer时运用了多线程,别忘了在新线程中操作界面时使用gdk_thread_xxx函数进行资源锁定,以避免冲突

阅读(2113) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

i3326570602016-04-13 11:46:25

你好,这个xid = gdk_x11_drawable_get_xid(window1->window); 返回的是什么类型...如何定义这个XID呢