pyglet Player.seek() causes unexpected results

0

I am trying to create a video player using the Pyglet for Python 3.4. The current code I have is very basic, and will simply play a file such as this math gif.

I want to loop the video until the window is closed, however trying to use player.seek() with any time is causing very odd behaviour.

An example of such behaviour is when playing a .gif, attempting to perform self.player.seek(self.player.time - 2) (as a "rewind" feature), the video will jump forward a few seconds, then freeze on that frame for a moment before continuing playback.

When attempting the same code while playing a .webm video file, nothing happens.
When attempting the same code while playing a .mp3 video file, the video would skip to to about 5 seconds in, regardless of how much time had elapsed.
When attempting the same code while playing a .m4v video file, the program failed with the following traceback:

Traceback (most recent call last):
  File "_ctypes/callbacks.c", line 234, in 'calling callback function'
  File "C:\Python34\lib\site-packages\pyglet\window\win32\__init__.py", line 617, in f
    result = event_handler(msg, wParam, lParam)
  File "C:\Python34\lib\site-packages\pyglet\window\win32\__init__.py", line 688, in _event_key
        self.dispatch_event(ev, symbol, modifiers)
  File "C:\Python34\lib\site-packages\pyglet\window\__init__.py", line 1154, in dispatch_event
    if EventDispatcher.dispatch_event(self, *args) != False:
  File "C:\Python34\lib\site-packages\pyglet\event.py", line 355, in dispatch_event
    if handler(*args):
  File "C:\Users\Matt\Documents\Coding\Pyglet Media Suite\video_player.py", line 30, in on_key_press
    self.player.seek(self.player.time - 2)
  File "C:\Python34\lib\site-packages\pyglet\media\__init__.py", line 1067, in seek
    self.source.seek(time)
  File "C:\Python34\lib\site-packages\pyglet\media\avbin.py", line 345, in seek
    av.avbin_seek_file(self._file, timestamp_to_avbin(timestamp))
  File "C:\Python34\lib\site-packages\pyglet\media\avbin.py", line 196, in f
    result = func(*args)
OSError: exception: access violation reading 0x00000028

I can understand that the .m4v file failed, as it is an Apple encoding, but the other failures confuse me. Specifically, why does seek() fail for .webm file formats.

My code is as follows:

import pyglet

class VideoPlayer(object):
    """Creates a new window and plays the requested video"""

    def __init__(self, filepath, fullscreen = False):
        self.filepath = filepath
        self.fullscreen = fullscreen
        self.window = pyglet.window.Window()
        self.video = pyglet.media.load(filepath)
        self.player = pyglet.media.Player()

        self.player.queue(self.video)

        @self.window.event
        def on_key_press(symbol, modifiers):
            key = pyglet.window.key
            if symbol == key.SPACE:
                if self.player.playing:
                    self.player.pause()
                    print("PAUSED")
                else:
                    self.player.play()
                    print("PLAYING")

            elif symbol == key.LEFT:
                self.player.seek(self.player.time - 2)
                print("Rewinding by 2 seconds")

        @self.window.event
        def on_draw():
            if (self.player.source.duration - self.player.time) < 0.1:
                # pyglet does not correctly handle EOS, so restart almost at the end
                self.player.source.seek(1.0)

            else:
                if self.player.playing:
                    self.player.get_texture().blit(0, 0)

        @self.window.event
        def on_close():
            self.player.delete()
            pyglet.app.exit()

        self.player.play()
        pyglet.app.run()

The reason I chose to try and use seek() is because Pyglet does not correctly handle EOS. Therefore I tried to simply seek back to the beginning of the video instead of using a more elegant "solution" like SourceGroups. I found a post which talks about the EOS problem in more detail.

How can I properly use seek()?

python
pyglet
seek
video-player
asked on Stack Overflow Jan 20, 2017 by Mattstir • edited Apr 7, 2019 by TrebledJ

1 Answer

0

I don't know if I can help, but I also stumbled upon inconsistent behavior with the seek function for a current project where I am trying to control audio playback via python.

The first thing I notice in your code, is that in the on_draw() function you call seek for the media source. But seek has to be called from the player object.

The only guess I can make is that you are using a version of AVbin that has a bug of some kind. pyglet uses AVbin to support a vast array of different media formats other than wav. If you are using AVbin for video playback, you may try to install a different version and try it out again.

One thing that has helped me to improve the behavior of the seek function on my media source is to load your video as StaticSource (setting "streaming=False") as second parameter in

pyglet.media.load(filepath)

Sadly, as of pyglet version 1.2.4, this feature is not supported for video formats.

answered on Stack Overflow Jan 21, 2017 by Simon E.

User contributions licensed under CC BY-SA 3.0