我正在实现一个语音聊天服务器,它将在我的 Windows 虚拟课堂电子学习应用程序中使用,它使用远程桌面 API。
到目前为止,我一直在使用 OPUS 压缩声音,并且测试了各种选项:
- 通过 RDP虚拟通道传递语音。这可行,但尽管使用 CHANNEL_PRIORITY_HI 创建频道,但它会产生很多延迟。
- 使用我自己的 TCP(或 UDP)语音服务器。对于这个选项,我一直想知道什么是最好的实现方法。
目前我正在将收到的 udp 数据报发送给所有其他客户端(稍后我将进行服务器端混合)。
我当前的 UDP 语音服务器的问题是即使在同一台电脑中也有延迟:例如,一台服务器和四个客户端连接,其中两个有开放式麦克风。
我在这个设置中听到了延迟:
void VoiceServer(int port)
{
XSOCKET Y = make_shared<XSOCKET>(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (!Y->Bind(port))
return;
auto VoiceServer2 = [&]()
{
OPUSBUFF o;
char d[200] = { 0 };
map<int, vector<char>> udps;
for (;;)
{
// get datagram
int sle = sizeof(sockaddr_in6);
int r = recvfrom(*Y, o.d, 4000, 0, (sockaddr*)d, &sle);
if (r <= 0)
break;
// a MESSAGE is a header and opus data follows
MESSAGE* m = (MESSAGE*)o.d;
// have we received data from this client already?
// m->arb holds the RDP ID of the user
if (udps.find(m->arb) == udps.end())
{
vector<char>& uu = udps[m->arb];
uu.resize(sle);
memcpy(uu.data(), d, sle);
}
for (auto& att2 : aatts) // attendee list
{
long lxid = 0;
att2->get_Id(&lxid);
#ifndef _DEBUG
if (lxid == m->arb) // if same
continue;
#endif
const vector<char>& uud = udps[lxid];
sendto(*Y, o.d + sizeof(MESSAGE), r - sizeof(MESSAGE), 0, (sockaddr*)uud.data(), uud.size());
}
}
};
// 10 threads receiving
for (int i = 0; i < 9; i++)
{
std::thread t(VoiceServer2);
t.detach();
}
VoiceServer2();
}
每个客户端运行一个 VoiceServer 线程:
void VoiceServer()
{
char b[4000] = { 0 };
vector<char> d2;
for (;;)
{
int r = recvfrom(Socket, b, 4000, 0, 0,0);
if (r <= 0)
break;
d2.resize(r);
memcpy(d2.data(), b, r);
if (audioin && wout)
audioin->push(d2); // this pushes the buffer to a waveOut writing class
SetEvent(hPlayEvent);
}
}
这是因为我在同一台机器上测试吗?但是对于我过去设置的 TeamSpeak 客户端,没有任何延迟。
感谢您的意见。