Воспроизведение разных видеофайлов в зависимости от значения переменной во время выполнения

У меня есть 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...), все, что работает, будет в порядке.

Я не знаю, как подойти к этой проблеме. Я искал что-то, что может сделать это, например pyglet или GStreamer, но четкого решения не нашел.

РЕДАКТИРОВАТЬ: у меня есть базовый проигрыватель и видеопроигрыватель с 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()

Как бы я это сделал? Руководство в правильном направлении и/или некоторый пример кода будут высоко оценены.

Заранее спасибо.


person Eyupium    schedule 26.02.2012    source источник
comment
Можете ли вы воспроизводить видеофайлы, не завися от переменной? Что вы пробовали?   -  person Peter Wood    schedule 27.02.2012
comment
Да, я могу. Я только что разместил код выше. Я использовал его для успешного воспроизведения видеофайла. Но потом я застреваю.   -  person Eyupium    schedule 27.02.2012


Ответы (1)


Ответ изменен на основе комментариев

Если ваша цель состоит в том, чтобы постоянно читать файл, который получает записи из выходных данных другого процесса, у вас есть пара аспектов, которые необходимо решить...

  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 и открываю новый файл:

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

Затем вы можете запустить этот скрипт. И снова в оболочке можно начинать писать строки:

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

        ...
        ...

Надеюсь, это поможет вам начать!

person jdi    schedule 26.02.2012
comment
Я не хотел усложнять вопрос лишними данными, но вот зачем и как мне нужна эта переменная: у меня есть устройство, которое будет связываться с ПК через последовательный порт, и оно будет отправлять значения и записывать их в файл. Теперь я хочу, чтобы проигрыватель читал из этого файла, а затем определял, какое видео воспроизводить дальше, не касаясь ничего другого. Я не хочу передавать какие-либо аргументы, как вы описали. Просто нужен способ изменить источник видеофайла в зависимости от этой переменной, и он должен сделать это во время выполнения. - person Eyupium; 27.02.2012
comment
Да, я не понял из вашего вопроса, что вам конкретно нужно было читать из файла, извините. Ну, есть разные подходы к этому. Ваш файл постоянно добавляется, и вы хотите отслеживать его вывод? Или вы хотите периодически проверять файл и читать его полные значения. Мне нужно больше информации о формате этого файла. - person jdi; 27.02.2012
comment
Ответ исправлен. Вы должны обновить свой вопрос, чтобы указать, что он должен одновременно отслеживать этот файл для новых значений с течением времени. Прямо сейчас это звучит так, как будто вы хотели однажды получить значения в свой скрипт, что гораздо проще сделать. - person jdi; 27.02.2012
comment
Мужик, ты мой король! Спасибо тебе большое за это. Мне действительно не приходило в голову использовать для этого потоки. Мне все еще нужно кое-что выяснить, так как я не очень много работал с потоками в Python, но я могу это сделать. Я попробовал ваш пример, а затем разработал версию, которая будет определять, каким должен быть следующий источник видео. Теперь мне просто нужно найти способ заставить Pyglet работать с потоками. Под этим я подразумеваю, что я не совсем понимаю, как создавать потоки для общения и влияния друг на друга, если это вообще возможно. - person Eyupium; 27.02.2012
comment
Я пытаюсь создать один поток, который будет запускать проигрыватель с первым видео, а затем другой поток, который будет проверять значения в файле (что мне удалось выполнить на данный момент), но я не знаю, как это сделать Пиглет для смены источника видео. Но это другой вопрос, который я начну с SO. Вы мне очень помогли. Как я и просил, вы направили меня в правильном направлении. Теперь я решил половину проблемы и знаю, что мне нужно дальше. Спасибо! - person Eyupium; 27.02.2012
comment
Без проблем! На самом деле я только что обновил свой ответ примером, чтобы вы начали отправлять события в pyglet. Я просто просмотрел его и собрал кое-что, что, вероятно, нуждается в тестировании. Но идея в том, что вы никогда не обращаетесь к методам вашего проигрывателя напрямую из потока. Вы отправляете событие из потока, который будет выбран и выполнен из вашего основного цикла событий. - person jdi; 27.02.2012