Steam voice chat stops working after server travel

I have a workaround, although it’s sort of hacky.

I pulled the OnlineSubsystemSteam plugin code into my project so I can modify it. In VoiceEngineSteam.h, I modified RegisterRemoteTalker (which is basically empty for steam) as follows:

virtual uint32 RegisterRemoteTalker(const FUniqueNetId& UniqueId) override
{
	const FUniqueNetIdSteam& SteamId = (const FUniqueNetIdSteam&)UniqueId;
	RemoteTalkerBuffers.Remove(SteamId);

	// Not needed in Steam
	return S_OK;
}

This will force the player’s talk buffer to be recreated. I had some trouble figuring out where to put this because of interface/scope craziness, so I just chose to put it here because it’s accessible through the interface. VoiceInterfaceSteam will not call the function if the talker has already been registered, however, so in VoiceInterfaceSteam.cpp I’ve modified the RegisterRemoteTalker function as follows:

bool FOnlineVoiceSteam::RegisterRemoteTalker(const FUniqueNetId& UniqueId) 
{
    uint32 Return = E_FAIL;

// Skip this if the session isn't active
if (SessionInt && SessionInt->GetNumSessions() > 0 &&
	// Or when voice is disabled
	VoiceEngine.IsValid())
{
	// See if this talker has already been registered or not
	FRemoteTalker* Talker = FindRemoteTalker(UniqueId);
	if (Talker == NULL)
	{
               ...
	}
	else
	{
		UE_LOG(LogVoice, Verbose, TEXT("Remote talker %s is being re-registered"), *UniqueId.ToDebugString());

		// call register anyways because we need to flush the buffer
		Return = VoiceEngine->RegisterRemoteTalker(UniqueId);
	}
	...
}

return Return == S_OK;
}

Then I’m just calling

VoiceInterface->RegisterRemoteTalker(SteamId)

for each player state after a seamless travel. The buffers get recreated and voice comes back immediately.

Obviously this is not an ideal solution, but it does technically solve the problem.