How do I publish participant metadata/attributes using Vivox? I need to include some stateful user data tied to a participant, such as a boolean to indicate whether or not the user has a microphone (so that I can “grey out” their speaker icon to others in order to indicate they don’t have a microphone).
How can I accomplish this with Vivox?
Other voice SDKs such as LiveKit have the ability to publish stateful user metadata via a key value store, but I didn’t see a mention of similar functionality in the Vivox documentation.
@NickFromVivox @mhakala do you have any recommendations?
Hey, Foreman_Dev!
For clarity, are you asking about the Core, Unreal, or Unity Vivox SDK?
For all of the above, there are certainly ways to access the information you’re looking for, but the advice will change depending on which one you’re developing with .
Hey there! I am asking about the Unity Vivox SDK. (Latest version of v16)
1 Like
If I look at the API reference for VivoxParticipant I don’t see a mention of user metadata besides DisplayName
and PlayerId
. Does Vivox not include functionality for user metadata, or am I looking in the wrong place?
A hacky workaround could be hijacking the DisplayName
string and using it as json key value store instead of its intended purpose. What I mean is literally filling in this string for DisplayName
:
{
"displayName": "PlayerDisplayName",
"hasMicrophoneDevice": true
}
And then parsing it back on the other end.
But this workaround is far from ideal since this metadata is set once when the user logs in and can’t be changed later.
Is there an actual way to do user metadata with Vivox?
Great, and thank you for all of the context!
I see what you’re aiming for~
While our VivoxParticipant
objects have various properties that are updated when a remote participant’s information changes, we do not currently provide a way to propagate out additional info that isn’t tracked by our properties (no metadata fields).
Additionally, audio device-related state is currently tracked local to the client and is not contextualized to a VivoxParticipant
(Example: VivoxService.Instance.AvailableInputDevices).
In order to communicate this to other players, you’d need to use game server logic or an additional service such as Lobby where you can do what you are thinking of.
For example, if you used Lobby you could create properties visible to everyone in the room and update them as you wish (Example). If you’d like to communicate a player’s local mute or device availability state, this is one way you could do it while using the local player’s VivoxService.Instance.SignedInPlayerId as a key.
Is a player’s local device state the only thing you were hoping to communicate to other players or are there additional details as well?
If you feel that this is inconvenient or less than ideal, please let me know and I’d be happy to relay that information back to the team!
Hey @UnityGarChar thanks for your reply.
Unfortunately this is insufficient and highlights a shortcoming of Vivox in comparison to other voice services. In my case I’m using a custom netcode implementation (FishNet), a custom backend, and using Vivox for voice chat. I will not be using Unity Lobby service.
Regardless, it should be possible for additional user metadata (such as a boolean for the user’s microphone device state hasMicrophoneDevice
) to be compartmentalized into the Vivox SDK itself so that I am able to communicate additional voice/chat-specific metadata and drop the same voice chat implementation into any project without introducing a dependency on a specific netcode/lobby implementation. If the answer is that I need to rely on a separate networking service to communicate additional user metadata such as the microphone device state, then this is insufficient. Other voice chat plugins (such as LiveKit) have the option to include additional user metadata within the voice plugin itself, as well as receive change events when any user metadata is updated. This allows the voice SDK to be self-sufficient and flexible to the needs of any project regardless of which netcode implementation is in use.
The inability to include custom participant metadata is a missing feature in Vivox compared to competitor voice chat plugins.
In my case, I want to include a boolean hasMicrophoneDevice
which is false if: 1) The user has no microphone devices present, or 2) The user denies microphone permission on an Android device such as the Meta Quest. And if that boolean is false, I grey-out that user’s speaker icon in the UI for other users so that they know that someone else doesn’t have a mic. However, the ability to include additional participant metadata is useful for a variety of other reasons. For example, allowing a user to set a custom “status”, or choosing an RGB color value to represent themself in a chat room.
The ability to include custom participant metadata should be added to Vivox. It’s useful for any voice chat or text chat service. It would be fairly straightforward to add this to Vivox.
Could you please communicate this to the Vivox team?
That being said, is there any reason I couldn’t use DisplayName
to hold a JSON string and essentially use that as a key/value datastore for custom metadata like I mentioned above?
If so, I realize that DisplayName
can’t be dynamically updated so I’d be limited to setting it only one time. But I’m currently only detecting microphone devices and mic permission on app startup, so for my specific use case that might be alright.
The length of our display name field is limited to a maximum of 127 bytes, plus a null terminator.
I checked the string you previously posted and it is larger than that, so you’d need to trim it a bit.
I believe that could work but, depending on the display name limitations of your app and if a user can give themselves a long display name, it may be fickle and susceptible to breaking.
Additionally, Vivox doesn’t enforce unique display names for users so if your app is not doing that there will be risks of conflicting keys if two users with the same display name join a channel together.
Those concerns aside, it should be able to work in theory. We don’t have strict character constraints on display names.
Thank you for checking that!
I think I can work around those limitations. If I only need to include a boolean to indicate the microphone device state, then perhaps I can use a more compact string format. For example, I could include a 0 or 1 at the beginning of the DisplayName
, then an underscore, then then the user’s actual display name after that. So it would look like 1_PlayerDisplayName
or 0_PlayerDisplayName
and I could parse the boolean and display name by finding the first occurrence of an underscore.
No worries as far as unique display names go - I arrange my player data by unique user ID, so that isn’t an issue. The display name is cosmetic and only shows up where needed in the UI.
For the DisplayName
size, you mentioned it’s limited to 127 bytes. What is the max character length for DisplayName
? In order to account for the byte limit I can truncate any usernames that would exceed the limit, but I just need to know the max supported characters.
If you will exclusively use the original ASCII values (0-127) in the string, you can expect our limit to be equal to 127 characters. If you expect to have display names with characters in the range beyond the original ASCII values, then that’ll need to be considered because the character limit will vary based on the input. For instance, something like ‘€’ will take up to 3 bytes. This is assuming your users have control over the display name and what goes into it~
Internally, this is how we convert the display name into bytes:
byte[] displaynameBytes = Encoding.UTF8.GetBytes(displayname);
We then check that it doesn’t exceed our limit of 127.
You could do something similar and truncate the string if it is going to exceed the 127 bytes that we cap out at. As long as the truncated string is consistent, this strategy sounds very reasonable!
@UnityGarChar Thanks for your help, I got it working. Now my player list UI shows a greyed-out speaker icon for those who don’t have a microphone device or don’t have microphone permission granted on android.
I also limited the DisplayName
string to 34 characters since the max for a Steam username is 32 chars, plus the 2 extra leading chars to indicate the boolean. That should keep it well under 127 bytes.
I will stress that it would be much better if Vivox included an official way to include custom user metadata related to each participant. What I ended up doing works, but it was a really hacky workaround and because I can only set it once, it doesn’t allow me to update the user’s metadata if they went and plugged in a microphone. Please consider this a feature request based on a real-life use case.
Thanks again for your help!
1 Like
I hadn’t initially replied but wanted to note that I have added the feedback here into our tracking system. I can’t commit to any future changes on the topic but it is on our radar for consideration.
1 Like
Thank you @NickFromVivox, I really appreciate that! It would undoubtedly be a worthwhile feature, making Vivox a more robust and complete voice solution. And it would hopefully not be very difficult to implement.