Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/gplay.py
diff options
context:
space:
mode:
authorDaniel Drake <dsd@laptop.org>2011-02-02 16:27:46 (GMT)
committer Daniel Drake <dsd@laptop.org>2011-02-02 16:37:48 (GMT)
commit3bc80c776f7ef2578a4b9fd26028574a12982ea3 (patch)
tree890aa0ee4a2b07d9c9704883d11f0385e03a2e70 /gplay.py
parentca2bbd6d74342247de97cffa150b577246c63107 (diff)
UI rework
This is a rework of the UI that uses a more standard GTK+ principles than previously. There is still a small amount of black magic, kept away inside mediaview.py. The UI/model separation was also refined in places, and a lot of code was simplified. Overall the functionality remains identical, and I tried to keep the UI the same as before (but it is not pixel perfect). As this was quite big there may be some bugs to shake out.
Diffstat (limited to 'gplay.py')
-rw-r--r--gplay.py141
1 files changed, 63 insertions, 78 deletions
diff --git a/gplay.py b/gplay.py
index de5aac2..168fb22 100644
--- a/gplay.py
+++ b/gplay.py
@@ -18,114 +18,99 @@
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
-#look at jukeboxactivity.py
-
-import gtk
-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 gobject
-import time
-gobject.threads_init()
import logging
logger = logging.getLogger('record:gplay.py')
-import record
-
-class Gplay:
+class Gplay(gobject.GObject):
+ __gsignals__ = {
+ 'playback-status-changed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_FLOAT)),
+ }
- def __init__(self, ca):
- self.ca = ca
- self.window = None
- self.players = []
- self.playing = False
+ def __init__(self, activity_obj):
+ super(Gplay, self).__init__()
+ self.activity = activity_obj
+ self._playback_monitor_handler = None
+ self._player = gst.element_factory_make('playbin')
- self.player = gst.element_factory_make('playbin')
-
- bus = self.player.get_bus()
- bus.enable_sync_message_emission()
+ bus = self._player.get_bus()
bus.add_signal_watch()
- bus.connect('message', self._onMessageCb)
-
- def _onMessageCb(self, bus, message):
- if message.type == gst.MESSAGE_ERROR:
- err, debug = message.parse_error()
- logger.error('_onMessageCb: error=%s debug=%s' % (err, debug))
-
- def setLocation(self, location):
- if (self.player.get_property('uri') == location):
- self.seek(gst.SECOND*0)
- return
-
- self.player.set_state(gst.STATE_READY)
- self.player.set_property('uri', location)
- ext = location[len(location)-3:]
- record.Record.log.debug("setLocation: ext->"+str(ext))
- if (ext == "jpg"):
- self.pause()
+ bus.connect('message::error', self._bus_error)
+ bus.connect('message::eos', self._bus_eos)
+ def _bus_error(self, bus, message):
+ err, debug = message.parse_error()
+ logger.error('bus error=%s debug=%s' % (err, debug))
- def queryPosition(self):
- "Returns a (position, duration) tuple"
- try:
- position, format = self.player.query_position(gst.FORMAT_TIME)
- except:
- position = gst.CLOCK_TIME_NONE
+ def _bus_eos(self, bus, message):
+ self.stop()
- try:
- duration, format = self.player.query_duration(gst.FORMAT_TIME)
- except:
- duration = gst.CLOCK_TIME_NONE
+ def set_location(self, location):
+ if self._player.get_property('uri') == location:
+ self.seek(0)
+ return
- return (position, duration)
+ self._player.set_state(gst.STATE_READY)
+ self._player.set_property('uri', location)
+ def seek(self, position):
+ if position == 0:
+ location = 0
+ else:
+ duration = self._player.query_duration(gst.FORMAT_TIME, None)[0]
+ location = duration * (position / 100)
- def seek(self, location):
event = gst.event_new_seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE, gst.SEEK_TYPE_SET, location, gst.SEEK_TYPE_NONE, 0)
- res = self.player.send_event(event)
+ res = self._player.send_event(event)
if res:
- self.player.set_new_stream_time(0L)
-
+ self._player.set_new_stream_time(0L)
def pause(self):
- self.playing = False
- self.player.set_state(gst.STATE_PAUSED)
-
+ self._player.set_state(gst.STATE_PAUSED)
def play(self):
- if not self.player.props.video_sink:
+ if self.get_state() == gst.STATE_PLAYING:
+ return
+
+ if not self._player.props.video_sink:
sink = gst.element_factory_make('xvimagesink')
sink.props.force_aspect_ratio = True
- self.player.props.video_sink = sink
-
- self.player.props.video_sink.set_xwindow_id(self.window.window.xid)
- self.playing = True
- self.player.set_state(gst.STATE_PLAYING)
+ self._player.props.video_sink = sink
+ self.activity.set_gplay_sink(self._player.props.video_sink)
+ self._player.set_state(gst.STATE_PLAYING)
+ self._emit_playback_status(0)
- def stop(self):
- self.playing = False
- self.player.set_state(gst.STATE_NULL)
+ self._playback_monitor_handler = gobject.timeout_add(500, self._playback_monitor)
+ def _playback_monitor(self):
+ try:
+ position = self._player.query_position(gst.FORMAT_TIME)[0]
+ duration = self._player.query_duration(gst.FORMAT_TIME)[0]
+ except gst.QueryError:
+ return True
- def get_state(self, timeout=1):
- return self.player.get_state(timeout=timeout)
+ value = (float(position) / float(duration)) * 100.0
+ self._emit_playback_status(value)
+ return True
+ def _emit_playback_status(self, position):
+ state = self._player.get_state()[1]
+ self.emit('playback-status-changed', state, position)
- def is_playing(self):
- return self.playing
+ def get_state(self):
+ return self._player.get_state()[1]
+ def stop(self):
+ if self._playback_monitor_handler:
+ gobject.source_remove(self._playback_monitor_handler)
+ self._playback_monitor_handler = None
-class PlayVideoWindow(gtk.Window):
- def __init__(self, bgd):
- gtk.Window.__init__(self)
+ self._player.set_state(gst.STATE_NULL)
+ self._emit_playback_status(0)
- self.modify_bg( gtk.STATE_NORMAL, bgd )
- self.modify_bg( gtk.STATE_INSENSITIVE, bgd )
- self.unset_flags(gtk.DOUBLE_BUFFERED)
- self.set_flags(gtk.APP_PAINTABLE)