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 会議に適切な同意者がいません。個人所有の 会議の場合は、開始者が会議に参加していることを確認してください。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: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 の後にアクセスしようとすると、セグメンテーション違反などの未定義の動作が発生します。