diff options
author | Manuel Kaufmann <humitos@gmail.com> | 2013-01-24 18:43:24 (GMT) |
---|---|---|
committer | Gonzalo Odiard <godiard@gmail.com> | 2013-01-25 13:48:11 (GMT) |
commit | 8f43c5215ed17647b2b4e21c37eae34a4550ffb1 (patch) | |
tree | be630faa53933b5d87f7cd8c72f4e4de741df95d | |
parent | ecb1ba3ebbdbd07b8601f2cf63d7b377bf9cb59a (diff) |
Controls class modularized
All the methods related to Controls class on the JukeboxActivity were
moved to the Controls class.
Signed-off-by: Manuel Kaufmann <humitos@gmail.com>
-rw-r--r-- | activity.py | 132 | ||||
-rw-r--r-- | controls.py | 152 | ||||
-rw-r--r-- | player.py | 3 |
3 files changed, 152 insertions, 135 deletions
diff --git a/activity.py b/activity.py index d0e0308..8fde33c 100644 --- a/activity.py +++ b/activity.py @@ -40,7 +40,6 @@ gi.require_version('Gst', '1.0') from gi.repository import GObject from gi.repository import Gdk from gi.repository import Gtk -from gi.repository import Gst from gi.repository import Gio from viewtoolbar import ViewToolbar @@ -53,7 +52,6 @@ PLAYLIST_WIDTH_PROP = 1.0 / 3 class JukeboxActivity(activity.Activity): - UPDATE_INTERVAL = 500 __gsignals__ = { 'no-stream': (GObject.SignalFlags.RUN_FIRST, None, []), @@ -88,10 +86,6 @@ class JukeboxActivity(activity.Activity): toolbar_box.toolbar.insert(view_toolbar_button, -1) view_toolbar_button.show() - self.control = Controls(toolbar_box.toolbar, self) - - toolbar_box.toolbar.insert(StopButton(self), -1) - self.set_toolbar_box(toolbar_box) toolbar_box.show_all() @@ -102,11 +96,6 @@ class JukeboxActivity(activity.Activity): # reproducing the video self.connect('notify::active', self.__notify_active_cb) - self.update_id = -1 - self.changed_id = -1 - self.seek_timeout_id = -1 - self.player = None - self.canvas = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self.playlist_widget = PlayList() @@ -114,6 +103,17 @@ class JukeboxActivity(activity.Activity): self.playlist_widget.show() self.canvas.pack_start(self.playlist_widget, False, True, 0) + # Create the player just once + logging.debug('Instantiating GstPlayer') + self.player = GstPlayer() + self.player.connect('eos', self.__player_eos_cb) + self.player.connect('error', self.__player_error_cb) + self.player.connect('play', self.__player_play_cb) + + self.control = Controls(self, toolbar_box.toolbar) + + toolbar_box.toolbar.insert(StopButton(self), -1) + self._empty_widget = Gtk.Label(label="") self._empty_widget.show() self.videowidget = VideoWidget() @@ -122,15 +122,7 @@ class JukeboxActivity(activity.Activity): self.show_all() self.canvas.connect('size-allocate', self.__size_allocate_cb) - # Create the player just once - logging.debug('Instantiating GstPlayer') - self.player = GstPlayer(self.videowidget) - self.player.connect('eos', self.__player_eos_cb) - self.player.connect('error', self.__player_error_cb) - self.player.connect('play', self.__player_play_cb) - - self.p_position = Gst.CLOCK_TIME_NONE - self.p_duration = Gst.CLOCK_TIME_NONE + self.player.init_view_area(self.videowidget) volume_monitor = Gio.VolumeMonitor.get() volume_monitor.connect('mount-added', self.__mount_added_cb) @@ -188,20 +180,9 @@ class JukeboxActivity(activity.Activity): return False if keyname == "space": - self.play_toggled() + self.control._button_clicked_cb(None) return True - def check_if_next_prev(self): - current_playing = self.playlist_widget._current_playing - if current_playing == 0: - self.control.prev_button.set_sensitive(False) - else: - self.control.prev_button.set_sensitive(True) - if current_playing == len(self.playlist_widget._items) - 1: - self.control.next_button.set_sensitive(False) - else: - self.control.next_button.set_sensitive(True) - def songchange(self, direction): current_playing = self.playlist_widget._current_playing if direction == 'prev' and current_playing > 0: @@ -221,7 +202,7 @@ class JukeboxActivity(activity.Activity): self.playlist_widget._current_playing = index path = self.playlist_widget._items[index]['path'] - self.check_if_next_prev() + self.control.check_if_next_prev() self.player.set_uri(path) self.player.play() @@ -232,7 +213,7 @@ class JukeboxActivity(activity.Activity): # self._switch_canvas(show_video=True) self.playlist_widget._current_playing = index - self.check_if_next_prev() + self.control.check_if_next_prev() self.player.set_uri(path) self.player.play() @@ -343,89 +324,6 @@ class JukeboxActivity(activity.Activity): write_playlist_to_file(self._playlist_jobject.file_path) datastore.write(self._playlist_jobject) - def play_toggled(self): - self.control.set_enabled() - - if self.player.is_playing(): - self.player.pause() - self.control.set_button_play() - else: - if self.player.error: - self.control.set_disabled() - else: - self.player.play() - if self.update_id == -1: - self.update_id = GObject.timeout_add(self.UPDATE_INTERVAL, - self.update_scale_cb) - self.control.set_button_pause() - - def scale_button_press_cb(self, widget, event): - self.control.button.set_sensitive(False) - self.was_playing = self.player.is_playing() - if self.was_playing: - self.player.pause() - - # don't timeout-update position during seek - if self.update_id != -1: - GObject.source_remove(self.update_id) - self.update_id = -1 - - # make sure we get changed notifies - if self.changed_id == -1: - self.changed_id = self.control.hscale.connect('value-changed', - self.scale_value_changed_cb) - - def scale_value_changed_cb(self, scale): - # see seek.c:seek_cb - real = long(scale.get_value() * self.p_duration / 100) # in ns - self.player.seek(real) - # allow for a preroll - self.player.get_state(timeout=50 * Gst.MSECOND) # 50 ms - - def scale_button_release_cb(self, widget, event): - # see seek.cstop_seek - widget.disconnect(self.changed_id) - self.changed_id = -1 - - self.control.button.set_sensitive(True) - if self.seek_timeout_id != -1: - GObject.source_remove(self.seek_timeout_id) - self.seek_timeout_id = -1 - else: - if self.was_playing: - self.player.play() - - if self.update_id != -1: - self.error('Had a previous update timeout id') - else: - self.update_id = GObject.timeout_add(self.UPDATE_INTERVAL, - self.update_scale_cb) - - def update_scale_cb(self): - success, self.p_position, self.p_duration = \ - self.player.query_position() - - if not success: - return True - - if self.p_position != Gst.CLOCK_TIME_NONE: - value = self.p_position * 100.0 / self.p_duration - self.control.adjustment.set_value(value) - - # Update the current time - seconds = self.p_position * 10 ** -9 - time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60)) - self.control.current_time_label.set_text(time) - - # FIXME: this should be updated just once when the file starts - # the first time - if self.p_duration != Gst.CLOCK_TIME_NONE: - seconds = self.p_duration * 10 ** -9 - time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60)) - self.control.total_time_label.set_text(time) - - return True - def __go_fullscreen_cb(self, toolbar): self.fullscreen() diff --git a/controls.py b/controls.py index 09b5325..6ee16a9 100644 --- a/controls.py +++ b/controls.py @@ -18,6 +18,7 @@ import logging from gi.repository import Gtk +from gi.repository import Gst from gi.repository import GObject from gettext import gettext as _ @@ -31,11 +32,17 @@ class Controls(GObject.GObject): """Class to create the Control (play, back, forward, add, remove, etc) toolbar""" - def __init__(self, toolbar, jukebox): + SCALE_UPDATE_INTERVAL = 1000 + + def __init__(self, activity, toolbar): GObject.GObject.__init__(self) + self.activity = activity self.toolbar = toolbar - self.jukebox = jukebox + + self._scale_update_id = -1 + self._scale_changed_id = -1 + self._seek_timeout_id = -1 self.open_button = ToolButton('list-add') self.open_button.set_tooltip(_('Add track')) @@ -56,7 +63,7 @@ class Controls(GObject.GObject): self.prev_button = ToolButton('player_rew') self.prev_button.set_tooltip(_('Previous')) self.prev_button.show() - self.prev_button.connect('clicked', self.prev_button_clicked_cb) + self.prev_button.connect('clicked', self.__prev_button_clicked_cb) self.toolbar.insert(self.prev_button, -1) self.pause_image = Gtk.Image.new_from_stock(Gtk.STOCK_MEDIA_PAUSE, @@ -77,14 +84,14 @@ class Controls(GObject.GObject): self.next_button = ToolButton('player_fwd') self.next_button.set_tooltip(_('Next')) self.next_button.show() - self.next_button.connect('clicked', self.next_button_clicked_cb) + self.next_button.connect('clicked', self.__next_button_clicked_cb) self.toolbar.insert(self.next_button, -1) current_time = Gtk.ToolItem() self.current_time_label = Gtk.Label(label='') current_time.add(self.current_time_label) current_time.show() - toolbar.insert(current_time, -1) + self.toolbar.insert(current_time, -1) self.adjustment = Gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0) self.hscale = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL, @@ -95,9 +102,9 @@ class Controls(GObject.GObject): logging.debug("FIXME: AttributeError: 'Scale' object has no " "attribute 'set_update_policy'") self.hscale.connect('button-press-event', - jukebox.scale_button_press_cb) + self.__scale_button_press_cb) self.hscale.connect('button-release-event', - jukebox.scale_button_release_cb) + self.__scale_button_release_cb) self.scale_item = Gtk.ToolItem() self.scale_item.set_expand(True) @@ -108,17 +115,27 @@ class Controls(GObject.GObject): self.total_time_label = Gtk.Label(label='') total_time.add(self.total_time_label) total_time.show() - toolbar.insert(total_time, -1) + self.toolbar.insert(total_time, -1) + + self.activity.connect('no-stream', self.__no_stream_cb) + self.activity.player.connect('play', self.__player_play) + + def __player_play(self, widget): + if self._scale_update_id == -1: + self._scale_update_id = GObject.timeout_add( + self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) + self.set_enabled() + self.set_button_pause() def __open_button_clicked_cb(self, widget): self.__show_picker_cb() def __erase_playlist_entry_clicked_cb(self, widget): - self.jukebox.playlist_widget.delete_selected_items() + self.activity.playlist_widget.delete_selected_items() def __show_picker_cb(self): jobject = None - chooser = ObjectChooser(self.jukebox, + chooser = ObjectChooser(self.activity, what_filter=mime.GENERIC_TYPE_AUDIO) try: @@ -127,20 +144,44 @@ class Controls(GObject.GObject): jobject = chooser.get_selected_object() if jobject and jobject.file_path: logging.info('Adding %s', jobject.file_path) - self.jukebox.playlist_widget.load_file(jobject) - self.jukebox.check_if_next_prev() + self.activity.playlist_widget.load_file(jobject) + self.check_if_next_prev() finally: if jobject is not None: jobject.destroy() - def prev_button_clicked_cb(self, widget): - self.jukebox.songchange('prev') + def __prev_button_clicked_cb(self, widget): + self.activity.songchange('prev') + + def __next_button_clicked_cb(self, widget): + self.activity.songchange('next') - def next_button_clicked_cb(self, widget): - self.jukebox.songchange('next') + def check_if_next_prev(self): + current_playing = self.activity.playlist_widget._current_playing + if current_playing == 0: + self.prev_button.set_sensitive(False) + else: + self.prev_button.set_sensitive(True) + if current_playing == len(self.activity.playlist_widget._items) - 1: + self.next_button.set_sensitive(False) + else: + self.next_button.set_sensitive(True) def _button_clicked_cb(self, widget): - self.jukebox.play_toggled() + self.set_enabled() + + if self.activity.player.is_playing(): + self.activity.player.pause() + self.set_button_play() + GObject.source_remove(self._scale_update_id) + else: + if self.activity.player.error: + self.set_disabled() + else: + self.activity.player.play() + self.activity._switch_canvas(True) + self._scale_update_id = GObject.timeout_add( + self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) def set_button_play(self): self.button.set_icon_widget(self.play_image) @@ -157,3 +198,80 @@ class Controls(GObject.GObject): self.button.set_sensitive(True) self.scale_item.set_sensitive(True) self.hscale.set_sensitive(True) + + def __scale_button_press_cb(self, widget, event): + self.button.set_sensitive(False) + self.was_playing = self.activity.player.is_playing() + if self.was_playing: + self.activity.player.pause() + + # don't timeout-update position during seek + if self._scale_update_id != -1: + GObject.source_remove(self._scale_update_id) + self._scale_update_id = -1 + + # make sure we get changed notifies + if self._scale_changed_id == -1: + self._scale_changed_id = self.hscale.connect('value-changed', + self.__scale_value_changed_cb) + + def __scale_value_changed_cb(self, scale): + # see seek.c:seek_cb + real = long(scale.get_value() * self.p_duration / 100) # in ns + self.activity.player.seek(real) + # allow for a preroll + self.activity.player.get_state(timeout=50 * Gst.MSECOND) # 50 ms + + def __scale_button_release_cb(self, widget, event): + # see seek.cstop_seek + widget.disconnect(self._scale_changed_id) + self._scale_changed_id = -1 + + self.button.set_sensitive(True) + if self._seek_timeout_id != -1: + GObject.source_remove(self._seek_timeout_id) + self._seek_timeout_id = -1 + else: + if self.was_playing: + self.activity.player.play() + + if self._scale_update_id != -1: + # self.error('Had a previous update timeout id') + pass + else: + self._scale_update_id = GObject.timeout_add( + self.SCALE_UPDATE_INTERVAL, self.__update_scale_cb) + + def __update_scale_cb(self): + success, self.p_position, self.p_duration = \ + self.activity.player.query_position() + + if not success: + return True + + if self.p_position != Gst.CLOCK_TIME_NONE: + value = self.p_position * 100.0 / self.p_duration + self.adjustment.set_value(value) + + # Update the current time + seconds = self.p_position * 10 ** -9 + time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60)) + self.current_time_label.set_text(time) + + # FIXME: this should be updated just once when the file starts + # the first time + if self.p_duration != Gst.CLOCK_TIME_NONE: + seconds = self.p_duration * 10 ** -9 + time = '%2d:%02d' % (int(seconds / 60), int(seconds % 60)) + self.total_time_label.set_text(time) + + return True + + def __no_stream_cb(self, widget): + self.activity.player.stop() + self.set_button_play() + self.check_if_next_prev() + + self.adjustment.set_value(0) + self.current_time_label.set_text('') + self.total_time_label.set_text('') @@ -40,7 +40,7 @@ class GstPlayer(GObject.GObject): 'play': (GObject.SignalFlags.RUN_FIRST, None, []), } - def __init__(self, videowidget): + def __init__(self): GObject.GObject.__init__(self) self.playing = False @@ -63,6 +63,7 @@ class GstPlayer(GObject.GObject): self.player = Gst.ElementFactory.make('playbin', None) self.pipeline.add(self.player) + def init_view_area(self, videowidget): videowidget.realize() self.videowidget = videowidget self.videowidget_xid = videowidget.get_window().get_xid() |