pyglet Player.seek()会导致意外结果

时间:2017-01-20 21:42:38

标签: python pyglet seek video-player

我正在尝试使用Pyglet for Python 3.4创建一个视频播放器。我当前的代码非常基本,只会播放this math gif等文件。

我想循环播放视频直到窗口关闭,但是尝试随时使用.gif会导致非常奇怪的行为。

此类行为的一个示例是,在播放self.player.seek(self.player.time - 2),尝试执行.webm时(作为"倒带"功能),视频将跳转前进几秒钟,然后在该帧上暂停一会儿,然后继续播放。

在播放.mp3视频文件时尝试使用相同的代码时,没有任何反应 在播放.m4v视频文件时尝试使用相同的代码时,无论已经过了多长时间,视频都会跳至大约5秒钟。 在播放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 视频文件时尝试使用相同的代码时,程序会因以下追溯而失败:

.m4v

我可以理解seek()文件失败了,因为它是Apple编码,但其他失败让我感到困惑。具体来说,为什么.webm文件格式失败{。}}。

我的代码如下:

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()

我选择尝试使用seek()的原因是因为Pyglet无法正确处理EOS。因此,我试着回到视频的开头而不是使用更优雅的解决方案&#34;比如SourceGroups。我发现了post更详细地讨论了EOS问题。

如何正确使用seek()

1 个答案:

答案 0 :(得分:0)

我不知道我是否可以提供帮助,但我也偶然发现当前项目的搜索功能不一致,我试图通过python控制音频播放。

我在你的代码中注意到的第一件事是你在on_draw()函数中调用了搜索媒体源。但是必须从玩家对象中调用搜索。

我唯一可以猜到的是你使用的AVbin版本有某种bug。 pyglet使用AVbin来支持除wav之外的大量不同媒体格式。如果您使用AVbin进行视频播放,您可以尝试安装其他版本并再次尝试。

有助于我改善搜索功能在我的媒体源上的行为的一件事是将视频加载为StaticSource(设置&#34; streaming = False&#34;)作为

中的第二个参数
pyglet.media.load(filepath)

可悲的是,从pyglet 1.2.4版开始,视频格式不支持此功能。