2016-07-05 5 views
0

Использование GStreamer «playbin» в питоне «set_window_handle» Код говорит GStreamer идентификатор окна, в котором для отображения видео:Проблемы определение GStreamer окна видео на Raspbian

Это работает в стандартной Linux Mate, а также на Raspberry Pi 3 работает Ubuntu-Mate. Однако, работая на одной и той же Малине, но используя современную ОС Raspbian, Gstreamer полностью игнорирует инструкцию для запуска в определенном окне, вместо этого она создает свое собственное окно, смахивающее в середине экрана.
Это не проблема, если новое окно могло быть обработано, перемещено и/или изменено, но оно не может. Он не может быть перемещен, он не может быть закрыт, и указатель мыши исчезает позади него.
Кто-нибудь знает, если это ошибка в Raspbian, X Windows или Gstreamer, или я не заметил каких-либо изменений, которые должны быть реализованы для этого, чтобы работать с ОС Raspbian?
Вот минимальный рабочий пример, который иллюстрирует поведение, описанное выше.

#!/usr/bin/env python 
import os,time 
import wx 
import gi 
gi.require_version('Gst', '1.0') 
gi.require_version('GstVideo', '1.0') 
from gi.repository import Gst 
from gi.repository import GstVideo 

class Player(wx.App): 

    def OnInit(self): 
     window = wx.Frame(None) 
     window.SetTitle("Gstreamer Player Test") 
     window.SetSize((-1,-1)) 
     window.Bind(wx.EVT_CLOSE,self.close) 
     vbox = wx.BoxSizer(wx.VERTICAL) 
     hbox = wx.BoxSizer(wx.HORIZONTAL) 
     self.fileid = wx.TextCtrl(window,style=wx.TE_PROCESS_ENTER) 
     self.fileid.SetToolTipString("Enter full path to media file") 
     hbox.Add(self.fileid, 1) 
     self.start = wx.Button(window,label="Start") 
     hbox.Add(self.start, 0) 
     self.start.Bind(wx.EVT_BUTTON, self.control) 
     self.fileid.Bind(wx.EVT_TEXT_ENTER, self.control) 
     vbox.Add(hbox, 0, wx.EXPAND, 0) 
     self.video_window = wx.Panel(window) 
     vbox.Add(self.video_window,1,wx.EXPAND,5) 
     window.SetSizer(vbox) 
     window.Layout() 
     window.Show() 
     self.SetTopWindow(window) 
     Gst.init(None) #initialise gstreamer 
     self.player = Gst.ElementFactory.make("playbin", "player") 
     bus = self.player.get_bus() 
     bus.add_signal_watch() #hook up bus to signals from gstreamer 
     bus.enable_sync_message_emission() 
     bus.connect('message', self.on_message) 
     bus.connect('sync-message::element', self.on_sync_message) 
     return True 

    def control(self, event): 
     if self.start.GetLabel() == "Start": 
      fileid = self.fileid.GetValue() 
      if os.path.exists(fileid): 
       self.start.SetLabel("Stop") 
       fileid = "file://"+unicode(fileid) 
       self.player.set_property('uri', fileid) 
       self.player.set_state(Gst.State.PLAYING) 
      else: 
       print "File error - No such file" 
     else: 
      self.player.set_state(Gst.State.NULL) 
      self.start.SetLabel("Start") 

    def on_message(self, bus, message): 
     t = message.type 
     if t == Gst.MessageType.EOS: # media has ended 
      self.player.set_state(Gst.State.NULL) 
      self.button.SetLabel("Start") 
     elif t == Gst.MessageType.ERROR: 
      print "Player error" 
      self.player.set_state(Gst.State.NULL) 
      self.start.SetLabel("Start") 

    def on_sync_message(self, bus, message): 
     if message.get_structure() is None: 
      return True 
     message_name = message.get_structure().get_name() 
     if message_name == 'prepare-window-handle': #Assign the window id to display in 
      imagesink = message.src 
      imagesink.set_property('force-aspect-ratio', True) #Force size to fit window 
      X_id = self.video_window.GetHandle() 
      print ("Window Id:", X_id) 
      imagesink.set_window_handle(X_id) 
     return True 

    def close(self,event): 
     self.player.set_state(Gst.State.NULL) 
     time.sleep(0.1) #Allow a little time to reach Null state 
     event.Skip() 

app = Player() 
app.MainLoop() 

ответ

0

Ответ на этот вопрос заключается в том, что это ошибка.
Bugzilla link

Является ли это в gstreamer или стеке Rpi, является спорным вопросом.
Разрешение заключается в том, чтобы указать видеоизображение в конвейере playbin.
Так что для этой конкретной программы следует читать следующим образом:

#!/usr/bin/env python 
import os,time 
import wx 
import gi 
gi.require_version('Gst', '1.0') 
gi.require_version('GstVideo', '1.0') 
from gi.repository import Gst 
from gi.repository import GstVideo 

class Player(wx.App): 

    def OnInit(self): 
     window = wx.Frame(None) 
     window.SetTitle("Gstreamer Player Test") 
     window.SetSize((-1,-1)) 
     window.Bind(wx.EVT_CLOSE,self.close) 
     vbox = wx.BoxSizer(wx.VERTICAL) 
     hbox = wx.BoxSizer(wx.HORIZONTAL) 
     self.fileid = wx.TextCtrl(window,style=wx.TE_PROCESS_ENTER) 
     self.fileid.SetToolTipString("Enter full path to media file") 
     hbox.Add(self.fileid, 1) 
     self.start = wx.Button(window,label="Start") 
     hbox.Add(self.start, 0) 
     self.start.Bind(wx.EVT_BUTTON, self.control) 
     self.fileid.Bind(wx.EVT_TEXT_ENTER, self.control) 
     vbox.Add(hbox, 0, wx.EXPAND, 0) 
     video_window = wx.Panel(window) 
     vbox.Add(video_window,1,wx.EXPAND,5) 
     window.SetSizer(vbox) 
     window.Layout() 
     window.Show() 
     self.SetTopWindow(window) 
     Gst.init(None) #initialise gstreamer 
     self.X_id = video_window.GetHandle() 
     self.player = Gst.ElementFactory.make("playbin", "player") 
#  self.ximagesink = Gst.ElementFactory.make("xvimagesink", None) 
     self.ximagesink = Gst.ElementFactory.make("ximagesink", None) 
     self.player.set_property('video-sink', self.ximagesink) 
     bus = self.player.get_bus() 
     bus.add_signal_watch() #hook up bus to signals from gstreamer 
     bus.enable_sync_message_emission() 
     bus.connect('message', self.on_message) 
     bus.connect('sync-message::element', self.on_sync_message) 
     return True 

    def control(self, event): 
     if self.start.GetLabel() == "Start": 
      fileid = self.fileid.GetValue() 
      if os.path.exists(fileid): 
       self.start.SetLabel("Stop") 
       fileid = "file://"+unicode(fileid) 
       self.player.set_property('uri', fileid) 
       self.player.set_state(Gst.State.PLAYING) 
      else: 
       print "File error - No such file" 
     else: 
      self.player.set_state(Gst.State.NULL) 
      self.start.SetLabel("Start") 

    def on_message(self, bus, message): 
     t = message.type 
     if t == Gst.MessageType.EOS: # media has ended 
      self.player.set_state(Gst.State.NULL) 
      self.button.SetLabel("Start") 
     elif t == Gst.MessageType.ERROR: 
      print "Player error" 
      self.player.set_state(Gst.State.NULL) 
      self.start.SetLabel("Start") 

    def on_sync_message(self, bus, message): 
     if message.get_structure() is None: 
      return True 
     message_name = message.get_structure().get_name() 
     if message_name == 'prepare-window-handle': #Assign the window id to display in 
      imagesink = message.src 
     #  imagesink.set_property('force-aspect-ratio', True) #Defaults anyway 
      imagesink.set_window_handle(self.X_id) 
     return True 

    def close(self,event): 
     self.player.set_state(Gst.State.NULL) 
     time.sleep(0.1) #Allow a little time to reach Null state 
     event.Skip() 

app = Player() 
app.MainLoop() 

Однако, если вы получаете тот же вопрос, используя «com.sun.star.comp.avmedia.Manager_GStreamer» в LibreOffice макрокоманды, это делает вам нехорошо, потому что разработчики Libreoffice сделали то же самое предположение, что и я, и, похоже, нет способа определить видеоизображение из Libreoffice. В этом случае нам просто придется подождать, пока исправление ошибок не вступит в общий выпуск.

Примечания: используйте ximagesink
с помощью xvimagesink дает ошибку на Raspbian, так как программное обеспечение Xv имеет вопрос, где никаких переходников не доступны.
Использование glimagesink дает нам страшное окно, застрявшее в середине экрана, и кажется, что eglesssink был спокойно уволен с работы, так как он больше не включен в плагины gstreamer на малине.

Смежные вопросы