如何使用gst和python创建视频聊天,并在单个gtk窗口中显示发起者和接受者的视频
我正在用gst和python开发视频聊天功能。在这个功能中,我想在一个gtk窗口里同时看到用户的摄像头画面和我自己的摄像头画面(就像empathy视频聊天那样)。
为此,我使用了gst.Tee对象,并创建了两个队列,一个连接到本地的gtk窗口,另一个则把同样的视频流连接到会话对象。
gst.Tee完成了这个任务,但也导致视频聊天的速度变慢,视频的播放比音频晚了。(我为音频会话使用了不同的流)
这里是代码片段:
self.pipeline = gst.Pipeline()
bus = self.pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', self._on_gst_message)
self.src_bin = gst.element_factory_make("autovideosrc", "src")
autovideosinkLocal = gst.element_factory_make("autovideosink", "autovideosinkLocal")
tee = gst.element_factory_make('tee', "tee")
queueLocal = gst.element_factory_make("queue", "queueLocal")
queueSend = gst.element_factory_make("queue", "queueSend")
self.pipeline.add(self.src_bin, tee, queueLocal, autovideosinkLocal, queueSend)
gst.element_link_many(self.src_bin, tee)
tee.link(queueLocal)
queueLocal.link(autovideosinkLocal)
tee.link(queueSend)
queueSend.get_pad('src').link(self.p2psession.get_property('sink-pad'))
self.pipeline.set_state(gst.STATE_PLAYING)
我该如何加快视频聊天的速度呢?(比如,如果我只使用一个接收端,只显示接受者的视频,那效果很好)
有没有其他方法可以做到这一点?
谢谢!
1 个回答
0
我本来不想回答这个问题,但因为没有其他人发言,我就试试看。
我不太确定这是否和摄像头有关(不过可能有关系),但你可以在PyGTK中为你的两个屏幕创建两个绘图区域(gtk.DrawingArea)。然后,你可以把视频连接到这些区域上。
我在我的代码中做的事情和这个类似,用来播放视频。这可能需要你创建两个独立的接收器,但老实说,我不太确定。(如果有人能进一步解释这个想法,请在评论中分享。)
这是我现在使用的代码片段(取自def __ init __)。我在Ubuntu上遇到了一点小问题(我觉得和JACK有关),但我相信这可能是特定于我的电脑的。请注意,我有一个预定义的路径。
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()
希望这对你有帮助。