视频中的奇怪间歇性错误 (GStreamer)
我有一个项目,使用的是Python 2.7、PyGTK 2.24和最新版本的PyGST。
在下面的代码中,我遇到了一个奇怪的间歇性错误。第一个错误比较长,视频播放得很好,但错误只会在我关闭视频窗口后出现。第二个错误则根本不让窗口打开。
import pygtk
pygtk.require('2.0')
import gtk, pango
import pygst
pygst.require('0.10')
import gst
import Trailcrest
import os, sys
class Video:
def __init__(self):
def on_message(bus, message):
if message.type == gst.MESSAGE_EOS:
# End of Stream
player.set_state(gst.STATE_NULL)
elif message.type == gst.MESSAGE_ERROR:
player.set_state(gst.STATE_NULL)
(err, debug) = message.parse_error()
print "Error: %s" % err, debug
def on_sync_message(bus, message):
if message.structure is None:
return False
if message.structure.get_name() == "prepare-xwindow-id":
if sys.platform == "win32":
win_id = videowidget.window.handle
else:
win_id = videowidget.window.xid
assert win_id
imagesink = message.src
imagesink.set_property("force-aspect-ratio", True)
imagesink.set_xwindow_id(win_id)
win = gtk.Window()
win.set_resizable(False)
win.set_has_frame(False)
win.set_position(gtk.WIN_POS_CENTER)
fixed = gtk.Fixed()
win.add(fixed)
fixed.show()
videowidget = gtk.DrawingArea()
fixed.put(videowidget, 0, 0)
videowidget.set_size_request(640, 480)
videowidget.show()
# Setup GStreamer
player = gst.element_factory_make("playbin", "MultimediaPlayer")
bus = player.get_bus()
bus.add_signal_watch()
bus.enable_sync_message_emission()
#used to get messages that GStreamer emits
bus.connect("message", on_message)
#used for connecting video to your application
bus.connect("sync-message::element", on_sync_message)
player.set_property("uri", "file://" + os.getcwd() + "/VID/SEQ-GAME-OPEN.ogv")
player.set_state(gst.STATE_PLAYING)
win.show()
def main():
gtk.gdk.threads_init()
gtk.main()
return 0
if __name__ == "__main__":
Video()
main()
程序 'Video.py' 收到了一个 X 窗口系统的错误。这可能是程序中的一个bug。错误信息是 'BadIDChoice(为这个连接选择了无效的资源ID)'。 (详细信息:序列号 373 错误代码 14 请求代码 1 次要代码 0) (给程序员的提示:通常,X错误是异步报告的;也就是说,你会在造成错误后过一段时间才收到错误信息。为了调试你的程序,可以使用 --sync 命令行选项来改变这种行为。这样你就可以在 gdk_x_error() 函数处获得有意义的回溯信息。)
关于这个,我简单说一下……我按照说明在命令行中运行了 "python Video.py --sync"(我在使用Kubuntu),结果又收到了那个信息。
这是另一个错误——这个错误完全阻止了播放。
python: ../../src/xcb_io.c:221: poll_for_event: 断言 `(((long) (event_sequence) - (long) (dpy->request)) <= 0)' 失败。程序被中止
这两个错误会交替出现,虽然不是完全规律。我可能会先遇到三个第一个错误,然后是两个第二个错误,再来一个第一个,一个第二个,两个第一个,等等。每次都是不同的。
到底发生了什么事?
1 个回答
3
你需要和X服务器同步,才能获取窗口的xid。
下面是具体的做法:
def on_sync_message(bus, message):
if message.structure is None:
return False
if message.structure.get_name() == "prepare-xwindow-id":
gtk.gdk.threads_enter()
gtk.gdk.display_get_default().sync()
win_id = videowidget.window.xid
imagesink = message.src
imagesink.set_property("force-aspect-ratio", True)
imagesink.set_xwindow_id(win_id)
gtk.gdk.threads_leave()