2015-11-04 48 views
0

我有以下管道的視頻流:gstreamer的視頻到窗口在python

發件人:

GST推出-1.0 rpicamsrc預覽= 0! 'video/x-h264,width = 1280,height = 720,framerate = 15/1,profile = high'!隊列! rtph264pay! udpsink主機= 192.168.0.8端口= 50000

接收機:

GST-發射-1.0 udpsrc端口= 50000個帽=「應用程序/ x-RTP,媒體=(字符串)視頻,時鐘 - rate =(int)90000,encoding-name =(string)H264「! rtph264depay!解碼器! autovideosink

這工作得很好,但我想這樣做在python的接收器,而直接將視頻流到一個窗口,在某種程度上是這樣的:

import gi 
gi.require_version('Gst', '1.0') 
from gi.repository import GObject, Gst, Gtk, GdkX11,GstVideo 

GObject.threads_init() 
Gst.init(None) 

class VideoReceiver: 
    def __init__(self): 

    self.window = Gtk.Window() 
    self.window.connect('destroy', self.stop) 
    self.window.set_default_size(320, 200) 

    self.drawingarea = Gtk.DrawingArea() 
    self.window.add(self.drawingarea) 

    self.window.show_all() 
    self.xid = self.drawingarea.get_property('window').get_xid() 

    self.pipeline = Gst.parse_launch ('udpsrc name=udpsrc port=50000' 
             ' caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264" ! ' 
             'rtph264depay ! decodebin ! autovideosink') 

    self.bus = self.pipeline.get_bus() 
    self.bus.add_signal_watch() 
    self.bus.connect('message::error', self.on_error) 

    self.bus.enable_sync_message_emission() 
    self.bus.connect('sync-message::element', self.on_sync_message) 

    def start(self): 
    self.pipeline.set_state(Gst.State.PLAYING) 
    Gtk.main() 

    def stop(self, window): 
    self.pipeline.set_state(Gst.State.NULL) 
    Gtk.main_quit() 

    def on_sync_message(self, bus, msg): 
    if msg.get_structure().get_name() == 'prepare-window-handle': 
     print('prepare-window-handle') 
     msg.src.set_property('force-aspect-ratio', True) 
     msg.src.set_window_handle(self.xid) 

    def on_error(self, bus, msg): 
    print('on_error():', msg.parse_error()) 

vr1=VideoReceiver() 
vr1.start() 

但窗口只是簡單的關閉時流式傳輸開始,程序結束而沒有錯誤。 任何想法可能是錯誤的,我怎樣才能將視頻輸出導入窗口?

輸出如果運行沒有根權限:

$ GST_DEBUG = 3 python3.2 test.py

** (test.py:3275): WARNING **: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files 
prepare-window-handle 
0:00:04.134038733 3275 0x1c72260 ERROR   egladaption gstegladaptation_egl.c:311:gst_egl_adaptation_create_surface:<autovideosink0-actual-sink-eglgles> Can't create surface 
0:00:04.135032949 3275 0x1c72260 ERROR   egladaption gstegladaptation.c:461:gst_egl_adaptation_init_surface:<autovideosink0-actual-sink-eglgles> Can't create surface 
0:00:04.135378104 3275 0x1c72260 ERROR   egladaption gstegladaptation.c:657:gst_egl_adaptation_init_surface:<autovideosink0-actual-sink-eglgles> Couldn't setup EGL surface 
0:00:04.135678780 3275 0x1c72260 ERROR   eglglessink gsteglglessink.c:2132:gst_eglglessink_configure_caps:<autovideosink0-actual-sink-eglgles> Couldn't init EGL surface from window 
0:00:04.135971436 3275 0x1c72260 ERROR   eglglessink gsteglglessink.c:2144:gst_eglglessink_configure_caps:<autovideosink0-actual-sink-eglgles> Configuring caps failed 
0:00:04.137130443 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
0:00:04.137830336 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
0:00:04.138175544 3275 0x1c78a60 WARN    GST_PADS gstpad.c:3620:gst_pad_peer_query:<sink:proxypad1> could not send sticky events 
0:00:04.157868139 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
0:00:04.158217826 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
0:00:04.158321940 3275 0x1c78a60 WARN    GST_PADS gstpad.c:3620:gst_pad_peer_query:<sink:proxypad1> could not send sticky events 
0:00:04.184023215 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
0:00:04.184216600 3275 0x1c78a60 WARN    GST_PADS gstpad.c:3620:gst_pad_peer_query:<sink:proxypad1> could not send sticky events 
0:00:04.185187274 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
0:00:04.185499825 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
0:00:04.186118000 3275 0x1c78a60 WARN    omxvideodec gstomxvideodec.c:2817:gst_omx_video_dec_loop:<omxh264dec-omxh264dec0> error: Internal data stream error. 
0:00:04.186551488 3275 0x1c78a60 WARN    omxvideodec gstomxvideodec.c:2817:gst_omx_video_dec_loop:<omxh264dec-omxh264dec0> error: stream stopped, reason not-negotiated 
0:00:04.187462163 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
0:00:04.187758151 3275 0x1c78a60 ERROR   eglglessink gsteglglessink.c:2167:gst_eglglessink_setcaps:<autovideosink0-actual-sink-eglgles> Failed to configure caps 
on_error(): (GError('Internal data stream error.',), 'gstomxvideodec.c(2817): gst_omx_video_dec_loop(): /GstPipeline:pipeline0/GstDecodeBin:decodebin0/GstOMXH264Dec-omxh264dec:omxh264dec-omxh264dec0:\nstream stopped, reason not-negotiated' 

輸出作爲根:

GST_DEBUG = 3須藤python3.2 test.py

** (test.py:3205): WARNING **: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files 
prepare-window-handle 

因此Gstreamer沒有錯誤,當流開始時窗口會關閉。

+0

使用GST_DEBUG = 3運行python接收器並檢查警告/錯誤..但是您是否在第二行之後沒有在parse_launch中丟失+號? – nayana

+0

不,它可以同時使用+和不使用,但我更正了代碼以使其一致。不幸的是,沒有來自Gstreamer的警告或錯誤消息,窗口只是關閉,程序在流開始時結束。 – Zorgmorduk

+0

如果我沒有sudo運行程序,那麼我確實有錯誤消息,但是當我以root身份運行時,窗口只會關閉。我會在兩種情況下發布確切的輸出。 – Zorgmorduk

回答

0

我沒有使用gtk來實現這個目的只有wxpython所以只是一些想法。
嘗試改變:

self.bus.connect('message::error', self.on_error) 

self.bus.connect('message', self.on_error) 

然後挑骨頭出來的消息還有,即

t = message.type 
if t == Gst.MessageType.ERROR: 
    error_0 = Gst.Message.parse_error (message)[0] 
    error_1 = Gst.Message.parse_error (message)[1] 
    report errors here....... 
elif t == Gst.MessageType.EOS: 
    print ("End of Audio") 
return True 

從ON_ERROR和on_sync_message總是return True
最後,
嘗試射擊set_window_handle在窗口而不是繪圖區域。