🎙️
PycordでDiscordの音声を拾ってみる
Pycordにはボイスチャンネルの音声を録音する機能がある。
この機能で参加させた音声チャンネル内の音声を sink というオブジェクトに溜めファイルに変換することができるのだが、今回、ボットAが参加したチャンネル音声をボットBが参加している別のチャンネルに転送するみたいなことをしたかったため、ライブラリ内部でどんなことしているかを覗いてみた。
Pycordのstart_recording
の内部を見てみるとrecv_audio
をスレッドで実行していそうである。
self.decoder = opus.DecodeManager(self)
self.decoder.start()
self.recording = True
self.sink = sink
sink.init(self)
t = threading.Thread(
target=self.recv_audio,
args=(
sink,
callback,
*args,
),
)
t.start()
recv_audio
はソケットからデータを拾っており、unpack_audio
で音声データを取り出し、
OpusのデコーダーでPCMデータに変換している。 PCMのフォーマットは16-bit 48KHz ステレオ。
while self.recording:
ready, _, err = select.select([self.socket], [], [self.socket], 0.01)
if not ready:
if err:
print(f"Socket error: {err}")
continue
try:
data = self.socket.recv(4096)
except OSError:
self.stop_recording()
continue
self.unpack_audio(data)
デコーダーはrecv_decoded_audio
を呼び出しているのでこのメソッドをいじれば音声データをとりだせそうである。
Discordの音声データは発話したユーザー毎にやってくるのでこの音声データをMixして、転送すれば良さそう。
とりあえず、下記のような転送ボットを作ってみたが、PCM音声の合成の処理をもう少し上手くしないとちょっと音声が不安定になりそう。
Discussion