このガイドでは、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 |
会議に同意できる参加者がいない。ユーザーが所有する会議の場合は、開始者が会議に参加していることを確認します。ワークスペース オーナーの会議の場合、会議を所有する組織のメンバーが少なくとも 1 人必要です。詳しくは、同意者の要件をご覧ください。 |
DISABLED_BY_ADMIN |
管理者が組織に対して Meet Media API を無効にしています。この場合、会議の開催中は変更できません。詳細については、Meet Media API lifecycle の図 3 をご覧ください。 |
DISABLED_BY_HOST_CONTROL |
主催者が会議で Meet Media API を無効にしています。アプリは参加できません。このことをエンドユーザーに伝える必要があるかもしれません。詳しくは、Meet Media API のライフサイクルの図 5 をご覧ください。 |
DISABLED_DUE_TO_WATERMARKING |
透かしが有効になっている場合、Meet Media API は会議に参加できません。この情報をエンドユーザーに伝えることもできます。詳しくは、Meet Media API lifecycle の図 2 をご覧ください。 |
DISABLED_DUE_TO_ENCRYPTION |
暗号化が有効になっている場合、Meet Media API は会議に参加できません。Meet の通話中にこの設定を変更することはできません。この情報をエンドユーザーに伝えることもできます。詳しくは、Meet Media API lifecycle の図 2 をご覧ください。 |
統合プラン
データチャネルが開かず、音声や動画が受信されない場合は、ローカル ピア接続の構成時に Unified Plan のみが使用されていることを確認してください。
メディアの説明の順序エラー
セッション記述プロトコル(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: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 ブラウザでウェブ クライアントを使用している場合:
- 新しいタブを開き、アドレスバーに「
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
の後にアクセスしようとすると、セグメンテーション違反などの未定義の動作が発生します。