def on_close(self, widget, data=None): """ Close and dispose everything that needs to be when window is closed. """ self.titlebar.close() if self.sleep_timer.is_running(): self.sleep_timer.stop() # save current position when still playing if player.get_gst_player_state() == Gst.State.PLAYING: db.Track.update(position=player.get_current_duration()).where( db.Track.id == player.get_current_track().id).execute() player.stop() player.dispose()
def track_changed(self): """ The track loaded in the player has changed. Refresh the currently playing track and mark it in the track overview popover. """ # also reset the book playing state if self.current_book_element is not None: self.current_book_element.set_playing(False) curr_track = player.get_current_track() self.current_book_element = next( filter(lambda x: x.book.id == curr_track.book.id, self.book_box.get_children()), None) self.block_ui_buttons(False, True)
def switch_to_playing(self): """ Switch the UI state back to playing. This enables all UI functionality for the user. """ self.titlebar.switch_to_playing() self.main_stack.props.visible_child_name = "main" self.category_toolbar.set_visible(True) if player.get_current_track(): self.block_ui_buttons(False, True) else: # we want to only block the player controls self.block_ui_buttons(False, True) self.block_ui_buttons(True, False) self.window.props.window.set_cursor(None)
def __on_play_clicked(self, event): """ """ track = db.get_track_for_playback(self.book) current_track = player.get_current_track() if current_track is not None and current_track.book.id == self.book.id: player.play_pause(None) if player.get_gst_player_state() == Gst.State.PLAYING: player.jump_to_ns(track.position) else: player.load_file(track) player.play_pause(None, True) return True
def __on_play_pause_clicked(self, button): """ Play/Pause the player. """ player.play_pause(None) pos = player.get_current_track().position if self.__first_play: self.__first_play = False if self.settings.get_boolean("replay"): amount = 30 * 1000000000 if pos < amount: pos = 0 else: pos = pos - amount player.jump_to_ns(pos)
def __on_button_press(self, eventbox, event): """ Play the selected track. """ current_track = player.get_current_track() if current_track and current_track.id == self.track.id: player.play_pause(None) if player.get_gst_player_state() == Gst.State.PLAYING: player.jump_to_ns(db.Track.select().where( db.Track.id == self.track.id).get().position) else: player.load_file(db.Track.select().where(db.Track.id == self.track.id).get()) player.play_pause(None, True) db.Book.update(position=self.track).where( db.Book.id == self.track.book.id).execute()
def __player_changed(self, event, message): """ Listen to and handle all gst player messages that are important for the ui. """ if event == "stop": if self.__inhibit_cookie: self.app.uninhibit(self.__inhibit_cookie) self.is_playing = False self.stop() self.titlebar.stop() self.sleep_timer.stop() elif event == "play": self.is_playing = True self.play() self.titlebar.play() self.sleep_timer.start() self.book_overview.select_track(None, True) self.refresh_recent() self.__inhibit_cookie = self.app.inhibit( self.window, Gtk.ApplicationInhibitFlags.SUSPEND, "Playback of audiobook") elif event == "pause": if self.__inhibit_cookie: self.app.uninhibit(self.__inhibit_cookie) self.is_playing = False self.pause() self.titlebar.pause() self.sleep_timer.stop() self.book_overview.select_track(None, False) elif event == "track-changed": self.track_changed() if self.sort_stack.props.visible_child_name == "recent": self.book_box.invalidate_filter() self.book_box.invalidate_sort() elif event == "error": if self.dialog_open: return if "Resource not found" in str(message): current_track = player.get_current_track() if db.is_external(current_track.book): player.stop() player.unload() player.emit_event("stop") else: self.dialog_open = True dialog = FileNotFoundDialog(current_track.file) dialog.show()
def __init_components(self): self.titlebar = Titlebar() self.sleep_timer = SleepTimer() self.speed = PlaybackSpeed() self.search = Search() self.settings = Settings() self.settings.add_listener(self.__on_settings_changed) self.book_overview = BookOverview() self.fs_monitor = fs_monitor.FilesystemMonitor() self.offline_cache = offline_cache.OfflineCache() player.init() self.titlebar.activate() if player.get_current_track() is None: self.block_ui_buttons(True)
def load_last_book(self): if db.Settings.get().last_played_book is not None: self.update_track_ui() self.update_ui_time(self.progress_scale) cur_m, cur_s = player.get_current_duration_ui() self.__set_progress_scale_value(cur_m * 60 + cur_s) pos = int(player.get_current_track().position) if tools.get_glib_settings().get_boolean("replay"): log.info("Replaying the previous 30 seconds.") amount = 30 * 1000000000 if (pos < amount): pos = 0 else: pos = pos - amount self.__set_progress_scale_value( int(pos / 1000000000 / self.ui.speed.get_speed()))
def get_playback_start_position(self): """ Returns the position where to start playback of the current track. This checks for the automatic replay option. :return: Position in ns """ pos = player.get_current_track().position if self.first_play: self.first_play = False if tools.get_glib_settings().get_boolean("replay"): amount = 30 * 1000000000 if pos < amount: pos = 0 else: pos = pos - amount return pos
def _on_play_button_press(self, widget, event): """ Play this book. """ if event.type == Gdk.EventType.BUTTON_PRESS and event.button != 1: return track = db.get_track_for_playback(self.book) current_track = player.get_current_track() if current_track and current_track.book.id == self.book.id: player.play_pause(None) if player.get_gst_player_state() == Gst.State.PLAYING: player.jump_to_ns(track.position) else: player.load_file(track) player.play_pause(None, True) return True
def __player_changed(self, event, message): """ """ if self.book is None or self.ui.titlebar.current_book is None or self.ui.titlebar.current_book.id != self.book.id: return if event == "play": self.play_book_button.set_image(self.pause_img) self.current_track_element.set_playing(True) self.last_played_label.set_text( tools.past_date_to_human_readable(message.book.last_played)) elif event == "pause": self.play_book_button.set_image(self.play_img) self.current_track_element.set_playing(False) elif event == "stop": self._mark_current_track() elif event == "track-changed": track = player.get_current_track() self.select_track(track, self.ui.is_playing)
def track_changed(self): """ The track loaded in the player has changed. Refresh the currently playing track and mark it in the track overview popover. """ # also reset the book playing state if self.current_book_element is not None: self.current_book_element.set_playing(False) self.current_book_element.select_track(None, False) curr_track = player.get_current_track() self.current_book_element = next( filter(lambda x: x.get_children()[0].book.id == curr_track.book.id, self.book_box.get_children()), None).get_children()[0] self._update_current_track_element() self.remaining_label.set_visible(True) self.current_label.set_visible(True)
def __update_ui_time(self, widget): """ Displays the value of the progress slider in the text boxes as time. """ val = int(self.progress_scale.get_value()) m, s = divmod(val, 60) self.current_label.set_markup("<tt><b>" + str(m).zfill(2) + ":" + str(s).zfill(2) + "</b></tt>") track = player.get_current_track() if track is not None: remaining_secs = int(track.length - val) remaining_mins, remaining_secs = divmod(remaining_secs, 60) self.remaining_label.set_markup("<tt><b>" + str(remaining_mins).zfill(2) + ":" + str(remaining_secs).zfill(2) + "</b></tt>")
def __load_last_book(self): """ Loads the last book into the player """ player.load_last_book() if db.Settings.get().last_played_book is not None: self.__update_track_ui() self.__update_ui_time(self.progress_scale) cur_m, cur_s = player.get_current_duration_ui() self.progress_scale.set_value(cur_m * 60 + cur_s) pos = int(player.get_current_track().position) if self.settings.get_boolean("replay"): log.info("Replaying the previous 30 seconds.") amount = 30 * 1000000000 if (pos < amount): pos = 0 else: pos = pos - amount self.progress_scale.set_value(int(pos / 1000000000))
def __on_rewind_clicked(self, button): """ """ seconds = 30 * self.ui.speed.get_speed() if self.ui.first_play: ns = seconds * 1000000000 track = player.get_current_track() pos = track.position if (pos > ns): pos -= ns else: pos = 0 player.save_current_track_position(pos=pos, track=track) else: player.rewind(seconds) # we want to see the jump imediatly therefore we apply the new time manually if self.progress_scale.get_value() > 30: self.progress_scale.set_value(self.progress_scale.get_value() - 30) else: self.progress_scale.set_value(0)
def __on_progress_clicked(self, widget, sender): """ Jump to the slided time and release the progress scale update lock. """ value = self.progress_scale.get_value() * self.ui.speed.get_speed() if tools.get_glib_settings().get_boolean("titlebar-remaining-time"): track, time = db.get_track_from_book_time(self.current_book, value) if track.id == player.get_current_track().id: player.jump_to(time) else: player.load_file( db.Track.select().where(db.Track.id == track.id).get()) player.play_pause(None, True) self.__set_progress_scale_value(time / self.ui.speed.get_speed()) player.jump_to(time) else: player.jump_to(value) self.progress_scale_clicked = False return False
def update_track_ui(self): # set data of new stream in ui track = player.get_current_track() if track is None: return self.title_label.set_text(track.book.name) self.subtitle_label.set_text(track.name) self.block_ui_buttons(False) self.progress_scale.set_sensitive(True) self.progress_scale.set_visible(True) # only change cover when book has changed if self.current_book is not track.book: self.current_book = track.book if tools.is_elementary(): size = 28 else: size = 40 self.set_title_cover( artwork_cache.get_cover_pixbuf( track.book, self.ui.window.get_scale_factor(), size), size) self.current_remaining = db.get_book_remaining(self.current_book, False) self.current_elapsed = db.get_book_progress(self.current_book, False) self.__update_progress_scale_range() if tools.get_glib_settings().get_boolean("titlebar-remaining-time"): self.progress_scale.set_value(self.current_elapsed / self.ui.speed.get_speed()) else: self.progress_scale.set_value(0) self.update_ui_time(None) self.current_label.set_visible(True) self.remaining_label.set_visible(True)
def set_title_cover(self, pixbuf): """ Sets the cover in the title bar. """ self.cover_img.set_from_pixbuf(pixbuf) self.cover_img.set_tooltip_text(player.get_current_track().book.name)