Question

I have 4 video files (different scenes of a movie).

There's a starting scene that will be played when I run the player. And before that scene ends, let's say the video player reads an int value (0-100) from external file (all happens at runtime), and depending on that int value, it has to determine which scene to play next.

pseudo example:

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

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

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

How can I make it change video sources at runtime, depending on that variable?

I don't care about the format of the video file, (Avi, mp4...) whatever works will be fine.

I don't know how to approach this problem. I've searched for something that has the potential to accomplish this, like pyglet or GStreamer, but I didn't find a clear solution.

EDIT: I have the basic player and video player with pyglet, and I was able to play the video without depending on a variable using this code:

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

How would I go about this? Guidance in the right direction and/or some sample code would be highly appreciated.

Thanks in advance.

Was it helpful?

Solution

Answer revised based on comments

If your goal is to constantly read a file that is receiving writes from the output of another process, you have a couple aspects that need to be solved...

  1. You either need to read a file periodically that is constantly being overwritten, or you need to tail the output of a file that is being appended to with new values.
  2. Your script currently blocks when you start the pyglet event loop, so this file check will have to be in a different thread, and then you would have to communicate the update event.

I can't fully comment on step 2 because I have never used pyglet and I am not familiar with how it uses events or signals. But I can at least suggest half of it with a thread.

Here is a super basic example of using a thread to read a file and report when a line is found:

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

The sleep loop at the end of the code is just a way to emulate your event loop and block.

Here is a test to show how it would work. First I open a python shell and open a new file:

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

Then you can start this script. And back in the shell you can start writing lines:

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

In your script terminal you will see it read and print the lines.

The other way would be if your process that is writing to this file is constantly overwriting it, you would instead just reread the file by setting monitor.seek(0) and calling readline().

Again this is a really simple example to get you started. There are more advanced ways of solving this I am sure. The next step would be to figure out how you can signal the pyglet event loop to call a method that will change your video source.

Update

You should review this section of the pyglet docs on how to create your own event dispatcher: http://pyglet.org/doc/programming_guide/creating_your_own_event_dispatcher.html

Again, without much knowledge of pyglet, here is what it might look like:

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

And for your thread class, you would pass in the dispatcher instance, and use the updateIndex() event to notify:

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)

        ...
        ...

Hope that gets you started!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top