2016-11-12 7 views
1

ビデオをダイアログに表示したい。Gtkダイアログでビデオを表示する方法は?

したがって、私はGst.DrawingAreaGst.PipelineGst.Element「playbin」として作成します。

少しの例を作成しましたが、ボタン付きのウィンドウが開きます。 ボタンをクリックするとダイアログが開き、ビデオが再生されます。 しかし、私はビデオの音声しか聞こえません。

別の例では、ウィンドウとDrawingAreaだけでうまく動作します。

Gtk.Dialogに動画を表示することは可能ですか?

私はPython 3.5.2を使用しています。

編集:

#!/usr/bin/python3 

from os import path 

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

from gi.repository import GObject 


GObject.threads_init() 
Gst.init(None) 
filename = "/path/to/movie.avi" 
uri = 'file://' + filename 


class DialogExample(Gtk.Dialog): 

def __init__(self, parent): 
    Gtk.Dialog.__init__(self, "My Dialog", parent, 0, 
     (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, 
     Gtk.STOCK_OK, Gtk.ResponseType.OK)) 

    self.drawingarea = Gtk.DrawingArea.new() 

    self.drawingarea.connect('draw', self.on_draw) 
    #self.drawingarea.connect('realize', self.on_realize) 
    self.drawingarea.connect('unrealize', self.on_unrealize) 
    self.drawingarea.set_size_request(800, 600) 
    self.set_default_size(1000, 800) 

    self.btn_Play = Gtk.Button.new_with_label("Play") 
    self.btn_Play.connect('clicked', self.on_click) 

    box = self.get_content_area() 
    box.add(self.drawingarea) 
    box.add(self.btn_Play) 

    # Create GStreamer pipeline 
    self.pipeline = Gst.Pipeline() 

    # Create bus to get events from GStreamer pipeline 
    self.bus = self.pipeline.get_bus() 
    self.bus.add_signal_watch() 
    self.bus.connect('message::eos', self.on_eos) 
    self.bus.connect('message::error', self.on_error) 

    # This is needed to make the video output in our DrawingArea: 
    self.bus.enable_sync_message_emission() 
    self.bus.connect('sync-message::element', self.on_sync_message) 

    # Create GStreamer elements 
    self.playbin = Gst.ElementFactory.make('playbin', None) 

    # Add playbin to the pipeline 
    self.pipeline.add(self.playbin) 

    # Set properties 
    self.playbin.set_property('uri', uri) 

    self.show_all() 


def on_click(self, button): 
    if self.playbin.get_state(0).state == Gst.State.PAUSED: 
     self.pipeline.set_state(Gst.State.PLAYING) 
     button.set_label("Stop") 
    else: 
     self.pipeline.set_state(Gst.State.PAUSED) 
     button.set_label("Play") 

def on_realize(self, widget, data=None): 
    print("on_relaize") 

    window = widget.get_window() 
    self.xid = window.get_xid() 
    self.playbin.set_window_handle(self.xid) 


def on_draw(self, widget, cr): 
    print("ondraw", self.playbin.get_state(0).state) 
    if self.playbin.get_state(0).state < Gst.State.PAUSED: 
     allocation = widget.get_allocation() 

     cr.set_source_rgb(0, 0, 0) 
     cr.rectangle(0, 0, allocation.width, allocation.height) 
     cr.fill() 

    self.on_realize(widget) 


def on_unrealize(self, widget, data=None): 
    # to prevent racing conditions when closing the window while playing 
    self.playbin.set_state(Gst.State.NULL) 
    self.pipeline.set_state(Gst.State.NULL) 

def on_sync_message(self, bus, msg): 
    if msg.get_structure().get_name() == 'prepare-window-handle': 
     print('prepare-window-handle') 

     print('on_sync', self.xid) 

     print(msg) 
     print(msg.src) 


def on_eos(self, bus, msg): 
    print('on_eos(): seeking to start of video') 
    self.pipeline.seek_simple(
     Gst.Format.TIME, 
     Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 
     0 
    ) 

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



class DialogWindow(Gtk.Window): 

def __init__(self): 
    Gtk.Window.__init__(self, title="Dialog Example") 

    self.set_border_width(6) 

    button = Gtk.Button("Open dialog") 
    button.connect("clicked", self.on_button_clicked) 

    self.add(button) 



def on_button_clicked(self, widget): 
    dialog = DialogExample(self) 


    response = dialog.run() 

    if response == Gtk.ResponseType.OK: 
     print("The OK button was clicked") 
    elif response == Gtk.ResponseType.CANCEL: 
     print("The Cancel button was clicked") 

    dialog.destroy() 


win = DialogWindow() 
win.connect("delete-event", Gtk.main_quit) 
win.show_all() 
Gtk.main() 

編集2: UI after I pressed the play button

答えて

2

たぶんあなた描画領域が私の中で、私は同じエラーを持っているし、それを強制することを決めた... をon_realizeメソッドを呼び出していません

def on_realize(self, widget): 
    print("on realize") 
    window = widget.get_window() 
    window_handle = window.get_xid() 
    self.player.set_window_handle(window_handle) 

def on_draw(self, widget, cr): 
    print("ondraw",self.player.get_state(0).state) 
    if self.player.get_state(0).state < Gst.State.PAUSED: 
     allocation = widget.get_allocation() 

     cr.set_source_rgb(0, 0, 0) 
     cr.rectangle(0, 0, allocation.width, allocation.height) 
     cr.fill() 

    self.on_realize(widget) 

この方法では、ときにそれをfininsh:コードはこのように滞在しましたondraw、自動的に私はあなたのコードを試してみて、下記のCOMENTSにdescripted変更後、それは

#!/usr/bin/python3 

from os import path 

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

from gi.repository import GObject 


GObject.threads_init() 
Gst.init(None) 
filename = "/home/eduardo/Downloads/tears_of_steel_1080p.webm" 
uri = 'file://' + filename 


class DialogExample(Gtk.Dialog): 

    def __init__(self, parent): 
     Gtk.Dialog.__init__(self, "My Dialog", parent, 0, 
      (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, 
      Gtk.STOCK_OK, Gtk.ResponseType.OK)) 

     self.drawingarea = Gtk.DrawingArea.new() 

     self.drawingarea.connect('draw', self.on_draw) 
     self.drawingarea.connect('realize', self.on_realize) 
     self.drawingarea.connect('unrealize', self.on_unrealize) 
     self.drawingarea.set_size_request(800, 600) 
     self.set_default_size(1000, 800) 

     self.btn_Play = Gtk.Button.new_with_label("Play") 
     self.btn_Play.connect('clicked', self.on_click) 

     box = self.get_content_area() 
     box.add(self.drawingarea) 
     box.add(self.btn_Play) 

     # Create GStreamer pipeline 
     self.pipeline = Gst.Pipeline() 

     # Create bus to get events from GStreamer pipeline 
     self.bus = self.pipeline.get_bus() 
     self.bus.add_signal_watch() 
     self.bus.connect('message::eos', self.on_eos) 
     self.bus.connect('message::error', self.on_error) 

     # This is needed to make the video output in our DrawingArea: 
     self.bus.enable_sync_message_emission() 
     self.bus.connect('sync-message::element', self.on_sync_message) 

     # Create GStreamer elements 
     self.playbin = Gst.ElementFactory.make('playbin', None) 

     # Add playbin to the pipeline 
     self.pipeline.add(self.playbin) 

     # Set properties 
     self.playbin.set_property('uri', uri) 

     self.show_all() 


    def on_click(self, button): 
     if self.playbin.get_state(0).state != Gst.State.PAUSED: 
      self.pipeline.set_state(Gst.State.PLAYING) 
      button.set_label("Stop") 
     else: 
      self.pipeline.set_state(Gst.State.PAUSED) 
      button.set_label("Play") 

    def on_realize(self, widget, data=None): 
     print("on_relaize") 

     window = widget.get_window() 
     self.xid = window.get_xid() 


    def on_draw(self, widget, cr): 
     print("ondraw", self.playbin.get_state(0).state) 
     if self.playbin.get_state(0).state < Gst.State.PAUSED: 
      allocation = widget.get_allocation() 

      cr.set_source_rgb(0, 0, 0) 
      cr.rectangle(0, 0, allocation.width, allocation.height) 
      cr.fill() 

#  self.on_realize(widget) 


    def on_unrealize(self, widget, data=None): 
     # to prevent racing conditions when closing the window while playing 
     self.playbin.set_state(Gst.State.NULL) 
     self.pipeline.set_state(Gst.State.NULL) 

    def on_sync_message(self, bus, msg): 
     if msg.get_structure().get_name() == 'prepare-window-handle': 
      print('prepare-window-handle') 

      print('on_sync', self.xid) 
      self.playbin.set_window_handle(self.xid) 

      print(msg) 
      print(msg.src) 


    def on_eos(self, bus, msg): 
     print('on_eos(): seeking to start of video') 
     self.pipeline.seek_simple(
      Gst.Format.TIME, 
      Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 
      0 
     ) 

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



class DialogWindow(Gtk.Window): 

    def __init__(self): 
     Gtk.Window.__init__(self, title="Dialog Example") 

     self.set_border_width(6) 

     button = Gtk.Button("Open dialog") 
     button.connect("clicked", self.on_button_clicked) 

     self.add(button) 



    def on_button_clicked(self, widget): 
     dialog = DialogExample(self) 


     response = dialog.run() 

     if response == Gtk.ResponseType.OK: 
      print("The OK button was clicked") 
     elif response == Gtk.ResponseType.CANCEL: 
      print("The Cancel button was clicked") 

     dialog.destroy() 


win = DialogWindow() 
win.connect("delete-event", Gtk.main_quit) 
win.show_all() 
Gtk.main() 
+0

は '(これは 輸入GI gi.require_versionをlibrarysのGstをインポートあまりにも試してみてください、この方法で得た方法on_realize

を呼び出します'、' 1.0 ') gi.require_version(' Gtk '、' 3.0 ') gi.require_version(' GdkX11 '、' 3.0 ') gi.require_version(' GstVideo '、' 1.0 ') gi.repository import Gst、Gtk、GLib、GdkX11、GstVideo – user7331387

+0

上記のコード例を 'on_draw'メソッドで編集し、mi ssingsの輸入。私はGLibだけを忘れてしまった。私はまた、再生/停止ボタンを追加します。 'on_realize'メソッドは確実に呼び出されますが、ビデオは表示されず、オーディオのみが聞こえます。 あなたのプロジェクトではうまくいきますか? – EinApfelBaum

+0

プロセスのコードの部分でbuton playをクリックしてください "if self.playbin.get_state(0).state == Gst.State.PAUSED:" に変更する必要があります "if self.playbin.get_state( 0).state!= Gst.State.PLAYING: "パイプラインがNULL状態で開始します。 – user7331387

関連する問題