An experimental sample of VoIP with Godot and netfox.
This sample implements a simple form of VoIP.
Voice data is captured from the microphone, quantized to 8 bits per sample, and then broadcasted as-is to other peers. Voice data is played back as it arrives.
To run the example, open it with Godot 4.x and click Run the Project, or press F5.
To setup VoIP in your own project, take the following steps.
The sample code relies on an audio bus configured specifically for recording sound. In the project, this bus is called Record, but can be changed.
The bus must have a Capture effect configured.
Mute the bus, so it is captured but not played back.
Copy the VoIP-related scripts from the example to your project:
scripts/voice-source.gd
scripts/voice-sink.gd
scripts/voip-sink.gd
Add a VoiceSource
node to your scene. Make sure to set the bus_name
to the
bus you've configured in the Audio setup step earlier. The node will emit
on_data
events with audio buffers.
To push voice over the network, add a VoipSink
node. Make sure to set its
multiplayer authority ( from code ).
Sinks by themselves do nothing, they expect data to be pushed to them from
other nodes. To do so, connect the VoiceSource
node's on_data
signal to the
VoipSink
's push_data
method.
Currently, no audio compression is implemented. This means ~11kb/s upload for each player, and ~11kb/s download for each player per player and ~11kb/s upload for the server per player.
To take an example with 4 players, the server will have a 44kb/s upload and 33 kb/s download, while the other players will have a 33kb/s download and 11kb/s upload ( since nobody downloads their own voice ).
The builtin PackedByteArray.compress implements some compression algorithms, but they are lossless, general, and don't work well for voice. During development, they actually increased size.
Integrating the Opus codec would be a great fit to compress audio data before sending it through the network. There's another project called libopus-gdnative-voip-demo that does exactly this, but the Opus integration behind it is Godot 3.x only.
In theory, the sample should work fine, as it uses RPCs like any other game would.
In practice, I've encountered cases where voice was one-way only.
This is an experimental sample to see if Godot's capable of VoIP.
This also means that currently there's no plans to build this sample further, as proper maintenance would take too much bandwidth for now. However, we encourage you to take a look, see if you can reuse or learn something, fork the repo and/or contribute.
Things that are supported and will be fixed if reported:
- Documentation issues
- example: Typo in documentation comment
- example: Readme is not up to date
- Implementation bugs
- Flaws/unexpected behaviour in project's existing scope
- Case-by-case basis, smaller fixes are OK, large overhauls are not planned
Yes and no.
For the example code, it is needed for events and its noray integration.
If you want to use VoIP in your own project, it is not necessary.
However, the example itself uses netfox, hence the project name.
For the example, the goal was to have 3D playback.
Due to Godot's class layout, AudioStreamPlayer3D, AudioStreamPlayer2D and AudioStreamPlayer don't have a shared parent class that plays back sound.
So if you need non-3D playback, you'll need to update VoiceSink
.
New features are currently not planned. However, PR's are always welcome!
If you've encountered an issue that is covered by the Support, feel free to open an issue!
This project is under the MIT License.