PyAudio
ライブラリを非同期コンテキストで使用したいのですが、ライブラリのメインエントリポイントにはコールバックベースのAPIしかありません。
_import pyaudio
def callback(in_data, frame_count, time_info, status):
# Do something with data
pa = pyaudio.PyAudio()
self.stream = self.pa.open(
stream_callback=callback
)
_
私がそれを使用したいと思っている方法は次のようなものです:
_pa = SOME_ASYNC_COROUTINE()
async def listen():
async for block in pa:
# Do something with block
_
問題は、このコールバック構文を、コールバックが発生したときに完了するフューチャーに変換する方法がわからないことです。 JavaScriptでは promise.promisify()
を使用しますが、Pythonにはそのようなものはないようです。
Future を使用することもできます
クラスasyncio.Future(*、loop = None)¶
Futureは、非同期操作の最終的な結果を表します。スレッドセーフではありません。
未来は待ち望まれるオブジェクトです。コルーチンは、結果または例外が設定されるか、キャンセルされるまで、Futureオブジェクトを待機できます。
通常、Futureは低レベルのコールバックベースのコード(asyncioトランスポートを使用して実装されたプロトコルなど)を高レベルの非同期/待機コードと相互運用できるようにするために使用されます。
経験則では、ユーザー向けAPIでFutureオブジェクトを公開しないでください。Futureオブジェクトを作成するための推奨方法は、loop.create_future()を呼び出すことです。このようにして、代替イベントループ実装は、Futureオブジェクトの独自の最適化された実装を注入できます。
ばかげた例:
def my_func(loop):
fut = loop.create_future()
pa.open(
stream_callback=lambda *a, **kw: fut.set_result([a, kw])
)
return fut
async def main(loop):
result = await my_func(loop) # returns a list with args and kwargs
pa.open
は、スレッドまたはサブプロセスで実行されます。そうでない場合は、open
への呼び出しを asyncio.loop.run_in_executor でラップする必要がある場合もあります。