我一直在考虑构建一个非常简单的Voice over IP程序,我想通过这个来创建它:
我会录制麦克风并且每隔2秒(或者甚至应该是1秒?)将它放入一个字符串(语音数据)中,通过插座发送到另一侧,另一侧将自动播放发送的字符串。
这是主要想法,但我想我会改变一两件事。
主要问题是 - 它会足够快吗?我不是在寻找像Skype这样超级快速的VOIP,但是它很棒......比如2秒deley(例如我说话后,2秒后其他人会听到我的话)或类似的东西...... < / p>
会不会很糟糕?也许我应该使用一个实现VOIP的开放式库? 因为我真想自己做点什么......
顺便说一句,我将使用C ++,当然使用UDP协议发送数据包......
那你觉得怎么样?
答案 0 :(得分:2)
如果您在传输音频前等待2秒钟,则感觉不像是对话。如果延迟超过100毫秒,可能是200毫秒,人们会感到恼火。
其次,VoIP应用程序通常用于与其他人交谈。在您的应用程序取得世界统治地位之前,可能最好还是建立一个已建立的VoIP协议(H.323或SIP),这样您就可以与其他人进行交流。只是一个想法。
答案 1 :(得分:2)
我不认为我会这样做。一个简单的事实是,在传输之前收集两秒钟(甚至一秒钟)的语音数据会让你失去很多,并且什么也得不到。
与普通开放协议相比,您可以在很多地方简化协议。典型的协议具有多种传输速率,存在检测,NAT遍历,多种编解码器等的各种选项。这使得正常的语音聊天程序相对复杂。通过消除它们中的大多数并只预先选择一组选项,您可以相当简化代码。
然而,每隔几毫秒发送一次数据包不很困难。相反,每隔几秒发送一次数据包就不会让你的代码变得更简单。如果有的话,它可能会使代码更复杂,因为你将不得不处理存储更多的数据。在典型情况下,您一次只处理几千字节的数据,因此存储几乎完全没有问题。如果您在传输之前存储了大量数据,那么存储数据将开始成为一个更加实质性的问题(尽管,公平地说,它仍然不会非常困难)。
就我个人而言,我认为我仍然会使用一些标准的编解码器,因此如果您决定这样做,代码和协议将很容易(或者更容易)扩展到更完整的东西。例如,如果我想让事情尽可能简单,我可能会首先使用G.711编解码器。即使这支持两种形式的压缩(mu-law和A-law),所以我可能会选择其中一种(可能是A-law)而只是使用它。
使用它,实际的编解码器(压缩/扩展代码)应该远低于100行代码(可能接近50行,具体取决于您喜欢格式化代码的方式)。如果需要,您可以在G.191下载国际电联的参考实现(注:G.191还包括许多其他编解码器的代码)。
它可以免费为您提供一定程度的压缩 。同样重要的是,它意味着您将构建代码以便在发送数据之前调用编码器对数据进行编码,并在收到数据后对其进行解码。如果您决定增强代码,最终选择不同的编码器/解码器,而不是尝试添加之前不存在的编码器/解码器(在这种情况下,您更可能需要完全重写)。
G.711旨在一次对样本缓冲区进行操作。支持的缓冲区大小为40,80,160和320个样本。如果你不关心延迟,320个样本将是显而易见的选择。使用它,您可以从输入(麦克风)读取320个样本,将其发送到压缩器,将结果放入UDP数据包,然后通过网络发送。根据需要重复。您可能希望在UDP数据包中包含序列号,因此接收端可以按顺序回放数据包。再说一遍,我可能会遵循一个标准。 RTP是非常微不足道的,它可能只增加了几十行代码(甚至可能比这更少)。
为尽可能简化,接收代码最初可能会忽略整个RTP标头,只接收数据包,解码有效负载,播放并重复。稍后,如果您发现数据包丢失和重新排序是一个问题,您可以添加代码来查看序列号和/或时间戳,并采取相应的行动。
这里的重点是等待2秒(或其他)不会使你的代码更简单。如果有的话,一次使用固定(和相当小)的样本数量可能会使代码更简单。你可以预先分配一些你关心的大小的缓冲区,并且只使用它们,而不是处理动态分配,因为你可能会一次缓冲几秒钟的数据。