分类:
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函数进行资源锁定,以避免冲突
i3326570602016-04-13 11:46:25
你好,这个xid = gdk_x11_drawable_get_xid(window1->window); 返回的是什么类型...如何定义这个XID呢