| 18 | gtk.gdk.threads_init() |
| 19 | |
| 20 | class GstPlayer: |
| 21 | def __init__(self, videowidget): |
| 22 | self.playing = False |
| 23 | self.player = gst.element_factory_make("playbin", "player") |
| 24 | self.videowidget = videowidget |
| 25 | self.on_eos = False |
| 26 | |
| 27 | bus = self.player.get_bus() |
| 28 | bus.enable_sync_message_emission() |
| 29 | bus.add_signal_watch() |
| 30 | bus.connect('sync-message::element', self.on_sync_message) |
| 31 | bus.connect('message', self.on_message) |
| 32 | |
| 33 | def on_sync_message(self, bus, message): |
| 34 | if message.structure is None: |
| 35 | return |
| 36 | if message.structure.get_name() == 'prepare-xwindow-id': |
| 37 | # Sync with the X server before giving the X-id to the sink |
| 38 | gtk.gdk.threads_enter() |
| 39 | gtk.gdk.display_get_default().sync() |
| 40 | self.videowidget.set_sink(message.src) |
| 41 | message.src.set_property('force-aspect-ratio', True) |
| 42 | gtk.gdk.threads_leave() |
| 43 | |
| 44 | def on_message(self, bus, message): |
| 45 | t = message.type |
| 46 | if t == gst.MESSAGE_ERROR: |
| 47 | err, debug = message.parse_error() |
| 48 | print "Error: %s" % err, debug |
| 49 | if self.on_eos: |
| 50 | self.on_eos() |
| 51 | self.playing = False |
| 52 | elif t == gst.MESSAGE_EOS: |
| 53 | if self.on_eos: |
| 54 | self.on_eos() |
| 55 | self.playing = False |
| 56 | |
| 57 | def set_location(self, location): |
| 58 | self.player.set_property('uri', location) |
| 59 | |
| 60 | def query_position(self): |
| 61 | "Returns a (position, duration) tuple" |
| 62 | try: |
| 63 | position, format = self.player.query_position(gst.FORMAT_TIME) |
| 64 | except: |
| 65 | position = gst.CLOCK_TIME_NONE |
| 66 | |
| 67 | try: |
| 68 | duration, format = self.player.query_duration(gst.FORMAT_TIME) |
| 69 | except: |
| 70 | duration = gst.CLOCK_TIME_NONE |
| 71 | |
| 72 | return (position, duration) |
| 73 | |
| 74 | def seek(self, location): |
| 75 | """ |
| 76 | @param location: time to seek to, in nanoseconds |
| 77 | """ |