Meet Media API エラーのトラブルシューティングと修正

このガイドでは、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 ブラウザでウェブ クライアントを使用している場合:

  1. 新しいタブを開き、アドレスバーに「chrome://webrtc-internals」と入力します。
  2. Stats graph for inbound-rtp というラベルの付いたセクションに移動します。
  3. 各音声グラフを調べて、パケットが受信されているかどうかを確認します。

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 ブラウザでウェブ クライアントを使用している場合:

  1. 新しいタブを開き、アドレスバーに「chrome://webrtc-internals」と入力します。
  2. Stats graph for inbound-rtp というラベルの付いたセクションに移動します。
  3. 各動画のグラフを調べて、パケットが受信されているかどうかを確認します。

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 の後にアクセスしようとすると、セグメンテーション違反などの未定義の動作が発生します。