@discordjs/voice(discordのvoice gateway)を理解する
Discordは音声接続のために3種の接続を用いている
これによって例えばユーザーのミュート状態、接続先のVCの情報、Voice Gatewayとの接続のための認証情報などが送受信される。 これで例えばユーザーが発言中などの情報がやり取りされる。
また、RTP接続のための認証情報もここでやり取りされる。
これが実際の音声のやり取りに使用される。
API Docs
これらの接続をどのように使用するのかは以下の図を参照すると少しわかるかもしれない
初回接続の成功時の図
code:txt
@discord.js/voice discord.js Gateway Voice Gateway RTP Server
| | | | |
---------------------------------- joinVoiceChannel ----------------------------------
----------------------- (VoiceConnectionStatus.Signalling) ---------------------------
|----------------->| sendPayload(VoiceStateUpdate)
|---------->| VoiceStateUpdate
|<----------| VoiceServerUpdate
|<----------------| onVoiceServerUpdate
-------- (VoiceConnectionStatus.Connecting,NetworkingStatusCode.OpeningWs) ------------
|---------------------------------------------------->| VoiceOpcodes.Identify
-------- (VoiceConnectionStatus.Connecting,NetworkingStatusCode.Identifying) ----------
|<----------------------------------------------------| VoiceOpcodes.Ready
------- (VoiceConnectionStatus.Connecting,NetworkingStatusCode.UdpHandshaking) --------
|--------------------------------------------------------------------->| IP Discovery
|<---------------------------------------------------------------------| IP Discovery
----- (VoiceConnectionStatus.Connecting,NetworkingStatusCode.SelectingProtocol) ------
|---------------------------------------------------->| VoiceOpcodes.SelectProtocol
|<----------------------------------------------------| VoiceOpcodes.SessionDescription
-------------- (VoiceConnectionStatus.Ready,NetworkingStatusCode.Ready) ---------------
この後は自由に音声を送受信できる。
以下の状態を持つ
Signalling
Voice Gatewayに接続するまでの状態
Disconnected
音声接続が切断された状態(再利用可能)
Connecting
Voice Gatewayへの接続の開始後、音声の送受信が可能になるまでの状態
Ready
音声の送受信が可能な状態
Destroyed
VoiceConnectionが破棄された状態(再利用不可)
https://gyazo.com/b9fa6374a1524affd431594632eca056
音声の再生に関する機能を持つ
以下の状態を持つ
Idle
Buffering
Playing
Paused
AutoPaused
音源を表す
内部的にはGraphというデータを変換する概念を連結したもの
例: ffmpeg -> @discordjs/opus
@discordjs/voiceが音声接続に必要な情報をGateway APIと接続するライブラリ(例えばdiscord.js。以下discord.jsとして説明する)とやり取りするためのメソッド(これがadapter)をやり取りするメソッド 型定義は以下のとおりである。
DiscordGatewayAdapterCreator: (methods: DiscordGatewayAdapterLibraryMethods) => DiscordGatewayAdapterImplementerMethods
DiscordGatewayAdapterLibraryMethods
@discordjs/voiceがあるギルドで特定のGateway Eventsが発生したときに呼び出してほしい複数の関数や、Gateway接続が終了された旨をdiscord.jsから@discordjs/voiceへ伝えるための関数がオブジェクトにまとめられて渡されて呼び出される。 @discordjs/voiceがAdapterCreatorをDiscordGatewayAdapterLibraryMethodsを引数として呼び出し、discord.jsはこれを保存しておきイベント発生時に呼び出す
DiscordGatewayAdapterImplementerMethods
discord.jsはAdapterCreatorの呼び出しに対してDiscordGatewayAdapterImplementerMethodsを返し、@discordjs/voiceはこれを保存しておき呼び出す
disconnect と destroyの違い
destroy
無条件で可能
VoiceChannelから切断する
実行したVoiceConnectionは再利用できない
disconnect
状態がSignallingおよびDestroyedの場合は実行してもfalse(失敗)が返ってくる。
VoiceChannelから切断する
実行したVoiceConnectionを再利用することもできる