Exemple #1
0
class ImageViewer(Player):
    """
    Player component for viewing images.
    """
    def __init__(self):

        self.__is_fullscreen = False
        self.__zoom_handler = None

        # whether the slideshow is playing
        self.__is_playing = False

        # slideshow handler
        self.__slideshow_handler = None

        # slideshow timeout in milliseconds
        self.__slideshow_timeout = 3000

        Player.__init__(self)

        self.__image = Image()
        self.__image.set_background(theme.color_image_viewer_background)
        #self.add(self.__image)

        kscr = KineticScroller(self.__image)

        gestures = Gestures(self.__image)
        gestures.connect_twirl(self.__on_twirl_gesture, kscr)
        gestures.connect_release(self.__on_release, kscr)
        #gestures.connect_hold(self.__on_hold)
        #gestures.connect_tap_hold(self.__on_tap_hold)
        gestures.connect_tap_tap(self.__on_tap_tap)
        gestures.connect_swipe(self.__on_swipe)

        # toolbar
        self.__btn_play = ToolbarButton(theme.mb_btn_play_1)
        self.__btn_play.connect_clicked(self.__on_btn_play)

        btn_previous = ToolbarButton(theme.mb_btn_previous_1)
        btn_previous.connect_clicked(self.__on_btn_previous)

        btn_next = ToolbarButton(theme.mb_btn_next_1)
        btn_next.connect_clicked(self.__on_btn_next)

        self.__toolbar = Toolbar()
        self.__toolbar.set_toolbar(btn_previous, self.__btn_play, btn_next)

        # arrangement
        self.__arr = Arrangement()
        self.__arr.connect_resized(self.__update_layout)
        self.__arr.add(self.__image, "image")
        self.__arr.add(self.__toolbar, "toolbar")
        #self.__arr.add(self.__volume_slider, "slider")
        self.add(self.__arr)

    def __update_layout(self):

        w, h = self.get_size()
        if (w < h):
            self.__arr.set_xml(_PORTRAIT_ARRANGEMENT)
        else:
            self.__arr.set_xml(_LANDSCAPE_ARRANGEMENT)

    def __slideshow_timer(self):

        gtk.main_iteration(False)

        if (self.__is_playing and self.may_render()):
            self.__image.slide_from_right()
            self.emit_message(msgs.MEDIA_ACT_NEXT)
            return True

        else:
            self.__btn_play.set_icon(theme.mb_btn_play_1)
            self.__slideshow_handler = None
            self.__is_playing = False
            self.emit_message(msgs.MEDIA_EV_PAUSE)

            return False

    def __on_btn_play(self):

        self.__is_playing = not self.__is_playing
        if (self.__is_playing):
            dlg = InputDialog("Slideshow Settings")
            dlg.add_range("Seconds between slides:", 1, _SLIDESHOW_MAX_TIMEOUT,
                          3)
            ret = dlg.run()

            if (ret != dlg.RETURN_OK): return

            secs = dlg.get_values()[0]
            self.__slideshow_timeout = int(secs * 1000)

            self.__btn_play.set_icon(theme.mb_btn_pause_1)

            self.emit_message(msgs.MEDIA_EV_PLAY)

            if (self.__slideshow_handler):
                gobject.source_remove(self.__slideshow_handler)
            self.__slideshow_handler = gobject.timeout_add(
                self.__slideshow_timeout, self.__slideshow_timer)

        else:
            self.__btn_play.set_icon(theme.mb_btn_play_1)

    def __on_btn_previous(self):

        self.__image.slide_from_left()
        self.emit_message(msgs.MEDIA_ACT_PREVIOUS)

    def __on_btn_next(self):

        self.__image.slide_from_right()
        self.emit_message(msgs.MEDIA_ACT_NEXT)

    def __on_twirl_gesture(self, direction, kscr):

        kscr.set_enabled(False)
        if (direction > 0):
            self.__image.zoom_in()
        else:
            self.__image.zoom_out()

    def __on_release(self, px, py, kscr):

        kscr.set_enabled(True)

        if (self.__zoom_handler):
            gobject.source_remove(self.__zoom_handler)

    def __on_hold(self, px, py):

        if (self.__zoom_handler):
            gobject.source_remove(self.__zoom_handler)
        self.__zoom_handler = gobject.timeout_add(50, self.__on_zoom_gesture,
                                                  1)

    def __on_tap_hold(self, px, py):

        if (self.__zoom_handler):
            gobject.source_remove(self.__zoom_handler)
        self.__zoom_handler = gobject.timeout_add(50, self.__on_zoom_gesture,
                                                  -1)

    def __on_zoom_gesture(self, direction):

        if (direction < 0):
            self.__image.zoom_out(False)
        elif (direction > 0):
            self.__image.zoom_in(False)
        return True

    def __on_tap_tap(self, px, py):

        self.__toggle_fullscreen()

    def __on_swipe(self, direction):

        if (self.__image.is_image_fitting()):
            if (direction > 0):
                self.__image.slide_from_left()
                self.emit_message(msgs.MEDIA_ACT_PREVIOUS)
            else:
                self.__image.slide_from_right()
                self.emit_message(msgs.MEDIA_ACT_NEXT)

    def __toggle_fullscreen(self):

        self.__is_fullscreen = not self.__is_fullscreen

        if (self.__is_fullscreen):
            self.__toolbar.set_visible(False)
            self.__image.set_background(
                theme.color_image_viewer_background_fullscreen)
        else:
            self.__toolbar.set_visible(True)
            self.__image.set_background(theme.color_image_viewer_background)

        self.emit_message(msgs.UI_ACT_FULLSCREEN, self.__is_fullscreen)
        self.__update_layout()
        self.render()

    def render_this(self):

        x, y = self.get_screen_pos()
        w, h = self.get_size()
        screen = self.get_screen()

        #screen.fill_area(x, y, w, h, theme.color_mb_background)
        self.__arr.set_geometry(0, 0, w, h)

    def get_mime_types(self):

        return ["image/*"]

    def load(self, f):

        self.__image.load(f)
        self.emit_message(msgs.MEDIA_EV_LOADED, self, f)
        self.render()

    def handle_MEDIA_ACT_PAUSE(self):

        if (self.is_player_active()):
            self.__on_btn_play()

    def handle_INPUT_EV_VOLUME_UP(self, pressed):

        if (self.is_visible() and self.__image):
            self.__image.zoom_in(False)

    def handle_INPUT_EV_VOLUME_DOWN(self, pressed):

        if (self.is_visible() and self.__image):
            self.__image.zoom_out(False)
Exemple #2
0
class VideoPlayer(Player):
    """
    Player component for playing videos.
    """
    def __init__(self):

        self.__is_fullscreen = False
        self.__volume = 50

        self.__player = None
        self.__context_id = 0
        self.__is_playing = False

        self.__blanking_handler = None
        self.__load_failed_handler = None

        # the currently playing file object (e.g. used for bookmarking)
        self.__current_file = None

        Player.__init__(self)

        # video screen
        self.__screen = VideoScreen()

        gestures = Gestures(self.__screen)
        gestures.connect_tap(self.__on_tap)
        gestures.connect_tap_tap(self.__on_tap_tap)
        gestures.connect_swipe(self.__on_swipe)

        # volume slider
        self.__volume_slider = Slider(theme.mb_list_slider)
        self.__volume_slider.set_mode(Slider.VERTICAL)
        self.__volume_slider.connect_value_changed(self.__on_change_volume)

        # progress bar
        self.__progress = MediaProgressBar(MediaProgressBar.UP)
        self.__progress.connect_changed(self.__on_seek)
        self.__progress.connect_bookmark_changed(self.__on_change_bookmark)

        # star button for bookmarks
        #self.__btn_star = ImageButton(theme.mb_btn_bookmark_1,
        #                              theme.mb_btn_bookmark_2)
        #self.__btn_star.connect_clicked(self.__on_btn_star)

        # toolbar elements
        self.__btn_play = ToolbarButton(theme.mb_btn_play_1)
        self.__btn_play.connect_clicked(self.__on_btn_play)

        btn_previous = ToolbarButton(theme.mb_btn_previous_1)
        btn_previous.connect_clicked(self.__on_btn_previous)

        btn_next = ToolbarButton(theme.mb_btn_next_1)
        btn_next.connect_clicked(self.__on_btn_next)

        # toolbar
        self.__toolbar = Toolbar()
        self.__toolbar.set_toolbar(btn_previous, self.__btn_play, btn_next)

        # arrangement
        self.__arr = Arrangement()
        self.__arr.connect_resized(self.__update_layout)
        self.__arr.add(self.__screen, "screen")
        self.__arr.add(self.__toolbar, "toolbar")
        self.__arr.add(self.__progress, "progress")
        #self.__arr.add(self.__btn_star, "btn_star")
        self.__arr.add(self.__volume_slider, "slider")
        self.add(self.__arr)

    def __update_layout(self):

        w, h = self.get_size()
        #if (self.__is_fullscreen):
        #    self.__btn_star.set_visible(False)
        #else:
        #    self.__btn_star.set_visible(True)

        if (w < h):
            self.__arr.set_xml(_PORTRAIT_ARRANGEMENT)
        else:
            self.__arr.set_xml(_LANDSCAPE_ARRANGEMENT)

    def __on_btn_play(self):

        if (self.__player):
            if (not self.__is_playing):
                self.__wait_for_dsp()
            self.__player.pause()

    def __on_btn_previous(self):

        self.emit_message(msgs.MEDIA_ACT_PREVIOUS)

    def __on_btn_next(self):

        self.emit_message(msgs.MEDIA_ACT_NEXT)

    def __on_tap(self, px, py):

        self.__toggle_fullscreen()

    def __on_tap_tap(self, px, py):

        self.__toggle_fullscreen()

    def __on_swipe(self, direction):

        if (self.__player):
            if (direction < 0):
                self.__player.rewind()
            elif (direction > 0):
                self.__player.forward()
        #end if

    def __on_status_changed(self, ctx_id, status):

        if (ctx_id == self.__context_id):
            if (status == self.__player.STATUS_PLAYING):
                self.__btn_play.set_icon(theme.mb_btn_pause_1)

                if (self.__load_failed_handler):
                    gobject.source_remove(self.__load_failed_handler)

                self.__is_playing = True
                self.__progress.set_message("")
                self.emit_message(msgs.MEDIA_EV_PLAY)

                # we need manual unblanking on Maemo5 for videos
                if (not self.__blanking_handler
                        and platforms.PLATFORM == platforms.MAEMO5):
                    self.__blanking_handler = gobject.timeout_add(
                        23000, self.__inhibit_blanking)
                #end if

            elif (status == self.__player.STATUS_STOPPED):
                self.__btn_play.set_icon(theme.mb_btn_play_1)
                self.__is_playing = False
                self.call_service(msgs.VIDEOPLAYER_SVC_RELEASE_DSP)
                self.emit_message(msgs.MEDIA_EV_PAUSE)

            elif (status == self.__player.STATUS_EOF):
                self.__btn_play.set_icon(theme.mb_btn_play_1)
                self.__is_playing = False
                self.call_service(msgs.VIDEOPLAYER_SVC_RELEASE_DSP)
                self.emit_message(msgs.MEDIA_EV_EOF)
                self.emit_message(msgs.MEDIA_ACT_NEXT)

            elif (status == self.__player.STATUS_CONNECTING):
                self.__progress.set_message("Connecting")

            elif (status == self.__player.STATUS_BUFFERING):
                self.__progress.set_message("Buffering")

    def __on_update_position(self, ctx_id, pos, total):

        if (ctx_id == self.__context_id):
            self.__progress.set_position(pos, total)
            self.__progress.set_message("%s / %s" \
                                        % (self.seconds_to_hms(pos),
                                           self.seconds_to_hms(total)))
            self.emit_message(msgs.MEDIA_EV_POSITION, pos, total)

    def __on_change_volume(self, v):

        if (self.__player):
            vol = int(v * 100)
            self.__player.set_volume(vol)
            self.__volume = vol

    def __on_change_player_volume(self, v):

        if (v != self.__volume):
            self.__volume_slider.set_value(v / 100.0)
            self.__volume = v

    def __on_change_player_aspect_ratio(self, ctx_id, r):

        if (ctx_id == self.__context_id and self.__player):
            self.__screen.set_aspect_ratio(r)

    def __on_change_bookmark(self):

        media_bookmarks.set_bookmarks(self.__current_file,
                                      self.__progress.get_bookmarks())

    def __on_error(self, ctx_id, err):

        if (ctx_id == self.__context_id and self.__player):
            self.emit_message(msgs.UI_ACT_SHOW_INFO, self.__player.ERRORS[err])

    def __on_seek(self, progress):

        if (self.__player):
            self.__player.seek_percent(progress)

    def __inhibit_blanking(self):

        if (self.__is_playing):
            platforms.inhibit_screen_blanking()
            return True
        else:
            self.__blanking_handler = None
            return False

    def __toggle_fullscreen(self):

        self.__is_fullscreen = not self.__is_fullscreen
        if (self.__is_fullscreen):
            self.__progress.set_visible(False)
            self.__volume_slider.set_visible(False)
            self.__toolbar.set_visible(False)
            #self.__btn_star.set_visible(False)
        else:
            self.__progress.set_visible(True)
            self.__volume_slider.set_visible(True)
            self.__toolbar.set_visible(True)
            #self.__btn_star.set_visible(True)

        self.__update_layout()
        self.emit_message(msgs.UI_ACT_FULLSCREEN, self.__is_fullscreen)
        #self.render()

    def _visibility_changed(self):

        # force video to landscape mode on Maemo
        win = self.get_window()
        if (win):  # and platforms.MAEMO5):
            if (self.is_visible()):
                print "show video"
                logging.debug("[videoplayer] forcing landscape mode")
                self.emit_message(msgs.ASR_ACT_ENABLE, False)
                self.emit_message(msgs.ASR_EV_LANDSCAPE)

            else:
                print "hide video"
                self.emit_message(msgs.ASR_ACT_RESTORE)
        #end if

        self.__screen.render()  #set_visible(self.is_visible())

    def render_this(self):

        x, y = self.get_screen_pos()
        w, h = self.get_size()
        screen = self.get_screen()

        if (w == 0 or h == 0): return

        if (self.__is_fullscreen):
            screen.fill_area(x, y, w, h, "#000000")
        else:
            screen.fill_area(x, y, w, h, theme.color_mb_background)
        self.__arr.set_geometry(0, 0, w, h)

        if (w < h):
            self.__screen.set_visible(False)
            if (platforms.MAEMO4):
                screen.draw_centered_text("Video cannot be displayed in\n" \
                                          "portrait mode.",
                                          theme.font_mb_plain,
                                          0, h / 2 - 80, w, 0, theme.color_mb_text)
        else:
            self.__screen.set_visible(True)

    def get_mime_types(self):

        return ["video/*"]

    def __wait_for_dsp(self):

        self.__progress.set_message("Waiting for DSP")
        self.call_service(msgs.VIDEOPLAYER_SVC_LOCK_DSP)
        self.__progress.set_message("")

    def __on_load_failed(self):

        self.__load_failed_handler = None
        self.call_service(msgs.VIDEOPLAYER_SVC_RELEASE_DSP)

    def load(self, f):

        self.render()
        self.__wait_for_dsp()

        self.__player = self.call_service(msgs.MEDIA_SVC_GET_OUTPUT)
        self.__player.connect_status_changed(self.__on_status_changed)
        self.__player.connect_position_changed(self.__on_update_position)
        self.__player.connect_volume_changed(self.__on_change_player_volume)
        self.__player.connect_aspect_changed(
            self.__on_change_player_aspect_ratio)
        self.__player.connect_error(self.__on_error)

        self.__player.set_window(self.__screen.get_xid())

        # loading may fail, so we need to setup a handler that frees the DSP
        # semaphore after some time
        if (self.__load_failed_handler):
            gobject.source_remove(self.__load_failed_handler)
        self.__load_failed_handler = gobject.timeout_add(
            30000, self.__on_load_failed)

        try:
            self.__progress.set_message("Loading")
            self.__context_id = self.__player.load_video(f)

            self.__current_file = f

            # load bookmarks
            self.__progress.set_bookmarks(media_bookmarks.get_bookmarks(f))

            self.emit_message(msgs.MEDIA_EV_LOADED, self, f)
        except:
            self.__progress.set_message("Error")
            logging.error("[videoplayer] error loading media file: %s\n%s", f,
                          logging.stacktrace())

    def set_bookmark(self):

        self.__progress.add_bookmark()

    def handle_MEDIA_ACT_PLAY(self):

        if (self.__player and self.is_player_active()):
            if (not self.__is_playing):
                self.__wait_for_dsp()
            self.__player.play()

    def handle_MEDIA_ACT_PAUSE(self):

        if (self.__player and self.is_player_active()):
            if (not self.__is_playing):
                self.__wait_for_dsp()
            self.__player.pause()

    def handle_MEDIA_ACT_STOP(self):

        if (self.__player and self.is_player_active()):
            self.__player.stop()

    def handle_MEDIA_ACT_SEEK(self, pos):

        if (self.__player and self.is_player_active()):
            self.__player.seek(pos)

    def handle_INPUT_EV_FULLSCREEN(self, pressed):

        if (self.is_visible()):
            self.__toggle_fullscreen()

    def handle_INPUT_EV_VOLUME_UP(self, pressed):

        self.__volume = min(100, self.__volume + 5)
        self.__volume_slider.set_value(self.__volume / 100.0)
        if (self.__player):
            self.__player.set_volume(self.__volume)

    def handle_INPUT_EV_VOLUME_DOWN(self, pressed):

        self.__volume = max(0, self.__volume - 5)
        self.__volume_slider.set_value(self.__volume / 100.0)
        if (self.__player):
            self.__player.set_volume(self.__volume)

    def handle_COM_EV_APP_SHUTDOWN(self):

        if (self.__player):
            self.__player.close()