本指南介绍了如何解决常见的 Google Meet Media API 错误。
排查错误代码问题
以下是有关问题排查的提示,可帮助您解决 connectActiveConference
端点返回的错误代码:
错误代码 | |
---|---|
NO_ACTIVE_CONFERENCE |
检查 Meet Media API 客户端是否仅在经过身份验证的用户已在会议空间的会议中时尝试连接。 |
INVALID_OFFER |
仔细阅读优惠要求,检查是否有任何缺失的详细信息,例如是否已打开所需的数据渠道。您还可以将应用的优惠字符串与示例优惠进行比较,并调查任何差异。 |
INCOMPATIBLE_DEVICE |
会议中的一个或多个设备与 Meet Media API 客户端不兼容。您的应用将无法加入,因此您可能需要将此情况告知最终用户。 |
CONNECTIONS_EXHAUSTED |
一次只能有一个 Meet Media API 客户端连接到会议。如果应用崩溃,则在尝试重新连接时可能会看到此错误。在这种情况下,请等待大约 30 秒,让 Meet 超时处理之前的连接。然后,再试一次。 |
统一方案
如果数据通道始终未打开,并且您始终未收到音频或视频,请检查在配置本地对等连接时是否仅使用了统一方案。
媒体说明顺序错误
使用 Session Description Protocol (SDP) 提议创建对等连接时,您可能会看到以下错误:
Failed to execute 'setRemoteDescription' on 'RTCPeerConnection':
Failed to set remote answer sdp:
The order of m-lines in answer doesn't match order in offer. Rejecting answer.
这意味着 SDP 应答中的媒体说明行与 SDP 提议中的媒体说明不一致:
SDP 优惠 | SDP 回答 |
---|---|
✅ m=audio 9 UDP/TLS/RTP/SAVPF 111 |
✅ m=audio 9 UDP/TLS/RTP/SAVPF 111 |
❌ m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 |
❌ m=audio 9 UDP/TLS/RTP/SAVPF 111 |
✅ m=audio 9 UDP/TLS/RTP/SAVPF 111 |
✅ m=audio 9 UDP/TLS/RTP/SAVPF 111 |
❌ m=audio 9 UDP/TLS/RTP/SAVPF 111 |
❌ m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 |
若要修正此错误,请确保在设置对等连接对象时,类似媒体类型已正确配置并分组在一起。不支持交错的媒体说明。
以下代码示例展示了如何正确匹配媒体说明:
C++
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection;
// Signal the entire video at once.
for (uint32_t i = 0; i < configurations.receiving_video_stream_count; ++i) {
webrtc::RtpTransceiverInit video_init;
video_init.direction = webrtc::RtpTransceiverDirection::kRecvOnly;
video_init.stream_ids = {absl::StrCat("video_stream_", i)};
webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
video_result = peer_connection->AddTransceiver(
cricket::MediaType::MEDIA_TYPE_VIDEO, video_init);
// . . .
}
JavaScript
pc = new RTCPeerConnection();
// Signal the entire video at once.
pc.addTransceiver(video, {'direction':'recvonly'});
pc.addTransceiver(video, {'direction':'recvonly'});
pc.addTransceiver(video, {'direction':'recvonly'});
DTLS 角色属性错误
设置 DTLS 角色属性时,您可能会看到以下错误:
All DTLS roles must be one of [ACTIVE, ACTPASS].
如果未针对 SDP offer 中的所有媒体说明正确设置 a=setup:< >
属性,就会发生此错误。
如需修正此错误,请确保 SDP 提议中的每个媒体说明都具有以下必需属性之一:
a=setup:actpass
a=setup:active
v=0
o=- 4743178474630771513 3 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS
. . .
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101
. . .
a=setup:actpass
. . .
m=audio 39807 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
. . .
a=setup:actpass
. . .
排查音频问题
以下部分可帮助您解决应用中的音频问题。
查看日志
如果您在 Chrome 浏览器中使用 Web 客户端,请执行以下操作:
- 打开新标签页,然后在地址栏中输入:
chrome://webrtc-internals
。 - 前往标有
Stats graph for inbound-rtp
的部分。 - 检查每个音频图,看看是否正在接收数据包。
如果您使用的是 C++ 参考客户端,请检查是否曾调用过 OnAudioFrame
。
验证 OAuth 范围
只有在初始连接请求中提供适当的范围时,才会传输音频。如需解决此错误,请确保提供正确的 OAuth 2.0 范围。如需了解详情,请参阅了解 Media API 范围。
验证会议是否已正确设置
当客户端连接到 Google Meet 服务器时,系统不会自动允许其加入会议。确保您已通过会话控制数据通道收到会话控制资源更新,且状态为
STATE_JOINED
。{"sessionStatus":{"connectionState":"STATE_JOINED"}}
确认有其他会议参与者的音频流未被静音。
验证音频信号
只有在 SDP offer 中发出此信号时,Meet 才会仅提供音频。相应优惠中必须存在 3 个仅接收音频的媒体说明。
m=audio 39807 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
. . .
a=mid:0
. . .
a=recvonly
. . .
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
. . .
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
. . .
a=mid:1
. . .
a=recvonly
. . .
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
. . .
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
. . .
a=mid:2
. . .
a=recvonly
. . .
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
. . .
如果 Meet 服务器收到有效的 offer,则会以 SDP answer 进行响应,其中包含三个仅发送的音频媒体描述。
m=audio 19306 UDP/TLS/RTP/SAVPF 111
. . .
a=mid:0
. . .
a=sendonly
a=msid:virtual-6666 virtual-6666
. . .
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
. . .
m=audio 9 UDP/TLS/RTP/SAVPF 111
. . .
a=mid:1
. . .
a=sendonly
a=msid:virtual-6667 virtual-6667
. . .
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
. . .
m=audio 9 UDP/TLS/RTP/SAVPF 111
. . .
a=mid:2
. . .
a=sendonly
a=msid:virtual-6668 virtual-6668
. . .
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
. . .
检查您的观察者实现
如果您将数据处理移至其他线程,请务必制作音频数据的副本。
AudioFrame.pcm16
实际上是对底层数据的引用,因此在 OnAudioFrame
之后尝试访问它会导致未定义的行为,例如出现分段错误。
排查视频问题
以下部分可帮助您解决应用中的视频问题。
查看日志
如果您在 Chrome 浏览器中使用 Web 客户端,请执行以下操作:
- 打开新标签页,然后在地址栏中输入:
chrome://webrtc-internals
。 - 前往标有
Stats graph for inbound-rtp
的部分。 - 检查每个视频图表,看看是否收到了数据包。
如果您使用的是 C++ 参考客户端,请检查是否曾调用过 OnVideoFrame
。
验证 OAuth 范围
仅当初始连接请求中提供了适当的范围时,才会传输视频。如需解决此错误,请确保提供正确的 OAuth 2.0 范围。如需了解详情,请参阅了解 Media API 范围。
验证会议是否已正确设置
当客户端连接到 Meet 服务器时,系统不会自动允许其加入会议。确保您已通过会话控制数据通道收到会话控制资源更新,且状态为
STATE_JOINED
。{"sessionStatus":{"connectionState":"STATE_JOINED"}}
确认有其他会议参与者的视频流未被静音。
验证视频信号
只有在 SDP offer 中发出信号时,Meet 才会提供视频。相应出价中必须存在最多三个仅接收视频的媒体说明。
v=0
o=- 4743178474630771513 3 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS
. . .
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 35 36 37 38 102 103 104 105 106 107 108 109 127 125 39 40 41 42 43 44 45 46 47 48 112 113 114 115 116 117 118 49
. . .
a=setup:actpass
a=mid:1
. . .
a=recvonly
. . .
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
. . .
如果 Meet 收到有效的提议,则会以包含 n
个仅发送视频媒体说明的 SDP 应答进行响应,其中 n
是 SDP 提议中视频媒体说明的数量。
v=0
o=- 0 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS virtual-video-7777/7777
a=ice-lite
. . .
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99
. . .
a=setup:passive
a=mid:1
. . .
a=msid:virtual-video-7777/7777 virtual-video-7777/7777
a=rtcp-mux
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtcp-fb:96 goog-remb
. . .
排查无视频问题
- 检查发送给 Meet 服务器的 SDP offer 中是否存在
m=video …
。 - 检查确认
a=recvonly
是每个m=video
行下的一个属性。 - 检查 SDP 回答中是否存在相同数量的
m=video
行。 - 检查
a=sendonly
或a=sendrecv
是否是 SDP 回答中每个m=video
行下的属性。 - 检查是否已向 Meet 服务器成功发送并接收
VideoAssignmentRequest
。成功或失败应通过同一数据渠道传回给客户端。
排查视频流数量低于预期的问题
- 检查 SDP offer 是否包含正确数量的
m=video …
行。 - 确保 SDP 应答中的所有
m=video
说明都包含a=sendonly
或a=sendrecv
属性。答案中标记为a=recvonly
的任何行都会相应减少发送到客户端的数据流数量。
检查您的观察者实现
如果您将数据处理移至其他线程,请务必制作视频数据的副本。
VideoFrame.frame
实际上是对底层数据的引用,因此在 OnVideoFrame
之后尝试访问它会导致未定义的行为,例如内存段错误。