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

问题描述 投票:0回答:1

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

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

这种行为的一个例子是当播放.gif,尝试执行self.player.seek(self.player.time - 2)(作为“倒带”功能)时,视频将向前跳几秒钟,然后在该帧上冻结一会儿,然后继续播放。

在播放.webm视频文件时尝试相同的代码时,没有任何反应。 在播放.mp3视频文件时尝试使用相同的代码时,无论已经过了多长时间,视频都会跳到大约5秒钟。 在播放.m4v视频文件时尝试相同的代码时,程序失败并显示以下回溯:

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文件失败了,因为它是Apple编码,但其他失败让我感到困惑。具体来说,为什么seek()失败的.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。因此,我试图回到视频的开头,而不是像SourceGroups那样使用更优雅的“解决方案”。我找到了一个post,它更详细地讨论了EOS问题。

我怎样才能正确使用seek()

python pyglet seek video-player
1个回答
0
投票

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

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

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

有一件事帮助我改善了我的媒体源上的搜索功能的行为是将视频加载为StaticSource(设置“streaming = False”)作为第二个参数

pyglet.media.load(filepath)

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

© www.soinside.com 2019 - 2024. All rights reserved.