このガイドでは、Google Meet Media API でよく発生するエラーの解決方法について説明します。
エラーコードのトラブルシューティング
connectActiveConference
エンドポイントから返されるエラーコードのトラブルシューティングのヒントを以下に示します。
| エラーコード | |
|---|---|
NO_ACTIVE_CONFERENCE |
Meet Media API クライアントが、 認証済みユーザーが 会議スペースの会議にすでに参加している場合にのみ接続を試みるようにします。会議の開始をポーリングする場合は、会議の開始イベントを使用します。 |
INVALID_OFFER |
オファーの要件を読んで、必要なデータチャネルを開くなど、詳細が不足していないか確認します。アプリのオファー文字列を オファーの例 と比較して、違いを調べることもできます。 |
INCOMPATIBLE_DEVICE |
会議の 1 つ以上のデバイスが Meet Media API クライアントと互換性がありません。アプリは参加できないため、 エンドユーザーにその旨を伝えることができます。デバイスに関連付けられたアカウントが未成年と見なされる場合など、デバイスに互換性がない理由があります。詳細については、エンドユーザーの要件をご覧ください。 |
UNSUPPORTED_PLATFORM_PRESENT |
会議の 1 つ以上のデバイスが Meet Media API クライアントと互換性がありません。アプリは参加できないため、 エンドユーザーにその旨を伝えることができます。サポートされていないプラットフォームの理由としては、モバイルアプリがモバイルアプリの最小バージョンを満たしていないことや、サポートされていないプラットフォームからの参加などが挙げられます。詳細については、エンドユーザーの要件をご覧ください。 |
CONNECTIONS_EXHAUSTED |
会議に接続できる Meet Media API クライアントは一度に 1 つのみです。アプリが クラッシュした場合、再接続しようとするとこのエラーが表示されることがあります。この場合は、Meet が以前の接続をタイムアウトするまで 30 秒ほど待ちます。その後、もう一度お試しください。 |
CONSENTER_ABSENT |
会議に適切な同意者がいません。個人所有の 会議の場合は、開始者が会議に参加していることを確認してください。Workspace オーナーの会議の場合は、会議を所有する組織のメンバーが少なくとも 1 人必要です。詳細については、同意者の要件をご覧ください。 |
DISABLED_BY_ADMIN |
管理者が組織に対して Meet Media API を無効にしました。この場合、会議の開催中に変更することはできません。詳細については、Meet Media API のライフサイクルの図 3 をご覧ください。 |
DISABLED_BY_HOST_CONTROL |
主催者が会議に対して Meet Media API を無効にしました。アプリは参加できないため、 エンドユーザーにその旨を伝えることができます。 詳細については、Meet Media API のライフサイクルの図 5 をご覧ください。 |
DISABLED_DUE_TO_WATERMARKING |
透かしが有効になっている場合、Meet Media API は会議に参加できません。エンドユーザーにその旨を伝えることができます。 詳細については、Meet Media API のライフサイクルの図 2 をご覧ください。 |
DISABLED_DUE_TO_ENCRYPTION |
暗号化が有効になっている場合、Meet Media API は会議に参加できません。Meet の通話中に変更することはできません。エンドユーザーにその旨を伝えることができます。 詳細については、Meet Media API のライフサイクルの図 2 をご覧ください。 |
統合プラン
データチャネルが開かず、音声や動画を受信しない場合は、ローカル ピア接続の構成時に 統合プランのみが使用されていることを確認してください。
メディア記述の順序エラー
セッション記述プロトコル(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 オファーのすべての
メディア記述に対して a=setup:< > 属性が正しく設定されていない場合に発生します。
このエラーを修正するには、SDP オファーの各メディア記述に次のいずれかの必須属性があることを確認してください。
a=setup:actpassa=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 ブラウザでウェブ クライアントを使用している場合:
- 新しいタブを開き、アドレスバーに「
chrome://webrtc-internals」と入力します。 - [
Stats graph for inbound-rtp] というラベルの付いたセクションに移動します。 - 各音声グラフを調べて、パケットが受信されているかどうかを確認します。
C++ リファレンス クライアントを使用している場合は、
OnAudioFrame
が呼び出されるかどうかを確認します。
OAuth スコープを確認する
音声は、最初の接続リクエストで適切なスコープが指定されている場合にのみ送信されます。エラーを解決するには、正しい OAuth 2.0 スコープを指定してください。詳細については、Meet Media API スコープをご覧ください。
会議が正しく設定されていることを確認する
クライアントが Google Meet サーバーに接続しても、会議に自動的に参加できるわけではありません。セッション管理データチャネルで、状態が
STATE_JOINEDのセッション管理リソースの更新を受信していることを確認してください。{"sessionStatus":{"connectionState":"STATE_JOINED"}}音声ストリームがミュートされていない会議 参加者が他にいることを確認します。
音声のシグナルを確認する
Meet は、SDP オファーでシグナルを送信した場合にのみ音声を提供します。オファーには、受信専用の音声メディア記述が 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 サーバーが有効なオファーを受信すると、送信専用の音声メディア記述が 3 つ含まれた SDP アンサーで応答します。
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 ブラウザでウェブ クライアントを使用している場合:
- 新しいタブを開き、アドレスバーに「
chrome://webrtc-internals」と入力します。 - [
Stats graph for inbound-rtp] というラベルの付いたセクションに移動します。 - 各動画グラフを調べて、パケットが受信されているかどうかを確認します。
C++ リファレンス クライアントを使用している場合は、
OnVideoFrame
が呼び出されるかどうかを確認します。
OAuth スコープを確認する
動画は、最初の接続リクエストで適切なスコープが指定されている場合にのみ送信されます。エラーを解決するには、正しい OAuth 2.0 スコープを指定してください。詳細については、Meet Media API スコープをご覧ください。
会議が正しく設定されていることを確認する
クライアントが Meet サーバーに接続しても、会議に自動的に参加できるわけではありません。セッション管理データチャネルで、状態が
STATE_JOINEDのセッション管理リソースの更新を受信していることを確認してください。{"sessionStatus":{"connectionState":"STATE_JOINED"}}動画 ストリームがミュートされていない会議 参加者が他にいることを確認します。
動画のシグナルを確認する
Meet は、SDP オファーでシグナルが送信された場合にのみ動画を提供します。オファーには、受信専用の動画メディア記述が 3 つまで必要です。
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 オファーに
m=video …が存在することを確認します。 a=recvonlyがすべてのm=video行の属性であることを確認します。- SDP アンサーに同じ数の
m=video行が存在することを確認します。 - SDP アンサーのすべての
m=video行にa=sendonlyまたはa=sendrecvが属性として含まれていることを確認します。 - Meet サーバーに
VideoAssignmentRequestが正常に送信され、受信されたことを確認します。成功または失敗は、同じデータチャネルを介してクライアントに通知する必要があります。
想定よりも動画ストリームが少ない場合のトラブルシューティング
- SDP オファーに正しい数の
m=video …行が含まれていることを確認します。 - SDP アンサーのすべての
m=video記述にa=sendonlyまたはa=sendrecv属性が含まれていることを確認します。アンサーでa=recvonlyとマークされた行があると、クライアントに送信されるストリームの量がその分だけ減ります。
オブザーバーの実装を確認する
データ処理を別のスレッドに移動する場合は、動画データのコピーを作成してください。
VideoFrame.frame
は実質的に基盤となるデータへの参照であるため、
OnVideoFrame
の後にアクセスしようとすると、セグメンテーション違反などの未定義の動作が発生します。