OpenAI RealTime 模型添加了一个新接口。现在它支持 WebRTC!本文是 WebRTC 专家 Gustavo Garcia 对此的看法和评测,一起来了解下。
鉴于有这么多人在研究它,我相信它一定很棒,所以还是像往常一样,让我们来看看音频传输方面到底是怎样的。
信令或建立连接
与 OpenAI 服务器建立实时会话有两种选择:
- WebSocket 信令:没有丑陋的 SDP,是更好的 API,但不太适合公共网络。
- HTTP/WebRTC 信令:具有较丑陋的 API,包括 SDP offer/answer,但可以在真实网络中良好运行,这对大多数使用案例至关重要。
在接下来的文章中,我们将只关注最有趣的后者(HTTP/WebRTC)。
验证
使用这些 RealTime API 直接从客户端向 OpenAI 服务器发送音频数据的第一步是使用 OpenAI API Secret 获取一个短暂密钥。这是一个简单的 HTTP 请求,可以通过命令行进行测试:
curl -X POST -H “Content-Type: application/json” -H “Authorization: Bearer OPENAI_API_SECRET” -d ‘{“model”: “gpt-4o-realtime-preview-2024–12–17”, “voice”: “verse”}’ https://api.openai.com/v1/realtime/sessions
有趣的是,检索到的凭证有效期很短,只有 60 秒。
该 API 的响应还包括 “audio_format”: “pcm16“,这看起来已经过时了,因为现在新的 WebRTC API 也支持 ”opus”,还有一些关于语音和静音检测的参数,我不确定开发人员是否有办法调整这些参数。
连接
WebRTC 连接仅使用 UDP 建立。没有 TURN 服务器或 ICE-TCP/SSLTCP 候选,因此不要指望此连接能在受限的公司网络中正常工作。
这可能没问题,因为在这些情况下你可以回退到 websockets API,尽管在我看来,OpenAI 应该提供一个执行该回退的 SDK,或者只是在答案中包含 iceServers 或 TCP 候选项。
所有示例还忽略了连接可能在某个时候断开的事实,您需要重新创建连接。这是另一个小功能,如果需要,可以隐藏在未来的 OpenAI SDK 中。
有趣的是,UDP 流量使用重用端口 3478 的老办法来尝试通过一些打开 STUN 流量的防火墙。另外,我在欧洲,分配给我的 WebRTC 服务器在美国,但我想一旦此 API 完成 Beta 测试,这种情况就会改变。
音频传输
正如 WebRTC 所预期的那样,音频传输是使用 Opus 编解码器以每秒 50 个数据包的速度进行的。此外还协商了 PCM 和 G722,因此它们可能也能正常工作,不过我不认为有理由将它们包括在内。
从下面的片段中可以看到服务器的整个 SDP 应答:
v=- 5732503706549353267 1734545489 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS realtimeapi
m=audio 3478 UDP/TLS/RTP/SAVPF 111 9 0 8
c=IN IP4 13.65.63.209
a=rtcp:3478 IN IP4 13.65.63.209
a=candidate:3461111247 1 udp 2130706431 13.65.63.209 3478 typ host generation 0
a=candidate:3461111247 2 udp 2130706431 13.65.63.209 3478 typ host generation 0
a=ice-ufrag:WGbWWofbaCZKJNIq
a=ice-pwd:SLqkjRNAwXPdKZsRmdlukcvcoPqUEsPw
a=fingerprint:sha-256 D7:A3:67:D9:49:5E:81:C5:A8:41:15:C1:A4:7A:FC:6F:51:8D:6F:6F:81:C2:A3:EB:BC:65:C0:B2:8A:26:4E:A7
a=setup:active
a=mid:0
a=extmap:3 <http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01>
a=sendrecv
a=msid:realtimeapi audio
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=ssrc:2472058689 cname:realtimeapi
a=ssrc:2472058689 msid:realtimeapi audio
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:WGbWWofbaCZKJNIq
a=ice-pwd:SLqkjRNAwXPdKZsRmdlukcvcoPqUEsPw
a=fingerprint:sha-256 D7:A3:67:D9:49:5E:81:C5:A8:41:15:C1:A4:7A:FC:6F:51:8D:6F:6F:81:C2:A3:EB:BC:65:C0:B2:8A:26:4E:A7
a=setup:active
a=mid:1
a=sctp-port:5000
鉴于用户可能大部分时间都处于静默状态,我本以为音频会启用不连续传输以减少带宽占用,但我猜 API 还没有优化。你可以看到它是如何一直以每秒 50 个数据包的速度收发的:
我考虑的另一个方案是降低上行链路音频比特率,因为 llm 可能并不需要惊人的音频质量来理解内容和与之相关的情感。
此外,还需要协商 transport-cc RTP 扩展,但它在这种纯音频用例中用途不大,或许可以取消,以消除传输中的一些微小开销。
在音频可靠性方面,opus inbandfec 是唯一的新增功能。没有 RED 或重传。鉴于 LLM 应能根据上下文推断出句子中缺失的部分,因此对于这种特定的使用情况来说,这可能是没有问题的。尽管如此,我还是看不出有什么理由至少不包括重传。
数据
建立了一个可靠的数据通道来接收来自服务器端的事件。这是一个很棒的功能,它提供了很大的灵活性,也是一个动态控制的通道(如使用的语音),而无需重新创建连接。
一旦开始发送和接收音频,就会收到很多事件。其中最有趣的事件包括:
- input_audio_buffer.speech_started: 当用户开始
- input_audio_buffer.speech_stopped: 当用户
- response.audio_transcript.delta:包括通过音频接收的文本的 deltas。
不出所料,接收文字比接收语音要快得多。这让我不禁怀疑,在某些情况下,阅读文本是不是比听声音更有效的 “对话 ”方式。
结论
很高兴看到新产品采用 WebRTC 并提供实时界面。对于测试版来说,其功能看起来很不错,我相信它会迅速发展。
我仍然不相信 Opus 和 WebRTC 是这种特定用例的最佳选择,在这种用例中,你是在与 “机器 ”对话,而不是在 “开会”,我希望将来我们最终会使用更多的定制编解码器和针对这种用例进行调整的传输方式,但我可能是错的。
原文:https://medium.com/@ggarciabernardo/openai-webrtc-api-review-79adadb699ee
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/webrtc/54964.html