mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 23:28:16 +00:00
examples/switch.py: New file, a basic demo for a single-stream switcher. Could be expanded later -- look at flumotion...
Original commit message from CVS: 2007-12-18 Andy Wingo <wingo@pobox.com> * examples/switch.py: New file, a basic demo for a single-stream switcher. Could be expanded later -- look at flumotion.component.combiners.switch.switch for some inspiration.
This commit is contained in:
parent
fb66fbf371
commit
535e724574
3 changed files with 194 additions and 1 deletions
|
@ -1,3 +1,9 @@
|
|||
2007-12-18 Andy Wingo <wingo@pobox.com>
|
||||
|
||||
* examples/switch.py: New file, a basic demo for a single-stream
|
||||
switcher. Could be expanded later -- look at
|
||||
flumotion.component.combiners.switch.switch for some inspiration.
|
||||
|
||||
2007-12-18 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* Makefile.am:
|
||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
|||
Subproject commit 67b8f4e3c576945f4d778c9040876af3a5a0756e
|
||||
Subproject commit 970759077c95ee4e85650db023ac6f974e2aa5e1
|
187
examples/switch.py
Executable file
187
examples/switch.py
Executable file
|
@ -0,0 +1,187 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- Mode: Python -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
|
||||
import sys
|
||||
|
||||
import gobject
|
||||
gobject.threads_init()
|
||||
|
||||
import pygst
|
||||
pygst.require('0.10')
|
||||
import gst
|
||||
import gst.interfaces
|
||||
import gtk
|
||||
|
||||
class SwitchTest:
|
||||
def __init__(self, videowidget):
|
||||
self.playing = False
|
||||
pipestr = ('videotestsrc pattern=0 ! queue ! s.sink0'
|
||||
' videotestsrc pattern=1 ! queue ! s.sink1'
|
||||
' switch name=s ! autovideosink')
|
||||
self.pipeline = gst.parse_launch(pipestr)
|
||||
self.videowidget = videowidget
|
||||
|
||||
bus = self.pipeline.get_bus()
|
||||
bus.enable_sync_message_emission()
|
||||
bus.add_signal_watch()
|
||||
bus.connect('sync-message::element', self.on_sync_message)
|
||||
bus.connect('message', self.on_message)
|
||||
|
||||
def on_sync_message(self, bus, message):
|
||||
if message.structure is None:
|
||||
return
|
||||
if message.structure.get_name() == 'prepare-xwindow-id':
|
||||
self.videowidget.set_sink(message.src)
|
||||
message.src.set_property('force-aspect-ratio', True)
|
||||
|
||||
def on_message(self, bus, message):
|
||||
t = message.type
|
||||
if t == gst.MESSAGE_ERROR:
|
||||
err, debug = message.parse_error()
|
||||
print "Error: %s" % err, debug
|
||||
if self.on_eos:
|
||||
self.on_eos()
|
||||
self.playing = False
|
||||
elif t == gst.MESSAGE_EOS:
|
||||
if self.on_eos:
|
||||
self.on_eos()
|
||||
self.playing = False
|
||||
|
||||
def play(self):
|
||||
self.playing = True
|
||||
gst.info("playing player")
|
||||
self.pipeline.set_state(gst.STATE_PLAYING)
|
||||
|
||||
def stop(self):
|
||||
self.pipeline.set_state(gst.STATE_NULL)
|
||||
gst.info("stopped player")
|
||||
self.playing = False
|
||||
|
||||
def get_state(self, timeout=1):
|
||||
return self.pipeline.get_state(timeout=timeout)
|
||||
|
||||
def is_playing(self):
|
||||
return self.playing
|
||||
|
||||
def switch(self, padname):
|
||||
switch = self.pipeline.get_by_name('s')
|
||||
stop_time = switch.emit('block')
|
||||
newpad = switch.get_static_pad(padname)
|
||||
start_time = newpad.get_property('running-time')
|
||||
|
||||
gst.warning('stop time = %d' % (stop_time,))
|
||||
gst.warning('stop time = %s' % (gst.TIME_ARGS(stop_time),))
|
||||
|
||||
gst.warning('start time = %d' % (start_time,))
|
||||
gst.warning('start time = %s' % (gst.TIME_ARGS(start_time),))
|
||||
|
||||
gst.warning('switching from %r to %r'
|
||||
% (switch.get_property('active-pad'), padname))
|
||||
switch.emit('switch', padname, stop_time, start_time)
|
||||
|
||||
class VideoWidget(gtk.DrawingArea):
|
||||
def __init__(self):
|
||||
gtk.DrawingArea.__init__(self)
|
||||
self.imagesink = None
|
||||
self.unset_flags(gtk.DOUBLE_BUFFERED)
|
||||
|
||||
def do_expose_event(self, event):
|
||||
if self.imagesink:
|
||||
self.imagesink.expose()
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def set_sink(self, sink):
|
||||
assert self.window.xid
|
||||
self.imagesink = sink
|
||||
self.imagesink.set_xwindow_id(self.window.xid)
|
||||
|
||||
class SwitchWindow(gtk.Window):
|
||||
UPDATE_INTERVAL = 500
|
||||
def __init__(self):
|
||||
gtk.Window.__init__(self)
|
||||
self.set_default_size(410, 325)
|
||||
|
||||
self.create_ui()
|
||||
self.player = SwitchTest(self.videowidget)
|
||||
self.populate_combobox()
|
||||
|
||||
self.update_id = -1
|
||||
self.changed_id = -1
|
||||
self.seek_timeout_id = -1
|
||||
|
||||
self.p_position = gst.CLOCK_TIME_NONE
|
||||
self.p_duration = gst.CLOCK_TIME_NONE
|
||||
|
||||
def on_delete_event():
|
||||
self.player.stop()
|
||||
gtk.main_quit()
|
||||
self.connect('delete-event', lambda *x: on_delete_event())
|
||||
|
||||
def load_file(self, location):
|
||||
self.player.set_location(location)
|
||||
|
||||
def play(self):
|
||||
self.player.play()
|
||||
|
||||
def populate_combobox(self):
|
||||
switch = self.player.pipeline.get_by_name('s')
|
||||
for i, pad in enumerate([p for p in switch.pads()
|
||||
if p.get_direction() == gst.PAD_SINK]):
|
||||
self.combobox.append_text(pad.get_name())
|
||||
if switch.get_property('active-pad') == pad.get_name():
|
||||
self.combobox.set_active(i)
|
||||
if self.combobox.get_active() == -1:
|
||||
self.combobox.set_active(0)
|
||||
|
||||
def combobox_changed(self):
|
||||
model = self.combobox.get_model()
|
||||
row = model[self.combobox.get_active()]
|
||||
padname, = row
|
||||
self.player.switch(padname)
|
||||
|
||||
def create_ui(self):
|
||||
vbox = gtk.VBox()
|
||||
self.add(vbox)
|
||||
|
||||
self.videowidget = VideoWidget()
|
||||
vbox.pack_start(self.videowidget)
|
||||
|
||||
hbox = gtk.HBox()
|
||||
vbox.pack_start(hbox, fill=False, expand=False)
|
||||
|
||||
self.combobox = combobox = gtk.combo_box_new_text()
|
||||
combobox.show()
|
||||
hbox.pack_start(combobox)
|
||||
|
||||
self.combobox.connect('changed',
|
||||
lambda *x: self.combobox_changed())
|
||||
|
||||
self.videowidget.connect_after('realize',
|
||||
lambda *x: self.play())
|
||||
|
||||
def main(args):
|
||||
def usage():
|
||||
sys.stderr.write("usage: %s\n" % args[0])
|
||||
return 1
|
||||
|
||||
# Need to register our derived widget types for implicit event
|
||||
# handlers to get called.
|
||||
gobject.type_register(SwitchWindow)
|
||||
gobject.type_register(VideoWidget)
|
||||
|
||||
if len(args) != 1:
|
||||
return usage()
|
||||
|
||||
w = SwitchWindow()
|
||||
w.show_all()
|
||||
gtk.main()
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
Loading…
Reference in a new issue