最近编写一个能播放在线音乐的小工具,使用GStreamer做为播放引擎,前端用Python编写 ,使用了gst-python库,该对是对GStreamer的封装。
由于是播放在线音乐,播放前都有几秒的缓冲,程序将捕捉该事件,实时输出缓冲进度.添加事件回调函数on_message,当缓冲或播放结束等事件发生时,该函数会被调用:
self.player = gst.element_factory_make("playbin","player");
bus = self.player.get_bus();
bus.add_signal_watch();
bus.connect('message',self.on_message)
def on_message(self,bus,message);
if message.type == gst.MESSAGE_BUFFERING: #缓冲事件
struct = message.structure;
print "\nbuffering(%d)" % struct.get_int("buffer-percent");
esif: #处理其它事件
GStreamer在缓冲回调on_message时,将信息保存在message中的structure结构中的,该结构将根据不同的事件保存不同值,而gst-python暂时不提供从structure中取出缓冲进度的功能,所以就对gst-python进行了扩充,即为gst-python添加
structure.get_int()方法.
下载gst-python-0.10.7,修改gststructure.override文件,该文件是处理structure的python封装,添加以下函数:
%%
override gst_structure_get_int kwargs
static PyObject *
_wrap_gst_structure_get_int(PyGObject *self,PyObject *args,PyObject *kwargs)
{
static char *kwlist[] = { "field" ,NULL };
int ret = -1;
char *field;
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"s:GstStructure.get_int",kwlist, &field))
return NULL;
gst_structure_get_int((GstStructure*)self->obj,field,(gint *)&ret);
return PyInt_FromLong(ret);
}
%%
override gst_structure_get_int kwargs
告诉代码生成器生成一个 gst_structure_get_int方法,kwargs告诉生成器该函数支持字典调用。
当python调用该函数时,所有参数都保存在args中,必须调用PyArg_ParseTupleAndKeywords解析参数:
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"s:GstStructure.get_int",kwlist, &field))
PyArg_ParseTupleAndKeywords的说明,可以参见:
http://www.python.org/doc/1.5.2p2/ext/parseTupleAndKeywords.html
http://www.python.org/doc/1.5.2p2/ext/parseTuple.html
gst_structure_get_int((GstStructure*)self->obj,field,(gint *)&ret);
将调用GStreamer的C接口,该方法将查询field的值保存到ret中。gst_structure_get_int的说明,可参见C接口说明:
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstStructure.html
最后调用Make编译gst-python,Make程序会调用代码生成器根据*.override生成gst.c文件。
代码生成器在gst.c中新增的内容:
static const PyMethodDef _PyGstStructure_methods[] = {
...
{ "get_int", (PyCFunction)_wrap_gst_structure_get_int, METH_VARARGS|METH_KEYWORDS,
NULL },
...
}
#line 65 "gststructure.override"
static PyObject *
_wrap_gst_structure_get_int(PyGObject *self,PyObject *py_key)
{
......
}
_PyGstStructure_methods保存python接口到c接口的映射,代码生成器是根据gst.defs文件生成_PyGstStructure_methods的内容,gst.defs文件已经生成好了,所以我们不必修改。
其中kwargs将生成上面的METH_KEYWORDS表示支持字典调用.另外在gststructure.override中添加的_wrap_gst_structure_get_int方法也会添加到gst.c中.
最后make会生成_gst.so文件,通过make install完成安装。
通过以上修改,就可以向上面例子那个通过调用struct.get_int("buffer-percent")来取得进度值了。
参考:
在 Python 中封装 GObject用C语言扩展Python的功能为python编写c/c++ 的extension