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 など) は気にしません。

この問題にアプローチする方法がわかりません。pygletGStreamerなど、これを達成する可能性があるものを探しましたが、明確な解決策が見つかりませんでした。

編集: 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 イベント ループを開始するとスクリプトがブロックされるため、このファイル チェックは別のスレッドで行う必要があり、その後、更新イベントを通信する必要があります。

pyglet を使用したことがなく、イベントやシグナルの使用方法に慣れていないため、ステップ 2 について完全にコメントすることはできません。しかし、少なくとも半分はスレッドで提案できます。

これは、スレッドを使用してファイルを読み取り、行が見つかったときに報告する非常に基本的な例です。

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 シェルを開き、新しいファイルを開きます。

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

その後、このスクリプトを開始できます。シェルに戻って、次の行を書き始めることができます。

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

スクリプト ターミナルでは、行を読み取って出力することがわかります。

もう1つの方法は、このファイルに書き込んでいるプロセスが常に上書きしている場合、代わりに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 に答える