2016-05-12 56 views
0

Raspberry Piでモーションが検出されたら、デフォルトのオーディオ再生でモーションディテクタを開発しています。Python:最初のタスクが終了したときにのみ2番目のタスクを実行するには

しかし、連続した動きが検出されると、次の音声は再生を開始し、前の音声が終了していなくても重なり始めます。

これをPythonで実装するためのループはありますか?

現在、私は別のものを再生する前に、オーディオの全長をタイマーループで使用しています。しかし、私はより良い解決策があると信じています。何か案が?

#!/usr/bin/python 

import sched, time 
s = sched.scheduler(time.time, time.sleep) 
def do_something(sc): 
    print "Doing stuff..." 
    # do your stuff 
    sc.enter(10, 1, do_something, (sc,)) 

s.enter(10, 1, do_something, (s,)) 
s.run() 
+0

理由だけではなく、ブール 'is_playing'をチェックしませんか? –

答えて

0

これは単なるアイデアですが、コメントではなく回答として書く方が簡単です。回避策は、機能を実行するたびに1を上回る状態を設定することです。 1以上の場合は、関数が終了するまで待ってから関数を再実行し、そうでなければ正常に関数を実行してください。

うまくいかない場合は、回答を削除しますが、可能性があります(2回の調整が必要です)。

import sched, time 
s = sched.scheduler(time.time, time.sleep) 
state = 0 

def do_something(sc): 
    global state 

    #increase the state, and cancel if it's over 1 (already running) 
    state += 1 
    if state > 1: 
     return 

    original_state = state 
    print "Doing stuff..." 
    # do your stuff 
    sc.enter(10, 1, do_something, (sc,)) 

    #Run again if the state has changed during the function 
    if original_state != state: 
     s.run() 
     state -= 1 
    state -= 1 

編集:動作するように思われる独自の機能を作成しました。バックグラウンドで実行され、状態のアイデアを使用してキューに入れられます。 time.sleep(0.01)部分は、最後の部分が次の部分の開始部分と重なっているように見えるだけです。 argskwargsを入力すると、空でもそれを渡すので、あなたの関数でそれらを許可する必要があります。

本体:あなたはそれを使用する方法

import time 
from threading import Thread 

class ThreadHelper(Thread): 
    def __init__(self, function, *args, **kwargs): 
     self.args = args 
     self.kwargs = kwargs 
     Thread.__init__(self) 
     self.function = function 

    def run(self): 
     self.function(*self.args, **self.kwargs) 

def run_once(func, *args, **kwargs): 
    global state 

    state[0] += 1 
    original_state = state[0] 

    if state[0] > 1: 
     return 

    func(*args, **kwargs) 
    time.sleep(0.01) 

    while state[0] != original_state: 
     state[0] -= 1 
     func(*args, **kwargs) 
     time.sleep(0.01) 

    state[0] -= 1 

def dosomething(*args, **kwargs): 
    print 'start' 
    time.sleep(0.5) 
    print 'end' 

state = [0] 
ThreadHelper(run_once, dosomething, _state=state).start() 
ThreadHelper(run_once, dosomething, _state=state).start() 
ThreadHelper(run_once, dosomething, _state=state).start() 
+0

これは 'do_something'の先頭に' global state'ステートメントが必要です –

+0

元の 'state = 0'が関数の外にある限り、何かをグローバルに宣言することなく、私のためにうまくいくようです。 – Peter

+0

コードを直接コピーして 'do_something(s) 'を追加すると、' UnboundLocalError:ローカル変数'状態 'が割り当て前に参照されています'というエラーが発生します。関数の外側にある 'state = 0'はまさに問題です。デフォルトでは、関数は 'state'を変更できないので、' state + = 1'は機能しません。 –

関連する問題