Exemple #1
0
    def load_media(self, vidSource):
        """ Loads a video.

        Parameters
        ----------
        vidSource : str
            The path to the video file
        """
        if not os.path.exists(vidSource):
            print("File not found: " + vidSource)
            pygame.display.quit()
            pygame.quit()
            sys.exit(1)

        self.decoder.load_media(vidSource)
        self.decoder.loop = self.loop
        pygame.display.set_caption(os.path.split(vidSource)[1])
        self.vidsize = self.decoder.clip.size

        self.destsize = self.calc_scaled_res(self.windowSize, self.vidsize)
        self.vidPos = ((self.windowSize[0] - self.destsize[0]) / 2, (self.windowSize[1] - self.destsize[1]) / 2)

        self.__textureSetup()

        if (self.decoder.audioformat):
            if self.soundrenderer == "pygame":
                from mediadecoder.soundrenderers import SoundrendererPygame
                self.audio = SoundrendererPygame(self.decoder.audioformat)
            elif self.soundrenderer == "pyaudio":
                from mediadecoder.soundrenderers.pyaudiorenderer import SoundrendererPyAudio
                self.audio = SoundrendererPyAudio(self.decoder.audioformat)
            elif self.soundrenderer == "sounddevice":
                from mediadecoder.soundrenderers.sounddevicerenderer import SoundrendererSounddevice
                self.audio = SoundrendererSounddevice(self.decoder.audioformat)
            self.decoder.set_audiorenderer(self.audio)
Exemple #2
0
    def load_media(_, vidSource, audio=True):

        logger.debug('loading %s' % vidSource)
        if not os.path.exists(vidSource):
            raise Exception("File not found: " + vidSource)

        _.decoder.load_media(vidSource, audio)
        _.decoder.loop = _.loop
        _.vidsize = _.decoder.clip.size
        _.width = _.vidsize[0]
        _.height = _.vidsize[1]
        _.__textureSetup()

        if (_.decoder.audioformat):
            if _.soundrenderer == "pygame":
                from mediadecoder.soundrenderers import SoundrendererPygame
                _.audio = SoundrendererPygame(_.decoder.audioformat)
            elif _.soundrenderer == "pyaudio":
                from mediadecoder.soundrenderers.pyaudiorenderer import SoundrendererPyAudio
                _.audio = SoundrendererPyAudio(_.decoder.audioformat)
            elif _.soundrenderer == "sounddevice":
                from mediadecoder.soundrenderers.sounddevicerenderer import SoundrendererSounddevice
                _.audio = SoundrendererSounddevice(_.decoder.audioformat)
            _.decoder.set_audiorenderer(_.audio)

        _.play()
Exemple #3
0
    def preload(self):
        """Preload stimulus to memory.

        Notes
        -----
        When the audio from the video should be played as well, the audiosystem
        has to be stopped (by calling ``expyriment.control.stop_audiosystem()``)
        BEFORE the video stimulus is preloaded! After the stimulus has been
        played the audiosystem can be started again (by calling
        ``expyriment.control.start_audiosystem()``).

        """

        if not self._is_preloaded:
            if not _internals.active_exp.is_initialized:
                message = "Can't preload video. Expyriment needs to be " + \
                          "initialized before preloading a video."
                raise RuntimeError(message)
            if self._backend == "pygame":
                self._file = pygame.movie.Movie(self._filename)
                size = self._file.get_size()
            elif self._backend == "mediadecoder":
                if self.get_ffmpeg_binary() is None:
                    raise RuntimeError("'ffmpeg' not found!")
                from mediadecoder.states import PLAYING
                from mediadecoder.decoder import Decoder
                self._file = Decoder(mediafile=self._filename,
                                     videorenderfunc=self._update_surface)
                if _internals.active_exp._screen.open_gl:
                    import moviepy.video.fx.all as vfx
                    self._file.clip = vfx.mirror_y(self._file.clip)
                if self._file.audioformat:
                    try:
                        from mediadecoder.soundrenderers.sounddevicerenderer import SoundrendererSounddevice
                        self._audio = SoundrendererSounddevice(
                            self._file.audioformat)
                        self._audio_renderer = "sounddevice"
                    except ImportError:
                        from mediadecoder.soundrenderers import SoundrendererPygame
                        self._audio = SoundrendererPygame(
                            self._file.audioformat)
                        self._audio_renderer = "pygame"
                    self._file.set_audiorenderer(self._audio)
                size = self._file.clip.size
            else:
                raise RuntimeError("Unknown backend '{0}'!".format(
                    self._backend))
            screen_size = _internals.active_exp.screen.surface.get_size()

            self._pos = [
                screen_size[0] // 2 - size[0] // 2 + self._position[0],
                screen_size[1] // 2 - size[1] // 2 - self._position[1]
            ]
            if self._backend == "pygame":
                self._surface = pygame.surface.Surface(size)
                self._file.set_display(self._surface)
            self._is_paused = False
            self._is_preloaded = True
Exemple #4
0
    def load_media(self, vidSource):
        """ Loads a video.

		Parameters
		----------
		vidSource : str
			The path to the video file
		"""
        if not os.path.exists(vidSource):
            print("File not found: " + vidSource)
            pygame.display.quit()
            pygame.quit()
            sys.exit(1)

        self.decoder.load_media(vidSource)
        self.decoder.loop = self.loop
        pygame.display.set_caption(os.path.split(vidSource)[1])
        self.vidsize = self.decoder.clip.size

        self.destsize = self.calc_scaled_res(self.windowSize, self.vidsize)
        self.vidPos = ((self.windowSize[0] - self.destsize[0]) / 2,
                       (self.windowSize[1] - self.destsize[1]) / 2)

        self.__textureSetup()

        if (self.decoder.audioformat):
            if self.soundrenderer == "pygame":
                from mediadecoder.soundrenderers import SoundrendererPygame
                self.audio = SoundrendererPygame(self.decoder.audioformat)
            elif self.soundrenderer == "pyaudio":
                from mediadecoder.soundrenderers.pyaudiorenderer import SoundrendererPyAudio
                self.audio = SoundrendererPyAudio(self.decoder.audioformat)
            elif self.soundrenderer == "sounddevice":
                from mediadecoder.soundrenderers.sounddevicerenderer import SoundrendererSounddevice
                self.audio = SoundrendererSounddevice(self.decoder.audioformat)
            self.decoder.set_audiorenderer(self.audio)
Exemple #5
0
class VideoPlayer():
    """ This is an example videoplayer that uses pygame+pyopengl to render a video.
    It uses the Decoder object to decode the video- and audiostream frame by frame.
    It shows each videoframe in a window and places the audioframes in a buffer
    (or queue) from which they are fetched by the soundrenderer object.
    """

    def __init__(self, dimensions, fullscreen=False, soundrenderer="pyaudio",
                 loop=False):
        """ Constructor.

        Parameters
        ----------
        dimensions : tuple (width, height)
            The dimension of the window in which the video should be shown. Aspect
            ratio is maintained.
        fullscreen : bool, optional
            Indicates whether the video should be displayed in fullscreen.
        soundrenderer : {'pyaudio','pygame'}
            Designates which sound backend should render the sound.
        """

        pygame.init()
        (windowWidth, windowHeight) = dimensions
        flags = pygame.DOUBLEBUF | pygame.OPENGL | pygame.HWSURFACE
        self.fullscreen = fullscreen
        if fullscreen:
            flags = flags | pygame.FULLSCREEN
        pygame.display.set_mode((windowWidth, windowHeight), flags)
        self.windowSize = (windowWidth, windowHeight)

        self.soundrenderer = soundrenderer
        self.loop = loop
        self.texUpdated = False

        self.__initGL()

        self.decoder = Decoder(
            videorenderfunc=self.__texUpdate,
        )
        self.texture_locked = False

    def __initGL(self):
        glViewport(0, 0, self.windowSize[0], self.windowSize[1])

        glPushAttrib(GL_ENABLE_BIT)
        glDisable(GL_DEPTH_TEST)
        glDisable(GL_CULL_FACE)

        glDepthFunc(GL_ALWAYS)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        glMatrixMode(GL_PROJECTION)
        glPushMatrix()
        glLoadIdentity()
        glOrtho(0.0, self.windowSize[0], self.windowSize[1], 0.0, 0.0, 1.0)

        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()

        glColor4f(1, 1, 1, 1)
        glClearColor(0.0, 0.0, 0.0, 1.0)
        glClearDepth(1.0)

    def calc_scaled_res(self, screen_res, image_res):
        """Calculate appropriate texture size.

        Calculate size or required texture so that it will fill the window,
        but retains the movies original aspect ratio.

        Parameters
        ----------
        screen_res : tuple
            Display window size/Resolution
        image_res : tuple
            Image width and height

        Returns
        -------
        tuple
            width and height of image scaled to window/screen
        """
        rs = screen_res[0] / float(screen_res[1])
        ri = image_res[0] / float(image_res[1])

        if rs > ri:
            return (int(image_res[0] * screen_res[1] / image_res[1]), screen_res[1])
        else:
            return (screen_res[0], int(image_res[1] * screen_res[0] / image_res[0]))

    def load_media(self, vidSource):
        """ Loads a video.

        Parameters
        ----------
        vidSource : str
            The path to the video file
        """
        if not os.path.exists(vidSource):
            print("File not found: " + vidSource)
            pygame.display.quit()
            pygame.quit()
            sys.exit(1)

        self.decoder.load_media(vidSource)
        self.decoder.loop = self.loop
        pygame.display.set_caption(os.path.split(vidSource)[1])
        self.vidsize = self.decoder.clip.size

        self.destsize = self.calc_scaled_res(self.windowSize, self.vidsize)
        self.vidPos = ((self.windowSize[0] - self.destsize[0]) / 2, (self.windowSize[1] - self.destsize[1]) / 2)

        self.__textureSetup()

        if (self.decoder.audioformat):
            if self.soundrenderer == "pygame":
                from mediadecoder.soundrenderers import SoundrendererPygame
                self.audio = SoundrendererPygame(self.decoder.audioformat)
            elif self.soundrenderer == "pyaudio":
                from mediadecoder.soundrenderers.pyaudiorenderer import SoundrendererPyAudio
                self.audio = SoundrendererPyAudio(self.decoder.audioformat)
            elif self.soundrenderer == "sounddevice":
                from mediadecoder.soundrenderers.sounddevicerenderer import SoundrendererSounddevice
                self.audio = SoundrendererSounddevice(self.decoder.audioformat)
            self.decoder.set_audiorenderer(self.audio)

    def __textureSetup(self):
        # Setup texture in OpenGL to render video to
        glEnable(GL_TEXTURE_2D)
        glMatrixMode(GL_MODELVIEW)
        self.textureNo = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, self.textureNo)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

        # Fill texture with black to begin with.
        img = np.zeros([self.vidsize[0], self.vidsize[1], 3], dtype=np.uint8)
        img.fill(0)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, self.vidsize[0], self.vidsize[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img)

        # Create display list which draws to the quad to which the texture is rendered
        (x, y) = self.vidPos
        (w, h) = self.destsize

        x, y = int(x), int(y)
        w, h = int(w), int(h)

        self.frameQuad = glGenLists(1);
        glNewList(self.frameQuad, GL_COMPILE)
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 0.0)
        glVertex3i(x, y, 0)
        glTexCoord2f(1.0, 0.0)
        glVertex3i(x + w, y, 0)
        glTexCoord2f(1.0, 1.0)
        glVertex3i(x + w, y + h, 0)
        glTexCoord2f(0.0, 1.0)
        glVertex3i(x, y + h, 0)
        glEnd()
        glEndList()

        # Clear The Screen And The Depth Buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    def __texUpdate(self, frame):
        """ Update the texture with the newly supplied frame. """
        # Retrieve buffer from videosink
        if self.texture_locked:
            return
        self.buffer = frame
        self.texUpdated = True

    def __drawFrame(self):
        """ Draws a single frame. """
        # Clear The Screen And The Depth Buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glCallList(self.frameQuad)

    def play(self):
        """ Starts playback. """
        # Signal player to start video playback
        self.paused = False

        # Start listening for incoming audio frames
        if self.decoder.audioformat:
            self.audio.start()

        self.decoder.play()

        # While video is playing, render frames
        while self.decoder.status in [mediadecoder.PLAYING, mediadecoder.PAUSED]:
            texture_update_time = 0
            if self.texUpdated:
                t1 = time.time()
                # Update texture
                self.texture_locked = True
                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, self.vidsize[0],
                                self.vidsize[1], GL_RGB, GL_UNSIGNED_BYTE, self.buffer)
                self.texture_locked = False
                texture_update_time = int((time.time() - t1) * 1000)
                self.texUpdated = False

            # Draw the texture to the back buffer
            t1 = time.time()
            self.__drawFrame()
            draw_time = (time.time() - t1) * 1000
            # Flip the buffer to show frame to screen
            t1 = time.time()
            pygame.display.flip()
            flip_time = (time.time() - t1) * 1000

            logger.debug("================== Frame {} ========================"
                         "".format(self.decoder.current_frame_no))
            if texture_update_time:
                logger.debug("Texture updated in {0} ms".format(texture_update_time))
            logger.debug("Texture drawn in {0} ms".format(draw_time))
            logger.debug("Screen flipped in {0} ms".format(flip_time))
            logger.debug("-----------------------------------------------------")
            logger.debug("Total: {} ms".format(texture_update_time + draw_time + flip_time))

            for e in pygame.event.get():
                if e.type == pygame.QUIT:
                    self.stop()
                if e.type == pygame.KEYDOWN:
                    # Quitting
                    if e.key == pygame.K_ESCAPE:
                        self.stop()
                    # Pausing
                    elif e.key == pygame.K_SPACE:
                        self.pause()
                    # Seeking
                    elif e.key == pygame.K_RIGHT:
                        new_time = min(
                            self.decoder.current_playtime + 10,
                            self.decoder.duration)
                        self.decoder.seek(new_time)
                    elif e.key == pygame.K_LEFT:
                        new_time = max(
                            self.decoder.current_playtime - 10,
                            0)
                        self.decoder.seek(new_time)

            pygame.event.pump()  # Prevent freezing of screen while dragging

            # Without this sleep, the video rendering threard goes haywire...
            time.sleep(0.005)

        if self.decoder.audioformat:
            self.audio.close_stream()

        pygame.quit()

    def stop(self):
        """ Stops playback. """
        self.decoder.stop()

    def pause(self):
        """ Pauses playback. """
        if self.decoder.status == mediadecoder.PAUSED:
            self.decoder.pause()
            self.paused = False
        elif self.decoder.status == mediadecoder.PLAYING:
            self.decoder.pause()
            self.paused = True
        else:
            print("Player not in pausable state")
Exemple #6
0
class VideoPlayer():
    """ This is an example videoplayer that uses pygame+pyopengl to render a video.
	It uses the Decoder object to decode the video- and audiostream frame by frame.
	It shows each videoframe in a window and places the audioframes in a buffer
	(or queue) from which they are fetched by the soundrenderer object.
	"""
    def __init__(self,
                 dimensions,
                 fullscreen=False,
                 soundrenderer="pyaudio",
                 loop=False):
        """ Constructor.

		Parameters
		----------
		dimensions : tuple (width, height)
			The dimension of the window in which the video should be shown. Aspect
			ratio is maintained.
		fullscreen : bool, optional
			Indicates whether the video should be displayed in fullscreen.
		soundrenderer : {'pyaudio','pygame'}
			Designates which sound backend should render the sound.	
		"""

        pygame.init()
        (windowWidth, windowHeight) = dimensions
        flags = pygame.DOUBLEBUF | pygame.OPENGL | pygame.HWSURFACE
        self.fullscreen = fullscreen
        if fullscreen:
            flags = flags | pygame.FULLSCREEN
        pygame.display.set_mode((windowWidth, windowHeight), flags)
        self.windowSize = (windowWidth, windowHeight)

        self.soundrenderer = soundrenderer
        self.loop = loop
        self.texUpdated = False

        self.__initGL()

        self.decoder = Decoder(videorenderfunc=self.__texUpdate, )
        self.texture_locked = False

    def __initGL(self):
        glViewport(0, 0, self.windowSize[0], self.windowSize[1])

        glPushAttrib(GL_ENABLE_BIT)
        glDisable(GL_DEPTH_TEST)
        glDisable(GL_CULL_FACE)

        glDepthFunc(GL_ALWAYS)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        glMatrixMode(GL_PROJECTION)
        glPushMatrix()
        glLoadIdentity()
        glOrtho(0.0, self.windowSize[0], self.windowSize[1], 0.0, 0.0, 1.0)

        glMatrixMode(GL_MODELVIEW)
        glPushMatrix()

        glColor4f(1, 1, 1, 1)
        glClearColor(0.0, 0.0, 0.0, 1.0)
        glClearDepth(1.0)

    def calc_scaled_res(self, screen_res, image_res):
        """Calculate appropriate texture size.

		Calculate size or required texture so that it will fill the window, 
		but retains the movies original aspect ratio.
		
		Parameters
		----------
		screen_res : tuple
			Display window size/Resolution
		image_res : tuple
		    Image width and height

		Returns
		-------
		tuple 
			width and height of image scaled to window/screen
		"""
        rs = screen_res[0] / float(screen_res[1])
        ri = image_res[0] / float(image_res[1])

        if rs > ri:
            return (int(image_res[0] * screen_res[1] / image_res[1]),
                    screen_res[1])
        else:
            return (screen_res[0],
                    int(image_res[1] * screen_res[0] / image_res[0]))

    def load_media(self, vidSource):
        """ Loads a video.

		Parameters
		----------
		vidSource : str
			The path to the video file
		"""
        if not os.path.exists(vidSource):
            print("File not found: " + vidSource)
            pygame.display.quit()
            pygame.quit()
            sys.exit(1)

        self.decoder.load_media(vidSource)
        self.decoder.loop = self.loop
        pygame.display.set_caption(os.path.split(vidSource)[1])
        self.vidsize = self.decoder.clip.size

        self.destsize = self.calc_scaled_res(self.windowSize, self.vidsize)
        self.vidPos = ((self.windowSize[0] - self.destsize[0]) / 2,
                       (self.windowSize[1] - self.destsize[1]) / 2)

        self.__textureSetup()

        if (self.decoder.audioformat):
            if self.soundrenderer == "pygame":
                from mediadecoder.soundrenderers import SoundrendererPygame
                self.audio = SoundrendererPygame(self.decoder.audioformat)
            elif self.soundrenderer == "pyaudio":
                from mediadecoder.soundrenderers.pyaudiorenderer import SoundrendererPyAudio
                self.audio = SoundrendererPyAudio(self.decoder.audioformat)
            elif self.soundrenderer == "sounddevice":
                from mediadecoder.soundrenderers.sounddevicerenderer import SoundrendererSounddevice
                self.audio = SoundrendererSounddevice(self.decoder.audioformat)
            self.decoder.set_audiorenderer(self.audio)

    def __textureSetup(self):
        # Setup texture in OpenGL to render video to
        glEnable(GL_TEXTURE_2D)
        glMatrixMode(GL_MODELVIEW)
        self.textureNo = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D, self.textureNo)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

        # Fill texture with black to begin with.
        img = np.zeros([self.vidsize[0], self.vidsize[1], 3], dtype=np.uint8)
        img.fill(0)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, self.vidsize[0],
                     self.vidsize[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img)

        # Create display list which draws to the quad to which the texture is rendered
        (x, y) = self.vidPos
        (w, h) = self.destsize

        x, y = int(x), int(y)
        w, h = int(w), int(h)

        self.frameQuad = glGenLists(1)
        glNewList(self.frameQuad, GL_COMPILE)
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 0.0)
        glVertex3i(x, y, 0)
        glTexCoord2f(1.0, 0.0)
        glVertex3i(x + w, y, 0)
        glTexCoord2f(1.0, 1.0)
        glVertex3i(x + w, y + h, 0)
        glTexCoord2f(0.0, 1.0)
        glVertex3i(x, y + h, 0)
        glEnd()
        glEndList()

        # Clear The Screen And The Depth Buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    def __texUpdate(self, frame):
        """ Update the texture with the newly supplied frame. """
        # Retrieve buffer from videosink
        if self.texture_locked:
            return
        self.buffer = frame
        self.texUpdated = True

    def __drawFrame(self):
        """ Draws a single frame. """
        # Clear The Screen And The Depth Buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glCallList(self.frameQuad)

    def play(self):
        """ Starts playback. """
        # Signal player to start video playback
        self.paused = False

        # Start listening for incoming audio frames
        if self.decoder.audioformat:
            self.audio.start()

        self.decoder.play()

        # While video is playing, render frames
        while self.decoder.status in [
                mediadecoder.PLAYING, mediadecoder.PAUSED
        ]:
            texture_update_time = 0
            if self.texUpdated:
                t1 = time.time()
                # Update texture
                self.texture_locked = True
                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, self.vidsize[0],
                                self.vidsize[1], GL_RGB, GL_UNSIGNED_BYTE,
                                self.buffer)
                self.texture_locked = False
                texture_update_time = int((time.time() - t1) * 1000)
                self.texUpdated = False

            # Draw the texture to the back buffer
            t1 = time.time()
            self.__drawFrame()
            draw_time = (time.time() - t1) * 1000
            # Flip the buffer to show frame to screen
            t1 = time.time()
            pygame.display.flip()
            flip_time = (time.time() - t1) * 1000

            logger.debug("================== Frame {} ========================"
                         "".format(self.decoder.current_frame_no))
            if texture_update_time:
                logger.debug(
                    "Texture updated in {0} ms".format(texture_update_time))
            logger.debug("Texture drawn in {0} ms".format(draw_time))
            logger.debug("Screen flipped in {0} ms".format(flip_time))
            logger.debug(
                "-----------------------------------------------------")
            logger.debug("Total: {} ms".format(texture_update_time +
                                               draw_time + flip_time))

            for e in pygame.event.get():
                if e.type == pygame.QUIT:
                    self.stop()
                if e.type == pygame.KEYDOWN:
                    # Quitting
                    if e.key == pygame.K_ESCAPE:
                        self.stop()
                    # Pausing
                    elif e.key == pygame.K_SPACE:
                        self.pause()
                    # Seeking
                    elif e.key == pygame.K_RIGHT:
                        new_time = min(self.decoder.current_playtime + 10,
                                       self.decoder.duration)
                        self.decoder.seek(new_time)
                    elif e.key == pygame.K_LEFT:
                        new_time = max(self.decoder.current_playtime - 10, 0)
                        self.decoder.seek(new_time)

            pygame.event.pump()  # Prevent freezing of screen while dragging

            # Without this sleep, the video rendering threard goes haywire...
            time.sleep(0.005)

        if self.decoder.audioformat:
            self.audio.close_stream()

        pygame.quit()

    def stop(self):
        """ Stops playback. """
        self.decoder.stop()

    def pause(self):
        """ Pauses playback. """
        if self.decoder.status == mediadecoder.PAUSED:
            self.decoder.pause()
            self.paused = False
        elif self.decoder.status == mediadecoder.PLAYING:
            self.decoder.pause()
            self.paused = True
        else:
            print("Player not in pausable state")