ストリームの購読 — Web

一旦 セッションに接続, セッション内のストリームを購読することができます。ストリームを購読すると、その動画ストリームがクライアントページに表示され、音声が再生されます。

このトピックには以下のセクションが含まれます:

セッション内でストリームが作成されたタイミングの検出

Session オブジェクトは streamCreated イベントは、セッションに新しいストリーム(自分のストリーム以外)が作成されたときに発生します。ストリームは、クライアントが 出版 ストリームをセッションに送る。セッションの streamCreated イベントは、最初に接続したときに、セッション内の各既存ストリームに対してもディスパッチされます。このイベントはStreamEventによって定義されます。 stream プロパティは、作成されたストリームを表します:

session.on("streamCreated", function (event) {
   console.log("New stream in the session: " + event.stream.streamId);
});
// Replace with a valid token:
session.connect(token);

どのストリームにも加入できる。次のセクションをご覧ください。

ストリームの購読

ストリームを購読するには、ストリームオブジェクトを subscribe メソッドを呼び出します:

session.subscribe(stream, replacementElementId);

について subscribe() メソッドは以下のパラメーターを取る:

  • stream-ストリームオブジェクト。

  • targetElement- (オプション) サブスクライバ・ビデオを置き換える DOM 要素を定義します。

  • properties— (オプション)HTML ページ内の「サブスクライバー」ビューの外観をカスタマイズするための一連のプロパティ(詳細は UIのカスタマイズ) を選択し、音声と動画の購読の有無を選択します(詳細は オーディオとビデオの調整).

  • completionHandler- (オプション) この関数が呼び出されたときに非同期に呼び出される。 subscribe() メソッドが正常に完了するか、失敗するか。もし subscribe() メソッドが失敗すると、完了ハンドラーにエラー・オブジェクトが渡される。このオブジェクトは code そして message プロパティを使用する。

以下のコードは、クライアントが発行したストリーム以外のすべてのストリームを購読します:

session.on("streamCreated", function(event) {
    session.subscribe(event.stream);
});

// Replace with your API key and token:
session.connect(token, function (error) {
    if(error) {
        // failed to connect
    }
});

について insertMode プロパティの properties パラメーターの Session.subscribe() メソッドは、パブリッシャ・オブジェクトがHTML DOMに挿入される方法を指定します。 targetElement パラメータを設定します。このパラメータには、以下のいずれかの値を設定できる:

  • "replace" - サブスクライバ・オブジェクトは、targetElement のコンテンツを置き換えます。これがデフォルトです。
  • "after" - Subscriber オブジェクトは、HTML DOM 内で targetElement の後に挿入される新しい要素です。(サブスクライバと targetElement の両方が同じ親要素を持ちます)。
  • "before" - Subscriber オブジェクトは、HTML DOM 内で targetElement の前に挿入される新しい要素です。(サブスクライバと targetElement の両方が同じ親要素を持ちます)。
  • "append" - サブスクライバ・オブジェクトは、targetElement の子要素として追加される新しい要素です。他の子要素がある場合、Publisher は targetElement の最後の子要素として追加されます。

例えば、次のコードは、新しいサブスクライバー・オブジェクトを subscriberContainer DOM要素:

session.on('streamCreated', function(event) {
  var subscriberProperties = {insertMode: 'append'};
  var subscriber = session.subscribe(event.stream,
    'subscriberContainer',
    subscriberProperties,
    function (error) {
      if (error) {
        console.log(error);
      } else {
        console.log('Subscriber added.');
      }
  });
});

サブスクライバーオブジェクトは element プロパティが設定され、そのプロパティはそれを含む HTML DOM 要素に設定されます。

デフォルトのUIを使用したくない場合は、 Video 加入者用の要素(参照: 本題). 独自のものを使用することもできます Video サブスクライバーの動画を表示するための要素を作成し、その要素のメディアソースとしてサブスクライバーの MediaStream オブジェクトを使用します。 Video 要素(参照: 本題).

ストリームからの配信停止

購読しているストリームの再生を停止するには、Subscriber オブジェクトを unsubscribe() メソッドを呼び出します:

session.unsubscribe(subscriber);

サブスクライバー・オブジェクトは破棄され、ストリーム表示は HTML DOM から削除されます。

ストリームがセッションから離れるタイミングの検出

自分のストリーム以外のストリームがセッションから抜けるとき、Sessionオブジェクトは streamDestroyed イベントを開催する:

session.on("streamDestroyed", function (event) {
  console.log("Stream stopped. Reason: " + event.reason);
});

パブリッシュしたストリームがセッションから離れると、パブリッシャー・オブジェクトは streamDestroyed イベントを開催する:

var publisher = OT.initPublisher();
publisher.on("streamDestroyed", function (event) {
  console.log("Stream stopped. Reason: " + event.reason);
});

について streamDestroyed イベントはStreamEventクラスで定義されています。このイベントには reason プロパティは、ストリームが終了した理由を詳細に記述する。これらの理由には以下が含まれる。 "clientDisconnected", "forceDisconnected", "forceUnpublished"あるいは "networkDisconnected".詳しくは ストリームイベント.

デフォルトでは streamDestroyed イベントがサブスクライブしているストリームに対してディスパッチされると、対応するサブスクライバー・オブジェクト (複数存在する可能性もあります) は破棄され、HTML DOM から削除されます。このデフォルトの動作を防ぐには preventDefault() メソッドを呼び出します:

session.on("streamDestroyed", function (event) {
  event.preventDefault();
  var subscribers = session.getSubscribersForStream(event.stream);
  // Now you can adjust the DOM elements around each
  // subscriber to the stream, and then delete it yourself.
});

に注意してほしい。 getSubscribersForStream() メソッドは、ストリームのすべてのサブスクライバオブジェクトを返します。

サブスクライバを自分で削除する前に、関連する DOM 要素を調整したい場合は、デフォルトの動作を防止して、サブスクライバを保持することができます。メソッドを呼び出して、サブスクライバ・オブジェクト(およびその DOM 要素)を削除できます。 destroy() メソッドを呼び出します。

サブスクライバオブジェクトは destroyed イベントは、オブジェクトが HTML DOM から削除されたときに発生します。このイベントに応答して、削除されたサブスクライバに関連する DOM 要素を調整 (または削除) することができます。

自動再接続

クライアントが購読中のストリームとの接続を切断した場合(たとえば、いずれかのクライアントでネットワーク接続が途絶えた場合など)、そのクライアントはストリームへの再接続を自動的に試みます。ストリームとの接続が切断され、クライアントが再接続を試みると、Subscriber オブジェクトは disconnected イベントを生成する。ストリームが復元されると、サブスクライバ・オブジェクトは connected イベントが発生します。クライアントがストリームをリストアできない場合、サブスクライバ・オブジェクトは destroyed イベントを開催する。

これらのイベントに応答して、アプリケーションは、一時的な切断、再接続、および破壊された状態を示すユーザーインターフェイス通知を(オプションで)表示できる:

subscriber.on(
  disconnected: function() {
    // Display a user interface notification.
  },
  connected: function() {
    // Adjust user interface.
  },
  destroyed: function() {
    // Adjust user interface.
  }
);

契約ストリームのフレームレートを制限する

また、サブスクライバーのビデオストリームのフレームレートを制限することもできます。サブスクライバーのフレームレートを制限するには、 restrictFrameRate() Subscriber オブジェクトのメソッドを呼び出し、 true:

subscriber.restrictFrameRate(true);

パス・イン false また、動画ストリームのフレームレートに制限はありません:

subscriber.restrictFrameRate(false);

フレームレートが制限されている場合、加入者ビデオフレームは1秒間に1回以下しか更新されない。

この機能は、OpenTok Media Router を使用するセッション( メディアモード (ルーティング設定)に設定されている場合を除き、メディアモードがリレー設定になっているセッションでは適用されません。リレー設定のセッションでは、このメソッドを呼び出しても何の効果もありません。

加入者のフレームレートを制限することには、次のような利点がある:

  • CPUの使用率を減らすことができる。
  • アプリが消費するネットワーク帯域幅を削減します。
  • より多くのストリームを同時に購読できる。

加入者のフレームレートを下げても、他のクライアントのビデオのフレームレートには影響しません。

加入者のオーディオがブロックまたはブロック解除された場合の検出

ブラウザによっては、オーディオの再生が自動的にブロックされ click イベントで、加入者のオーディオ再生が開始されます。これらのブラウザには、Safari、Firefox 66+、Chrome 71+が含まれます。

Subscriber オブジェクトは、オーディオの再生がブロックされている場合に、オーディオ再生ボタンを表示します。Subscriber のデフォルトのオーディオ再生ボタンを無効にし、ユーザーがクリックしてオーディオの再生を開始できる独自の UI 要素を表示することができます。詳しくは、 加入者オーディオがブロックされている場合にカスタムUI要素を表示する.

加入者の音声がブロックされると、Subscriber オブジェクトは audioBlocked イベント、そしてそれは audioUnblocked オーディオのブロックが解除された際のイベント:

subscriber.on({
  audioBlocked: function(event) {
   console.log("Subscriber audio is blocked.")
  },
  audioUnblocked: function(event) {
   console.log("Subscriber audio is unblocked.")
  }
});

また、加入者には以下のものが含まれます。 isAudioBlocked() これにより、以下の結果が返されます true 音声が遮断された場合、または false そうでない場合は。

以下のいずれかが発生した場合、加入者オーディオのブロックは解除される:

  • ユーザーは、デフォルトの加入者オーディオ再生アイコンをクリックします。
  • について OT.unblockAudio() このメソッドは、HTML要素が click イベント(デフォルトのオーディオ再生アイコンを無効にしている場合)
  • ローカルクライアントは、カメラやマイクへのアクセス権を取得します(たとえば、 OT.initPublisher()).

詳しくは Firefoxの自動再生に関するMozillaの記事 そして Chromeの自動再生に関するGoogleの記事.

加入者のビデオが無効になっていることを検知する

購読者の動画が無効化されると、Subscriber オブジェクトは videoDisabled イベントを開催する:

subscriber.on("videoDisabled", function(event) {
  // You may want to hide the subscriber video element:
  domElement = document.getElementById(subscriber.id);
  domElement.style["visibility"] = "hidden";

  // You may want to add or adjust other UI.
});

OpenTok Media Router、またはフォールバック機能を有効にしているパブリッシャーが、サブスクライバーの動画を無効にした場合、そのサブスクライバーに関連するユーザーインターフェースを調整する必要がある場合があります。

について reason プロパティの videoDisabled イベントオブジェクトは、ビデオが無効になった理由を定義します。以下の値のいずれかを設定する:

  • "publishVideo" — 出版社は電話をかけて動画の公開を中止した publishVideo(false).

  • "quality" — OpenTok Media Router、あるいはパブリッシングクライアントの場合、 パブリッシャー・オーディオ・フォールバック が有効になっている場合、ストリームの品質変化に基づいて、サブスクライバーへの動画送信が停止されます。OpenTok Media Router のこの機能により、接続状態が悪化した際にサブスクライバーは動画ストリームの受信を停止します(音声ストリームがある場合は、サブスクライバーは引き続きそれを受信します)。 パブリッシャーのオーディオフォールバック機能では、パブリッシャーの接続状態が悪化した際にパブリッシャーがビデオストリームの配信を停止し、それに伴いサブスクライバーがビデオストリームを切断します。

    このイベントを送信する前に、サブスクライバーのストリーム品質、またはフォールバックが有効になっているパブリッシャーのストリーム品質が、ビデオストリームが無効化される恐れがあるほど低いレベルまで低下した場合、サブスクライバーは videoDisableWarning イベントを開催する。

    接続状態が改善して再び動画の再生が可能になった場合、Subscriber オブジェクトは videoEnabled イベントが発生すると、加入者は動画の受信を再開します。

    デフォルトでは、サブスクライバーは、 videoDisabled この理由によるイベントがディスパッチされ、以下の場合にインジケーターが解除されます。 videoDisabled この理由によるイベントがディスパッチされます。このアイコンの表示は、 setStyle() 加入者の方法として、以下を設定し、 videoDisabledDisplayMode プロパティ;あるいは、 Session.subscribe() メソッドで、 style プロパティの properties パラメータが必要だ。

    この機能は、OpenTok Media Router を使用するセッション( メディアモード (「ルーティング」に設定されている場合)、またはフォールバックが有効になっているパブリッシャーとのセッション内。パブリッシャーのフォールバック有効化については、 ドキュメント.

    ストリームを公開する際、ストリームの画質が原因でビデオが無効化されるのを防ぐことができます。設定 audioFallbackEnabled への false での properties オブジェクトが渡される。 OT.initPublisher() メソッド(この機能は非推奨となる予定です)、または subscriber への false での audioFallback として渡されたオブジェクト properties パラメーターの OT.initPublisher() メソッドを使用する。

  • "subscribeToVideo" — 加入者は、電話をかけて動画の購読を開始または停止しました。 subscribeToVideo(false).

  • "codecNotSupported" - コーデックに互換性がないため、ビデオの購読が停止されました。 ビデオコーデック (開発者ガイド)。

加入者は、 videoEnabled イベントを発生させる:

subscriber.on("videoEnabled", function(event) {
  // You may want to display the subscriber video element,
  // if it was hidden:
  domElement = document.getElementById(subscriber.id);
  domElement.style["visibility"] = "visible";

  // You may want to add or adjust other UI.
});

について reason プロパティの videoEnabled event オブジェクトは、動画が有効化された理由を定義します。これは、以下のいずれかの値に設定できます:

  • "publishVideo" — 出版社は、電話をかけて動画の配信を開始した publishVideo(true).

  • "quality" — OpenTok Media Router(フォールバック機能対応のパブリッシャー)は、ストリームの品質変化に応じて、サブスクライバーへの動画送信を再開しました。OpenTok Media Routerのこの機能により、接続状態が悪化した際にサブスクライバーは動画ストリームの受信を中断し、ストリームの品質が改善した場合は動画ストリームの受信を再開します。 パブリッシャーのオーディオフォールバック機能では、パブリッシャーの接続状態が悪化した際にパブリッシャーが動画ストリームの配信を停止し、それに伴ってサブスクライバーが動画ストリームを切断します。

    この機能は、OpenTok Media Router を使用するセッション( メディアモード (ルーティングが有効になっている場合)、またはフォールバックが有効になっているパブリッシャーとのセッションにおいて。

  • "subscribeToVideo" — 加入者は、電話をかけて動画の購読を開始または停止しました。 subscribeToVideo(false).

  • "codecChanged" - 加入者ビデオは、互換性のないコーデックからコーデックを変更した後に有効になりました ( ビデオコーデック (開発者ガイド)。

加入者のストリームの動画サイズが変更されたことを検知する

モバイルデバイスから配信されているストリームが、デバイスの向きが変わったことに伴ってサイズ変更された場合、サブスクライバーの動画のサイズが変更されることがあります。また、動画ソースが画面共有ウィンドウであり、ストリームを配信しているユーザーが、ストリームのソースとなっているウィンドウのサイズを変更した場合にも、同様の現象が発生することがあります。 動画のサイズが変更されると、Subscriber オブジェクトは videoDimensionsChanged イベントを開催する。

以下のコードは、ストリームの動画サイズが変更された際に、サブスクライバーのサイズを変更するものです:

subscriber.on('videoDimensionsChanged', function(event) {
  subscriber.element.style.width = event.newValue.width + 'px';
  subscriber.element.style.height = event.newValue.height + 'px';
  // You may want to adjust other UI.
});

ストリームに関する情報の取得

Streamオブジェクトには、ストリームを定義する以下のプロパティがあります:

  • connection—ストリームを配信している接続に対応する Connection オブジェクト。これは、 connection Session オブジェクトのプロパティを使用して、そのストリームがローカルの Web ページによって配信されているかどうかを確認します。
  • creationTime—ストリームの作成日時を表すタイムスタンプ(数値)。この値はミリ秒単位で計算されます。この値を Date オブジェクトに変換するには、 new Date(stream.creationTime).
  • hasAudio—(ブール値) ストリームに音声があるかどうか。このプロパティは、パブリッシャーが( Publisher.publishAudio()).こうなると セッション オブジェクトは streamPropertyChanged イベントを開催する。
  • hasVideo-論理値) ストリームに動画があるかどうか。
  • initials—(ブール値) ストリームのイニシャル(ストリームのパブリッシャーが作成された際にイニシャルが設定されていた場合) 初期化されました).
  • name—(文字列) ストリームの名前。デフォルトでは、ユーザーがHTML DOM内のサブスクライバーにマウスを合わせると、この名前が表示されます。ただし、UIをカスタマイズして、名前を非表示にしたり、マウスを合わせなくても表示させたりすることができます。
  • videoDimensions—このオブジェクトには2つのプロパティがあります: width そして height.どちらもNumbersだ。その width プロパティはエンコードされたストリームの幅です。 height プロパティは、エンコードされたストリームの高さです。(これらは、ストリームに対応するPublisherオブジェクトとSubscriberオブジェクトの実際の幅とは無関係です)。このプロパティは、iOSデバイスからパブリッシュされたストリームのサイズが変更された場合、デバイスの向きの変更に基づいて変更される可能性があります。
  • videoType—動画の種類:「camera」、「screen」、「custom」、または未定義のいずれかです。「screen」動画は、パブリッシャー側の画面共有を動画ソースとして使用します。「custom」動画は、パブリッシャー側の VideoTrack 要素を動画ソースとして使用します。 videoTypeundefined ストリームが音声のみの場合 ( 音声ガイド).このプロパティは、モバイル機器から公開されるストリームがカメラから画面共有ビデオタイプに変更された場合に変更される可能性があります。詳細については 画面共有 - Web.

について hasAudio, hasVideo, videoDimensionsそして videoType プロパティは変更される場合があります(たとえば、パブリッシャーが動画をオンまたはオフにした場合など)。これが発生すると、 セッション オブジェクトは streamPropertyChanged イベント(参照: StreamPropertyChangedイベント.)

について getStats() Subscriber オブジェクトのこのメソッドは、そのサブスクライバーのストリームに関する情報を提供します。低レベルのピア接続統計情報を取得するには、 Subscriber.getRtcStatsReport() メソッドを呼び出す。このメソッドはプロミスを返す。 RtcStatsReport サブスクライブされたストリームのオブジェクト。

参照 クライアント観測可能性開発者ガイド をご覧ください。

好みのフレームレートと解像度を設定する

を使用するストリームを購読する際は、 スケーラブルビデオ機能, 設定するオプションがあります preferredResolution への "auto" ネットワークとCPUの使用率を最適化するため、レンダリングされるサイズに基づいて加入者の動画解像度を自動的に管理します。上級ユーザーの場合は、加入クライアントがOpenTok Media Routerから受信するストリームについて、希望するフレームレートや解像度を手動で設定することも可能です。これらは以下の設定として指定できます。 preferredFrameRate そして preferredResolution の特性である。 options そこを通り抜けると、 [`Session.subscribe()`](/video/sdk-reference/js/Session.html#subscribe) メソッド。以下の設定を行うことをお勧めします。 preferredResolution への "auto". これに伴い、 "auto" 設定では、OpenTok.js はブラウザ内のサブスクライバーの動画のサイズに基づいて、推奨解像度を選択します。また、ストリームを購読した後に、推奨フレームレートや解像度を設定することもできます(詳細は [`Subscriber.setPreferredFrameRate()`](/opentok/sdks/js/reference/Subscriber.html#setPreferredFrameRate) そして Subscriber.setPreferredResolution()).

注: について "auto" 解像度の設定は、SDKによって作成されたデフォルトの「Subscriber Video」要素を使用する場合にのみ適用されます。 videoElementCreated イベント(参照: 本題).

注: これらの設定は、パブリッシャーがデフォルトのスケーラビリティ・レイヤー・レイアウトを使用していることを前提としています。パブリッシャーがデフォルト以外のターゲット・スケーラビリティ・モードを設定している場合は( 目標スケーラビリティモードの設定)、メディアルーターのレイヤー選択が、要求された解像度やフレームレートと一致しない場合があります。詳しくは 加入者が希望する解像度およびフレームレートとの連動 詳細はこちら。

登録済みの音声および動画にフィルターやエフェクトを適用する

購読中のストリームのオーディオトラックやビデオトラックに、フィルターやエフェクトを適用することができます。詳しくは、 本題.

音声および映像の品質の変化の検出

クライアントでネットワーク接続の品質が低下する期間が生じた場合、それが加入者の通話品質に影響を及ぼす可能性があります。Subscriber オブジェクトは、 qualityScoreChanged 計算された音声および映像のMOSスコアが変化した際のイベント。これらのスコアは、1(最悪)から5(最高)までの整数で報告され、それぞれ「悪い」、「低」、「普通」、「良い」、「優秀」に対応しています。詳細については、「加入者」を参照してください。 クオリティスコア変更 イベントを開催する。

Subscriber オブジェクトは、品質スコアのいずれかが変更された場合にのみ、このイベントをディスパッチします。各 Subscribe は、オーディオ、ビデオ、あるいはその両方のいずれを購読しているかによって、それぞれ独自のオーディオおよびビデオの品質スコアを含むイベントをディスパッチします。

これらの事象が発生した場合、アプリケーションは(オプションで)通話品質の低下を招くネットワーク状況をクライアントに通知することができます:

subscriber.on('qualityScoreChanged', ({qualityScore}) => {
  if (qualityScore.audioQualityScore <= 3){
    // Alert the user that the remote party is experiencing degraded service
  }
  if (qualityScore.videoQualityScore <= 3){
    // Alert the user that the remote party is experiencing degraded service
  }
});

トラブルシューティング

購読時に接続の問題が発生しないようにするには、このセクションのヒントに従ってください。トラブルシューティングに関する一般的な情報については、以下を参照してください。 デバッグ — Web.

エラー処理

購読時のエラー処理は、公開時よりも少し簡単です。購読する方法は1つしかなく、それは Session.subscribe() メソッド――そして、サブスクライブ時に発生するエラーのほとんどは、ネットワークの問題に起因します。これは、例えば、ユーザーが WebRTC 接続を許可しない非常に制限の厳しいネットワーク環境下にある場合(ただし WebSocket 接続は機能していた)などに発生する可能性があります。 サブスクライバーの接続に失敗した場合、サブスクライバー内部で独自のエラーメッセージが表示されるだけです。この表示は見た目があまり良くなく、エンドユーザーにとって有益な情報もほとんど提供されません。このケースについては、ご自身で処理を行い、サブスクリプションに失敗したことと、ネットワーク接続を確認するようユーザーに伝えるメッセージを表示することをお勧めします。これらのエラーの処理方法は以下の通りです:

session.subscribe(event.stream, 'subscriber', {insertMode: 'append'}, function (err) {
  if (err) {
    showMessage('Streaming connection failed. This could be due to a restrictive firewall.');
  }
});

接続性の喪失

サブスクライバーは、接続に成功した後でも接続が切断されることがあります。 多くの場合、これによりセッションの接続も切断されますが、必ずしもそうとは限りません。また、ローカル側で接続が切断されたのではなく、相手側のパブリッシャーの接続が切断された可能性もあります。サブスクライバーの切断には、 streamDestroyed セッション上のイベントで、 reason プロパティを次のように「networkDisconnected」に設定します:

session.on({
  streamDestroyed: function (event) {
    if (event.reason === 'networkDisconnected') {
      event.preventDefault();
      var subscribers = session.getSubscribersForStream(event.stream);
      if (subscribers.length > 0) {
        var subscriber = document.getElementById(subscribers[0].id);
        // Display error message inside the Subscriber
        subscriber.innerHTML = 'Lost connection. This could be due to your internet connection '
          + 'or because the other party lost their connection.';
        event.preventDefault();   // Prevent the Subscriber from being removed
      }
    }
  }
});

セッションサブスクライブの再試行の実装

次のような場合、一時的な購読の失敗が発生することがあります。 session.subscribe() が呼び出された際、基盤となる WebRTC 接続が時間内に確立できない場合、またはネットワークの一時的な障害によって ICE ネゴシエーションが中断された場合。 session.subscribe() 失敗した場合、SDKはコンプリートハンドラのコールバックを通じてエラーを返します。推奨されるアプローチは、試行の間に遅延を設けたアプリケーションレベルのリトライロジックを実装することです。

注: 以下の機能に対するリトライ機能の組み込みサポート session.subscribe() これはSDKのロードマップに含まれています。それがリリースされるまでは、ご自身で実装する必要があります。

購読の失敗がなぜ起こるのか

一時的なサブスクリプションの失敗の最も一般的な根本原因は、以下の通りです:

  • OT_TIMEOUT (コード 1501): サブスクリプションが許可された時間枠(30秒)内に完了しませんでした。これは、パブリッシュ側のタイムアウトに相当するサブスクライブ側のエラーであり、再試行が可能なエラーの中で最も一般的なものです。
  • ICEの交渉決裂(OT_ICE_WORKFLOW_FAILED): WebRTCのピア間接続を確立できませんでした。これは通常、ネットワークの制限や一時的な接続の問題が原因です。
  • ピア接続の確立に失敗しました (OT_CREATE_PEER_CONNECTION_FAILED): WebRTCのピア接続オブジェクトを作成できませんでした。これは、多くの場合、一時的なプラットフォームまたはネットワークの問題が原因です。
  • サブスクリプション手続き中のネットワークの不具合: ICEネゴシエーションやメディアバインディング中にネットワークが一時的に中断すると、ハードエラーが発生することなく、サブスクリプションがタイムアウトすることがあります。

回復可能なエラーと回復不可能なエラー

すべてではない session.subscribe() エラーはすべて同じではありません。再試行を行う前にエラーを正しく分類することが不可欠です。回復不可能なエラーに対して再試行を行うと、時間を浪費するだけでなく、真の障害を見逃す原因にもなりかねません。

注: 必ず error.name プログラムでエラーを特定するためのプロパティ。数値の error.code このプロパティは非推奨です。

回復不可能なエラー — 再試行しないでください

これらのエラーは、厳格な制約、無効な呼び出しコンテキスト、または終端ストリーム状態によるものです。再試行しても解決しません。

error.name 説明 推奨される対応
OT_NOT_CONNECTED session.subscribe() セッションが接続される前に呼び出されました。 確保する session.connect() 登録する前に、正常に完了している必要があります。
OT_DISCONNECTED クライアントがセッションに接続されていないため、操作は失敗しました。 再試行する前に、セッションが再接続されるのを待ってください。
OT_INVALID_PARAMETER に引数として渡された1つ以上のパラメータ session.subscribe() 無効でした(例:nullストリームやターゲット要素など)。 アプリケーションのロジックを修正してください。再試行は行わないでください。
OT_STREAM_DESTROYED そのストリームは、購読される前に削除されてしまいました。 再試行しないでください。このストリームは存在しません。このストリームに対する保留中のサブスクリプション状態をすべて削除してください。
OT_STREAM_NOT_FOUND そのストリームはセッション内で見つかりませんでした。 再試行しないでください。このストリームは利用できなくなりました。
OT_STREAM_LIMIT_EXCEEDED このセッションは、同時ストリームの制限を超えています。 ユーザーに通知してください。ストリームスロットが利用可能になるまで再試行しないでください。
OT_UNABLE_TO_SUBSCRIBE ユーザーが、暗号化シークレットを指定せずに、E2EEが有効なセッションでサブスクリプションを試みたか、予期しないエラーによりサブスクリプションが失敗しました。 E2EEセッションについては、以下を通じて暗号化シークレットが設定されていることを確認してください。 session.setEncryptionSecret() 購読する前に。一般的なケースでは、エラーをログに記録し、ユーザーに通知してください。

回復可能なエラー — 再試行しても問題ありません

これらのエラーは、通常、一時的なネットワークの状態、シグナリングのタイムアウト、またはプラットフォームの一時的な利用不能によって引き起こされます。

error.name 説明 推奨される対応
OT_TIMEOUT (コード 1501) サブスクリプションが妥当な時間内に完了しませんでした。再試行可能なサブスクライブエラーの中で最も一般的なものです。 購読を解除し、バックオフ(最大3回まで)を行ってから再試行してください。
OT_ICE_WORKFLOW_FAILED ICEネゴシエーションに失敗しました — ピア接続を確立できませんでした。制限の厳しいネットワークでは、しばしば一時的な現象として発生します。 配信停止手続きを行った後、再度お試しください。それでも問題が解決しない場合は、ネットワークやファイアウォールの不具合の可能性についてユーザーにお知らせください。
OT_CREATE_PEER_CONNECTION_FAILED WebRTCのピア接続を確立できませんでした。ファイアウォールの制限や、一時的なプラットフォームの問題が考えられます。 登録を解除してから、もう一度試してください。それでも問題が解決しない場合は、ユーザーにネットワーク接続を確認するよう促してください。
OT_SET_REMOTE_DESCRIPTION_FAILED WebRTC接続が、以下の処理中に失敗しました。 setRemoteDescription. 通常、一時的な通信の問題です。 購読を解除してから、バックオフを適用して再試行してください。
OT_MEDIA_ERR_ABORTED / OT_MEDIA_ERR_NETWORK ネットワークエラーにより、メディアの取得が中止または中断されました。 配信停止の手続きを行い、しばらく待ってから再度お試しください。
OT_MEDIA_ERR_DECODE video要素でストリームを再生しようとした際に、デコードエラーが発生しました。 購読を解除し、少し時間を置いてから再度お試しください。それでも問題が解決しない場合は、メディア形式が互換性がない可能性があります。
OT_MEDIA_ERR_SRC_NOT_SUPPORTED このストリームは、再生に適していないと判定されました。 購読を解除してから、もう一度試してみてください。それでも問題が解決しない場合は、購読者の動画要素の設定を確認してください。

重要:再試行する前に必ず登録を解除してください

とは異なり session.publish()、ここではパブリッシャーインスタンスをそのまま再利用できる場合が多く、 session.subscribe() 呼び出す必要があります session.unsubscribe() 再試行する前に、サブスクライバーオブジェクトを破棄する. 失敗したサブスクライバーインスタンスを再利用しようとしても、うまくいきません。

async function subscribeWithRetry(session, stream, targetElement, options, attempt = 1) {
  const MAX_RETRIES = 3;
  const RETRY_DELAY_MS = 3000;

  let subscriber = session.subscribe(stream, targetElement, options);

  const error = await new Promise((resolve) => {
    subscriber.on('subscribeComplete', (err) => resolve(err));
  });

  if (!error) {
    console.log('Subscribed successfully.');
    return subscriber;
  }

  // Always clean up the failed subscriber before retrying
  try { session.unsubscribe(subscriber); } catch (e) { /* ignore */ }

  // Non-recoverable: do not retry
  const nonRetryable = [
    'OT_NOT_CONNECTED',
    'OT_DISCONNECTED',
    'OT_INVALID_PARAMETER',
    'OT_STREAM_DESTROYED',
    'OT_STREAM_NOT_FOUND',
    'OT_STREAM_LIMIT_EXCEEDED',
    'OT_UNABLE_TO_SUBSCRIBE',
  ];

  if (nonRetryable.includes(error.name)) {
    console.error('Non-retryable subscribe error:', error.name);
    handleNonRecoverableError(error);
    return null;
  }

  // Recoverable: retry with backoff
  if (attempt < MAX_RETRIES) {
    console.warn(`Subscribe attempt ${attempt} failed (${error.name}), retrying...`);
    await delay(RETRY_DELAY_MS * attempt);
    return subscribeWithRetry(session, stream, targetElement, options, attempt + 1);
  }

  console.error('All subscribe attempts failed.');
  handleSubscribeFailure(session, stream);
  return null;
}

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function handleNonRecoverableError(error) {
  // Surface a meaningful message to the user based on error.name
}

function handleSubscribeFailure(session, stream) {
  // Inform the user that the stream could not be loaded
}

使用方法:

session.on('streamCreated', (event) => {
  subscribeWithRetry(session, event.stream, document.getElementById('subscriber'), {});
});

タイミングが重要なシナリオ

再試行中にストリームが終了する

リトライが保留中の状態でストリームが破棄された場合、 streamDestroyed セッションイベントが発生します。存在しなくなったストリームを購読してしまうことを避けるため、そのストリームに対して保留中の再試行をすべてキャンセルする必要があります。

const pendingRetries = new Map(); // stream.id → timeout handle

session.on('streamDestroyed', (event) => {
  const pending = pendingRetries.get(event.stream.id);
  if (pending) {
    clearTimeout(pending);
    pendingRetries.delete(event.stream.id);
    console.log(`Cancelled pending retry for destroyed stream: ${event.stream.id}`);
  }
});

サブスクライブの再試行中のセッション再接続

セッションが再接続中の場合(ネットワーク切断後など)、セッションが再接続されるまで再試行を延期してください。セッションが再接続中のときにサブスクライブを試みると、即座に失敗します。

let isSessionReconnecting = false;

session.on('sessionReconnecting', () => { isSessionReconnecting = true; });
session.on('sessionReconnected', () => {
  isSessionReconnecting = false;
  // Re-trigger any deferred subscriptions here
});

// In your retry logic, check before retrying:
if (isSessionReconnecting) {
  // Defer — wait for sessionReconnected before retrying
  return;
}

やってはいけないこと

  • を行う。 違う 失敗したサブスクライバーインスタンスを再利用する — 常に session.unsubscribe() そして、再試行時に新しいサブスクリプションを作成します。
  • を行う。 違う 再試行する OT_STREAM_DESTROYED または OT_STREAM_NOT_FOUND — ストリームが失われており、再試行しても常に失敗します。
  • を行う。 違う 再試行する OT_STREAM_LIMIT_EXCEEDED — これはセッションレベルの容量制限であり、一時的なエラーではありません。
  • を行う。 違う 無制限に再試行する — 試行回数は3回までとし、すべて失敗した場合はユーザーに通知する。
  • を行う。 違う セッションの再接続中に再試行する — 以下の時点まで延期する sessionReconnected 火災。

推奨パラメータの概要

パラメータ 推奨値 備考
最大再試行回数 3 以下に準じて session.publish() 再試行の手順
再試行の遅延時間 3秒 × 試行回数(3秒、6秒、9秒) 公開の再試行よりもわずかに長い — サブスクリプションのタイムアウトは30秒です
すべての再試行で失敗する ユーザーに通知する ストリームを黙って破棄しないようにしてください
再試行不可能なエラー OT_STREAM_DESTROYED, OT_STREAM_NOT_FOUND, OT_STREAM_LIMIT_EXCEEDED これらについては、早めに失敗しよう
加入者の整理 いつも session.unsubscribe() 再試行の前に 必須 — パブリッシャーとは異なり、サブスクライバーインスタンスは再利用できません