Для цикла, вызвать следующий / предыдущий элемент из внешней функции - PullRequest
0 голосов
/ 10 января 2019

Я только что получил в свои руки Python (Flask) в первый раз. Я пытаюсь создать простой API, который будет действовать как удаленный список воспроизведения с функциями Play / Pause / Stop / Prev / Next.

Мне удалось создать первые две функции (Play / Stop), но когда-нибудь мне понадобятся некоторые идеи (Prev / Next). Не забывайте, что в конце каждой итерации у меня происходит событие сна. Я использую многопоточность (Auto включен Flask), чтобы иметь возможность вызывать stop () , пока play () работает.

playing = 0


@app.route('/play', methods=['POST'])
def play():
    mediaFiles = request.json
    global playing
    playing = 1
    while playing == 1:
        for file in mediaFiles['mediaFiles']:
            if playing == 0:
                break
            print(file['path'])
            time.sleep(5)
    return 'Played'


@app.route('/stop')
def stop():
    global playing
    playing = 0
    return 'Stopped...'

Я попытался создать глобальную переменную 'currentIndex', которая будет отслеживать последний проигрываемый индекс в массиве, а затем использовать deque , чтобы повернуть массив и начать с позиции, где он был приостановлен , Это может сработать, но опять же у меня все еще есть функции Prev / Next

Я считаю, что есть лучший способ, чем использовать while и for, чтобы справиться с этим, потому что из того, что я вижу, может быть даже невозможно использовать этот подход и иметь (Prev / Next) функции.

1 Ответ

0 голосов
/ 10 января 2019

Все, что вам нужно, это сохранить текущий индекс для файла. Но только намек, но это может быть более или менее:

playing = 0

current_index = 0


@app.route('/play', methods=['POST'])
def play():
    mediaFiles = request.json
    global playing
    playing = 1
    while playing == 1:
        for current_index, file in enumerate(mediaFiles['mediaFiles'][current_index:], current_index):
            if playing == 0:
                break
            print(file['path'])
            time.sleep(5)
        current_index = 0            # loop back to 0 after last file
    return 'Played'

Предыдущие / Следующие функции просто должны были бы увеличивать / уменьшать current_index Сложность в том, что вам придется создать синхронизированный итератор для предотвращения условий гонки, если вы попытаетесь обновить current_index из разных потоков.

Например, вы можете использовать:

class syncenumerate:
    def __init__(self, lock, iterable, start=0):
        self.lock = lock
        self.iter = enumerate(iterable, start)
    def __iter__(self):
        return self
    def __next__(self):
        self.lock.acquire()
        try:
            ret = next(self.iter)
        finally:
            self.lock.release()    # ensure that the lock is released at StopIteration
        return ret

Вы легко получаете потокобезопасную синхронизацию:

playing=0
lck = threading.Lock()
current_changed = 0
...
    while playing == 1:
        for current_index, file in syncenumerate(lck, mediaFiles['mediaFiles']
                [current_index:], current_index):
            if current_changed = 1:    # restart enumeration is current was changed
                lck.acquire()
                current_changed = 0
                lck.release()
                break
            if playing == 0:
                ...

И изменить, например, в Next:

lck.acquire()
current_index += 1
if current_index >= max: current_index = 0
current_changed = 1
lck.release()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...