質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.34%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

150閲覧

aiortcを使用して、リモートから受け取ったオーディオトラックをリアルタイムに再生したい。

hyt30

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2025/01/10 00:47

編集2025/01/10 08:02

実現したいこと

  • リアルタイムにオーディオを再生したい。

前提

webrtcをpythonで実装できる、aiortcのライブラリを使用して、
zoomやmeetのような、リアルタイムに通話できるシステムを作成しています。

発生している問題・エラーメッセージ

ピア接続が確立後、
以下のコードで、PyAVのAudioFrameをNumpy配列に変換し、
ノンブロッキングに、wirte()しています。

wirte()が5回ほど行われると、フリーズしてしまうのですが、
原因は何が考えられるでしょうか?

該当のソースコード

python

1import sounddevice as sd 2import numpy as np 3 4 # リモートのトラックを受信する 5 @peer_connection.on("track") 6 async def on_track(track): 7 print("receive track") 8 if track.kind == "audio": 9 print("audio track") 10 sample_rate = 48000 # サンプルレートを定義 11 channels = 2 # ステレオなのでチャンネル数を2に設定 12 13 stream = sd.OutputStream(samplerate=sample_rate, channels=channels) 14 15 stream.start() 16 17 try: 18 while True: 19 frame = await track.recv() 20 # pyavのAudioFrameをnumpy配列に変換 21 frame_data = frame.to_ndarray() 22 stereo_data = frame_data.reshape(960, 2) 23 print(f"Channels: {len(frame.layout.channels)}, Shape: {stereo_data.shape}") 24 # sounddeviceで再生 25 stream.write(stereo_data.astype(np.float32).copy()) 26 except Exception as e: 27 print(f"Error during audio playback: {e}") 28 finally: 29 stream.stop() 30 stream.close()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ライブラリは使ったことありませんが、
フリーズしそうな、気になった点を調べたところ

ノンブロッキングに、wirte()しています。

OutputStream.write はブロッキング・メソッドです。
https://python-sounddevice.readthedocs.io/en/0.5.1/usage.html#blocking-read-write-streams

⇒ 気になった点 async/await 対応なら write 時にも await があるはずです。

ノンブロッキングに書き込む場合は callback 形式になるようですが、
コードの見た目だけでも 読み込み/書き込み のループで対応させたい場合は、
キューに入れてから、別スレッドでキューからデータを読みだして write()

サンプルコードに sounddevice のストリームを asyncio (aiortc は詳しくないので別途調べて) で使う方法
ありましたが、sounddevice 自体が非同期対応ではなく、
非同期フレームワークのなかでどう工夫して使うかといった感じでした。
using a stream in an asyncio coroutin

await stream.write(...) みたいな事はできないようです。


他に考えられる要因は、エラーメッセージが出てなければ今回は関係ないかもしれませんが
(環境によってはエラーメッセージが出ない・出てる場所が解らないこともあるので、
エラーが正常にされるのを確認の上)try/except がループの外側なので、
何らかのエラーがあった場合に、ループは抜けて処理が終わることになります。

追記: ↑の場合は、ブロッキング処理がないから、質問にある「フリーズ」には該当しませんでした。訂正。

投稿2025/01/14 01:51

編集2025/01/14 10:53
teamikl

総合スコア8791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.34%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問