1

我有 4 个视频文件(电影的不同场景)。

当我运行播放器时,将播放一个起始场景。在该场景结束之前,假设视频播放器从外部文件中读取一个 int 值 (0-100)(所有这些都发生在运行时),并且根据该 int 值,它必须确定接下来要播放哪个场景。

伪示例:

        if (x > 0 && x < 30)
           videoSource = scene2

        else if (x >= 30 && x < 60)
           videoSource = scene3

        else if (x >= 60 && x <= 100)
            videoSource = scene 4

如何让它在运行时更改视频源,具体取决于该变量?

我不关心视频文件的格式,(Avi,mp4 ...)任何工作都可以。

我不知道如何解决这个问题。我已经搜索了有可能实现此目的的东西,例如pygletGS​​treamer,但我没有找到明确的解决方案。

编辑:我有 pyglet 的基本播放器和视频播放器,我能够播放视频而不依赖于使用此代码的变量:

import pyglet
vidPath="sample.mpg"
window = pyglet.window.Window()
player = pyglet.media.Player()
source = pyglet.media.StreamingSource()
MediaLoad = pyglet.media.load(vidPath)

player.queue(MediaLoad)
player.play()

@window.event
def on_draw():
  window.clear()
  if player.source and player.source.video_format:
    player.get_texture().blit(0,0)

pyglet.app.run()

我该怎么办?非常感谢您提供正确方向的指导和/或一些示例代码。

提前致谢。

4

1 回答 1

2

根据评论修改答案

如果您的目标是不断读取从另一个进程的输出接收写入的文件,那么您有几个方面需要解决......

  1. 您要么需要定期读取一个不断被覆盖的文件,要么需要尾随一个文件的输出,该文件正在附加新值。
  2. 当您启动 pyglet 事件循环时,您的脚本当前会阻塞,因此此文件检查必须在不同的线程中,然后您必须传达更新事件。

我不能完全评论第 2 步,因为我从未使用过 pyglet,而且我不熟悉它如何使用事件或信号。但我至少可以用一个线程建议其中的一半。

这是一个使用线程读取文件并在找到行时报告的超级基本示例:

import time
from threading import Thread

class Monitor(object):

    def __init__(self):
        self._stop = False

    def run(self, inputFile, secs=3):
        self._stop = False

        with open(inputFile) as monitor:

            while True:
                line = monitor.readline().strip()
                if line.isdigit():

                    # this is where you would notify somehow
                    print int(line)

                time.sleep(secs)

                if self._stop:
                    return

    def stop(self):
        self._stop = True


if __name__ == "__main__":

    inputFile = "write.txt"

    monitor = Monitor()

    monitorThread = Thread(target=monitor.run, args=(inputFile, 1))
    monitorThread.start()

    try:
        while True:
            time.sleep(.25)

    except:
        monitor.stop()

代码末尾的睡眠循环只是模拟事件循环和阻塞的一种方式。

这是一个测试来展示它是如何工作的。首先我打开一个 python shell 并打开一个新文件:

>>> f = open("write.txt", 'w+', 10)

然后你可以启动这个脚本。回到 shell,你可以开始写行:

>>> f.write('50\n'); f.flush()

在您的脚本终端中,您将看到它读取并打印行。

另一种方法是,如果您正在写入此文件的进程不断覆盖它,您只需通过设置monitor.seek(0)和调用 readline() 来重新读取文件。

同样,这是一个非常简单的示例,可以帮助您入门。我敢肯定,有更先进的方法可以解决这个问题。下一步是弄清楚如何向 pyglet 事件循环发出信号以调用将更改视频源的方法。

更新

您应该查看 pyglet 文档的这一部分,了解如何创建自己的事件调度程序:http: //pyglet.org/doc/programming_guide/creating_your_own_event_dispatcher.html

同样,在没有太多 pyglet 知识的情况下,它可能看起来像这样:

class VideoNotifier(pyglet.event.EventDispatcher):

    def updateIndex(self, value):
        self.dispatch_events('on_update_index', value)

VideoNotifier.register_event('on_update_index')


videoNotifier = VideoNotifier()

@videoNotifier.event
def on_update_index(newIndex):
    # thread has notified of an update
    # Change the video here
    pass

对于您的线程类,您将传入调度程序实例,并使用 updateIndex() 事件来通知:

class Monitor(object):

    def __init__(self, dispatcher):
        self._stop = False
        self._dispatcher = dispatcher

    def run(self, inputFile, secs=3):
        ...
        ...

        # should notify video of new value
        line = int(line_from_file)
        self._dispatcher.updateIndex(line)

        ...
        ...

希望这能让你开始!

于 2012-02-26T22:31:02.907 回答