ストリームの公開 — Web

一旦 セッションに接続この場合、セッションに接続している他のクライアントが閲覧できるストリームを公開することができる。

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

クライアントに公開機能があるかどうかを確認する

セッションに接続したら、クライアントが公開できるかどうかを確認できます。の値を確認してください。 capabilities.publish プロパティの Session オブジェクトを公開することができます。これが1に設定されている場合、クライアントはパブリッシュできる:

if (session.capabilities.publish == 1) {
    // The client can publish. See the next section.
} else {
    // The client cannot publish.
    // You may want to notify the user.
}

パブリッシュするには、クライアントはパブリッシュをサポートするロールが割り当てられたトークンでセッションに接続する必要があります。また、カメラとマイクが接続されている必要があります。また、クライアントの環境がパブリッシングをサポートしている必要があります ( ブラウザサポート).

また、公開はHTTPSページでのみサポートされています。

パブリッシャーの初期化

について OT.initPublisher() メソッドは、Publisher オブジェクトを初期化して返します。Publisher オブジェクトは、公開する動画のビューを表します:

var publisher;
var targetElement = 'publisherContainer';

publisher = OT.initPublisher(targetElement, null, function(error) {
  if (error) {
    // The client cannot publish.
    // You may want to notify the user.
  } else {
    console.log('Publisher initialized.');
  }
});

について OT.initPublisher() メソッドは3つのパラメーターを取る:

  • targetElement- オプション)パブリッシャの動画が置き換わる DOM 要素を定義します。

  • properties- オプション)パブリッシャをカスタマイズするプロパティのセット。パブリッシャの properties このパラメータには、パブリッシャーが使用するオーディオおよびビデオ入力デバイスを指定するためのオプションも含まれています(参照: パブリッシャーが使用するカメラとマイクの設定).その properties このパラメータには、HTML ページでのビューの外観をカスタマイズするためのオプションも含まれています(参照: UIのカスタマイズを参照)、オーディオとビデオを公開するかどうかを選択します。 オーディオまたはビデオのみの公開). その他のパブリッシャーのオプションについては、 properties パラメーターの OT.initPublisher() メソッドを使用する。

  • completionHandler- (オプション) パブリッシャーが正常にインスタンス化されたか、エラーになったかを指定する 完了ハンドラ。

このパブリッシャー・オブジェクトを Session.publish() ストリームをセッションに公開する方法。詳しくは ストリームの公開.

電話する前に Session.publish()このPublisherオブジェクトを使用して、Publisherに接続されたマイクとカメラをテストできます。

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

  • "replace" - Publisherオブジェクトは、targetElementのコンテンツを置換します。これは既定です。
  • "after" - Publisherオブジェクトは、HTML DOMのtargetElementの後に挿入される新しい要素です。(PublisherとtargetElementはどちらも同じ親要素を持ちます)。
  • "before" - Publisherオブジェクトは、HTML DOMのtargetElementの前に挿入される新しい要素です。(PublisherとtargetElementはどちらも同じ親要素を持ちます)。
  • "append" - Publisherオブジェクトは、targetElementの子要素として追加される新しい要素です。他の子要素がある場合、Publisher は targetElement の最後の子要素として追加されます。

例えば、次のコードは、新しいPublisherオブジェクトを publisherContainer DOM要素:

// Try setting insertMode to other values: "replace", "after", or "before":
var publisherProperties = {insertMode: "append"};
var publisher = OT.initPublisher('publisherContainer', publisherProperties, function (error) {
  if (error) {
    console.log(error);
  } else {
    console.log("Publisher initialized.");
  }
});

クライアントがカメラおよびマイクへのアクセスを許可したかどうかを検知する

Publisher オブジェクトがクライアントのカメラやマイクにアクセスするには、ユーザーがそれらのアクセス権を許可する必要があります。ユーザーがカメラやマイクへのアクセスを許可または拒否すると、Publisher オブジェクトはイベントをディスパッチします。

publisher.on({
  accessAllowed: function (event) {
    // The user has granted access to the camera and mic.
  },
  accessDenied: function accessDeniedHandler(event) {
    // The user has denied access to the camera and mic.
  }
});

また、ユーザーにカメラやマイクへのアクセスを許可するか拒否するかという選択肢が表示された際、Publisher オブジェクトはイベントをディスパッチします:

publisher.on({
  accessDialogOpened: function (event) {
    // The Allow/Deny dialog box is opened.
  },
  accessDialogClosed, function (event) {
    // The Allow/Deny dialog box is closed.
  }
});

出版社には accessAllowed プロパティ。これは、クライアントが(true) あるいは(false) カメラとマイクへのアクセス権を許可しました。

パブリッシャーが使用するカメラとマイクの設定

パブリッシャーが使用する音声と映像の入力デバイスを(オプションで)指定できます。あなたが OT.initPublisher() メソッドを呼び出すと、(オプションで) audioSource そして videoSource の特性である。 properties オブジェクトが渡される。 OT.initPublisher() メソッドを使用する。

まず OT.getDevices() メソッドで利用可能なデバイスを列挙します。デバイスの配列は devices パラメーターの callback 関数に渡される。 OT.getDevices() メソッドを使用します。例えば、次のコードはオーディオとビデオ入力デバイスのリストを取得します:

var audioInputDevices;
var videoInputDevices;
OT.getDevices(function(error, devices) {
  audioInputDevices = devices.filter(function(element) {
    return element.kind == "audioInput";
  });
  videoInputDevices = devices.filter(function(element) {
    return element.kind == "videoInput";
  });
  for (var i = 0; i < audioInputDevices.length; i++) {
    console.log("audio input device: ", audioInputDevices[i].deviceId);
  }
  for (i = 0; i < videoInputDevices.length; i++) {
    console.log("video input device: ", videoInputDevices[i].deviceId);
  }
});

によってリストアップされた各デバイスは OT.getDevices() には一意のデバイスIDがあります。 deviceId プロパティを使用します。これらのデバイスID値を audioSource そして videoSource の特性である。 properties オブジェクトに渡される OT.initPublisher():

var pubOptions =
  {
    audioSource: audioInputDevices[0].deviceId,
    videoSource: videoInputDevices[0].deviceId
  };
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("OT.initPublisher error: ", error);
});

を設定する。 videoSource プロパティ null または false 音声のみのセッションで ( 音声セッションでの発表).

について OpenTok ハードウェア設定コンポーネント は、クライアントが使用するカメラとマイクを選択するためのユーザーインターフェースを提供します。これは OT.getDevices() メソッドを使用する。

画面共有ストリーム(ソースがカメラではなくクライアントの画面であるストリーム)を公開することもできます。詳しくは 画面共有.

また、次のこともできる。 パブリッシャーが使用するカメラを変更する、または、それを 前面カメラまたは背面カメラ (このオプションが利用可能な場合)。

また、次のこともできる。 パブリッシャーが使用するオーディオソースを変更する.

前面カメラまたは背面カメラの使用

パブリッシャーを初期化する際、 facingMode に渡しするオプションオブジェクトのプロパティ OT.initPublisher(). たとえば、このプロパティを次のように設定できます。 "user" (前面カメラ)または "environment" (背面カメラ)、クライアントのシステムでこのオプションが利用可能な場合。(通常、これらのオプションはモバイル端末でのみ利用可能です。)

を設定した場合 facingMode オプション、do 違う を設定する。 videoSource 財産である。

カメラとマイクの選択を記憶する

HTTP経由で読み込まれるページのセキュリティを確保するため、すべてのブラウザでは、ストリームの配信に使用するカメラやマイクを選択するよう、常にユーザーに確認を求めます。

ChromeでHTTPS経由で読み込まれたページでは、ユーザーのカメラおよびマイクの選択設定が記憶され、同じHTTPSドメインから読み込まれるページに再度アクセスした際に、その設定が再利用されます。

FirefoxでHTTPS経由で読み込まれたページでは、ユーザーがデバイスを選択する際に、カメラとマイクを記憶しておく(同じHTTPSドメインから読み込まれるページに次回アクセスした際)というオプションが利用可能です。

IEでHTTPS経由で読み込まれたページでは、同じHTTPSドメインに対する過去の利用履歴(もしあれば)に基づいて、ユーザーが以前選択したカメラやマイクを設定することで、 usePreviousDeviceSelection プロパティ true に渡すオプションに OT.initPublisher() メソッドを使用する:

var pubOptions = {usePreviousDeviceSelection: true};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("OT.initPublisher error: ", error);
});

IEで使用するカメラとマイクをユーザーに選択させる(以前のデバイス選択を無視する)には、次のようにします。 違う を設定する。 usePreviousDevices プロパティは OT.initPublisher() メソッド(または falseデフォルト)。

デフォルトのオーディオ入力デバイス管理を無効にする

デフォルトでは、新しいオーディオ入力デバイスが接続されると、SDKが自動的にその切り替えを処理します。ただし、現在使用中のマイクをそのまま選択し続けたいエンドユーザーにとっては、この動作が望ましくない場合もあります。

SDKの上級ユーザーであれば、オーディオ入力デバイスの自動管理を無効にすることができます。これを行うには、 disableAudioInputDeviceManagement プロパティを OT.initPublisher() メソッドを使用する:

var pubOptions = {disableAudioInputDeviceManagement: true};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("Publishing a stream");
});

注: これは高度な機能です。これを有効にすると、SDKで使用されるオーディオ入力デバイスは にはなりません。 エンドユーザーがマイクを変更した際に更新される。

ストリームの公開

Publisher オブジェクトを作成したら(参照: パブリッシャーの初期化)、それを publish() メソッドを呼び出して、ストリームをセッションに公開します:

    publisher = OT.initPublisher('replacementElementId');
    session.publish(publisher, function(error) {
      if (error) {
        console.log(error);
      } else {
        console.log('Publishing a stream.');
      }
    });

2番目のパラメーターは完了ハンドラー関数で、発行に失敗した場合はエラーオブジェクトが渡される。そうでない場合は、エラーは渡されずに完了ハンドラ関数が呼び出されます。

このコードでは session がSessionオブジェクトであること、そしてクライアントがそのセッションに接続していること。詳細は セッションへの参加.

Publish オブジェクトは streamCreated イベントが発生する:

var publisher = OT.initPublisher();
session.publish(publisher, function(error) {
  if (error) {
    console.log(error);
  } else {
    console.log('Publishing a stream.');
  }
});
publisher.on('streamCreated', function (event) {
    console.log('The publisher started streaming.');
});

パブリッシャ・オブジェクトは element プロパティが設定され、そのプロパティはそれを含む HTML DOM 要素に設定されます。

パブリッシャーによるセッションへのストリーミングを停止する

以下の関数を呼び出すことで、パブリッシャーによるセッションへのストリーミングを停止できます。 unpublish() メソッドを呼び出します:

    session.unpublish(publisher);

なお、(公開を継続したまま)動画または音声の配信を個別に停止することができます。詳細については、以下を参照してください。 オーディオとビデオの調整.

公開されたストリームがセッションから離れるときの検出

をディスパッチします。 streamDestroyed イベントが発生する:

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

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

デフォルトでは、パブリッシャーが streamDestroyed イベントを呼び出すと、パブリッシャは破棄され、HTML DOM から削除されます。このデフォルトの動作を防ぐには preventDefault() メソッドを呼び出します:

publisher.on("streamDestroyed", function (event) {
    event.preventDefault();
    console.log("The publisher stopped streaming.");
});

パブリッシャ・オブジェクトを再利用してセッションに再度パブリッシュする場合は、デフォルトの動作を防止してパブリッシャを保持します。

また、パブリッシャーは destroyed イベントが発生します。このイベントに応答して、削除されたパブリッシャーに関連する DOM 要素を調整 (または削除) することができます。

ストリームのビデオ解像度を設定する

公開ストリームの推奨ビデオ解像度を設定するには、次のように設定します。 resolution プロパティの properties パラメータに渡す OT.initPublisher() メソッドを使用する:

var publisherProperties = {resolution: '1280x720'};
var publisher = OT.initPublisher(targetElement,
                                 publisherProperties);
publisher.on('streamCreated', function(event) {
   console.log('Stream resolution: ' +
     event.stream.videoDimensions.width +
     'x' + event.stream.videoDimensions.height);
});

これは resolution プロパティは文字列で、ビデオの解像度を指定します。文字列の形式は "_width_x_height_"ここで、幅と高さはピクセルで表されます。有効な値は "1920x1080", "1280x720", "640x480"そして "320x240".

要求されたビデオストリームの解像度は、 videoDimensions.width そして videoDimensions.height Stream オブジェクトのプロパティ。

ストリームのデフォルトの解像度(解像度を指定しない場合)は、640x480ピクセルです。クライアントシステムが要求した解像度をサポートできない場合、ストリームは次にサポートされる最大の設定を使用します。

について videoHeight() そして videoWidth() メソッドは、パブリッシャ・オブジェクトの構成された解像度を返します。サブスクライバのビデオ・ストリームの実際の解像度は videoWidth() そして videoHeight() メソッドの値と異なる場合があります。の値とは異なる場合があります。 resolution として渡されたプロパティ properties プロパティの OT.initPublisher() リクエストされた解像度に対応していないブラウザで公開する場合、このメソッドを使用します。

注: 参照 1080pデベロッパーガイド 1080p解像度を使用する際の注意事項については、こちらをご覧ください。

ストリームのフレームレートを設定する

公開ストリームの推奨フレームレートを設定するには frameRate プロパティの properties パラメータに渡す OT.initPublisher() メソッドを使用する:

var publisherProperties = {frameRate: 7};
var publisher = OT.initPublisher(targetElement,
                                 publisherProperties);
publisher.on('streamCreated', function(event) {
   console.log('Frame rate: ' + event.stream.frameRate);
});

この値を、動画の希望するフレームレート(1秒あたりのフレーム数)に設定してください。有効な値は、30、15、7、1です。

パブリッシャーがフレームレートを指定した場合、ビデオストリームの実際のフレームレートは frameRate ただし、実際のフレームレートは、ネットワークやシステムの状況に応じて変化します。を呼び出すときにフレームレートを指定しない場合は、フレームレートを指定する必要があります。 OT.initPublisherこのプロパティは未定義である。

OpenTok Media Router を使用するセッション( メディアモード (ルーティング設定に設定されている場合)、フレームレートを比例的に下げることで、ストリームが使用できる最大帯域幅も比例して減少します。ただし、セッションでは メディアモード を relayed に設定すると、フレームレートを下げてもストリームの帯域幅は減らない。

また、サブスクライバーのビデオストリームのフレームレートを制限することもできます。詳細については、以下を参照してください。 契約ストリームのフレームレートを制限する.

ストリームの最大ビットレートの設定

公開されたストリームの最大ビットレートを設定できます。最大ビットレートを設定することで、従量制の接続から接続しているユーザーの場合、帯域幅の消費を抑えることができます。詳しくは、 本書.

パブリッシャーの削除

パブリッシャを削除するには destroy() メソッドを使用する:

    publisher.destroy();

を呼び出す。 destroy() このメソッドは、Publisher オブジェクトを削除し、HTML DOM から取り除きます。

パブリッシャーのストリームに関する統計情報の取得

について Publisher.getStats() このメソッドは、パブリッシャーの現在のオーディオ・ビデオ統計情報を定義するオブジェクトの配列を返します。ルーティングされたセッション( OpenTok メディアルーター)、この配列には1つのオブジェクトが含まれており、OpenTok Media Routerに送信される単一のオーディオ・ビデオストリームの統計情報を定義しています。中継セッションでは、この配列には、公開されたストリームの各加入者に対応するオブジェクトが含まれます。

詳細な低レベルのピア接続統計情報を取得するには、 Publisher.getRtcStatsReport() メソッド。これはプロミスを返し、成功した場合は、以下の配列で解決されます。 RtcStatsReport オブジェクトがある。

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

パブリッシャーのストリームをテストする

テストストリームを公開し、そのオーディオとビデオの統計情報を確認することで、接続でサポートされるストリームのタイプ(高解像度やオーディオのみなど)を判断できます。

ローカルクライアントによって配信されているストリームの統計情報を取得するには、OpenTok Media Router を使用するセッションを使用する必要があります( メディアモード (「ルーティング済み」に設定)、そして testNetwork プロパティ true での options オブジェクトに渡します。 Session.subscribe() メソッドを使用します。その後 getStats() Subscriber オブジェクトのメソッドを使用して、公開しているストリームのオーディオおよびビデオの統計情報を取得します。詳しくは、 本題 をご覧ください。

について opentok-ネットワークテスト レポには、セッションに公開する前にテストストリームの統計情報を使用する方法を示すサンプルコードが含まれています。

カメラや画面以外の動画ソースからの動画の公開

パブリッシャーの動画ソースとして、動画を設定できます MediaStreamTrack オブジェクト。これにより、次のような操作が可能になります:

  • HTMLのCanvas要素を動画として使用して、動画を公開します。 次の関数を呼び出すことができます。 captureStream() のメソッドを使用する。 HTMLCanvasElement オブジェクトを呼び出し、 getVideoTracks() 結果の CanvasCaptureMediaStream video MediaStreamTrack オブジェクトを取得するためのオブジェクト。基本的な例については、「Publish-Canvas」サンプルを参照してください。 opentok-web-samples repo をGitHubで公開している。

  • 「Video」要素から動画を公開します。 に電話してください captureStream() 〜の方法 HTMLVideoElement MediaStream オブジェクトを取得するためのオブジェクト。この getVideoTracks() MediaStream オブジェクトのこのメソッドは、オーディオ MediaStreamTrack オブジェクトの配列(通常は 1 つだけ)を返します。その後、この MediaStreamTrack オブジェクトを audioSource プロパティの options オブジェクトに渡します。 OT.initPublisher() メソッド。基本的な例については、「Publish-Video」サンプルを参照してください。 opentok-web-samples repo をGitHubで公開している。

ビデオ MediaStreamTrack オブジェクトを videoSource プロパティの options オブジェクトに渡します。 OT.initPublisher() メソッドを使用します。これにより、MediaStreamTrack オブジェクトで表される動画が、公開ストリームの動画ソースとなります。

マイク以外の音声ソースからの音声を出力する

パブリッシャーのオーディオソースをオーディオに設定できます MediaStreamTrack オブジェクト。これにより、次のような操作が可能になります:

  • 「Audio」または「Video」要素からオーディオを出力します。 に電話してください captureStream() 〜の方法 HTMLAudioElement オブジェクト、または HTMLVideoElement MediaStream オブジェクトを取得するためのオブジェクト。この getAudioTracks() MediaStream オブジェクトのこのメソッドは、オーディオ MediaStreamTrack オブジェクトの配列(通常は 1 つだけ)を返します。その後、この MediaStreamTrack オブジェクトを audioSource プロパティの options オブジェクトに渡します。 OT.initPublisher() メソッドを使用する。
  • オーディオの MediaStreamTrack オブジェクトからオーディオを出力します。 たとえば、次のように使用できます。 オーディオコンテキスト オブジェクトと Web Audio API オーディオを動的に生成します。その後、以下を呼び出すことができます。 createMediaStreamDestination().stream.getAudioTracks()[0] AudioContextオブジェクトで、オーディオMediaStreamTrackオブジェクトを取得する。 audioSource プロパティの options オブジェクトに渡します。 OT.initPublisher() メソッド。基本的な例については、「Stereo-Audio」サンプルを参照してください。 opentok-web-samples repo をGitHubで公開している。

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

公開されたストリームのソース音声または動画として使用されるマイクやカメラから取得した音声や動画に対して、背景の置き換えや背景のぼかしなどのフィルターやエフェクトを適用できます。詳しくは、 本題.

特定の状況下でビデオのパフォーマンスを向上させるビデオコンテンツのヒント設定

動画コンテンツのヒントを設定して、公開動画の品質とパフォーマンスを向上させることができます。これは特定の状況で役立ちます:

  • 主にテキストまたはビデオコンテンツを含むスクリーン共有ビデオを公開する場合。
  • カメラの映像ソースを使用する場合、フレームレートを下げつつ解像度を維持したいときは、コンテンツヒントを「text」または「detail」に設定できます。ルーティングされたセッションにおいて、パブリッシャーが スケーラブルビデオ, フル解像度で低フレームレートのストリームを送信し、ネットワーク状況が許せば、フル解像度で通常のフレームレートのストリームも送信します。OpenTok Media Router は、これらのストリームのうちいずれか1つを加入者に転送します。

これは、指定したコンテンツの種類により適したエンコーディングや処理方法を使用するよう、ブラウザに指示するものです。

ストリームの初期ビデオコンテンツヒントを設定する。 videoContentHint に渡すオプションの OT.initPublisher() メソッドを使用する:

var publisherOptions = {
  videoContentHint: "text",
  // other options, such as videoSource: "screen"
};
var publisher = OT.initPublisher(targetElement, publisherOptions, callbackFunction);

を呼び出すことで、動画コンテンツのヒントを動的に変更できます。 setVideoContentHint() メソッドを呼び出します:

publisher.setVideoContentHint("motion");

ビデオコンテンツヒントは、以下の値のいずれかに設定できます:

  • "" - ヒントは提供されません(デフォルト)。パブリッシング・クライアントは、動画コンテンツをどのように扱うべきか、最善の推測を行います。
  • "motion" - トラックは、動きが重要なビデオを含んでいるかのように扱われるべきである。たとえば、ビデオを含む画面共有ビデオストリームにこの設定を使用することができます。
  • "detail" - トラックは、ビデオの詳細が特別に重要であるかのように扱われるべきである。たとえば、テキストコンテンツ、絵画、線画を含む画面共有ビデオストリームにこの設定を使用することができます。
  • "text" - トラックは、テキストの詳細が特別に重要であるかのように扱われるべきである。たとえば、テキストコンテンツを含む画面共有ビデオストリームにこの設定を使用することができます。

テキスト」と「詳細」のコンテンツヒントでは、ブラウザはビデオのフレームレートを下げる必要があっても、高解像度を維持しようとします。モーション」コンテンツヒントでは、ブラウザはフレームレートが失速するのを防ぐために解像度を下げます。

これらのオプションの詳細については、 W3C ワーキングドラフト.

Chrome 60 以降、Safari 12.1 以降、Edge 79 以降、Opera 47 以降、Samsung Internet の最新バージョン、Android 70 以降の WebView、および iOS 12.2 以降の WebView は、動画コンテンツのヒントに対応しています。その他のブラウザでは、この設定は無視されます。

フレームレートが低くなっても構わないというのであれば、以下の選択肢も検討してみてはいかがでしょうか。 購読中のストリームのフレームレートを制限する 品質を向上させるため。

オーディオの代替再生先(パブリッシャー)

詳細については、開発者ガイドをご覧ください。 オーディオフォールバック . パブリッシャーのオーディオフォールバック機能は、帯域幅と品質の監視機能を強化し、通信の品質向上を図ります。

その他のオーディオ・ビデオ・オプション

詳細については、開発者ガイドをご覧ください。 オーディオとビデオの調整.

出版時のベストプラクティス

このセクションでは、ストリームをうまく公開するためのヒントを紹介します。

デバイスへのアクセスを許可する

ユーザーに対して、カメラやマイクへのアクセスを許可するよう求められることを事前に伝えておくことがベストプラクティスです。公開に失敗するケースの圧倒的多数は、ユーザーが「拒否」ボタンをクリックしたり、「許可」ボタンをまったくクリックしなかったりすることが原因であることがわかっています。 このプロセスをユーザーに案内するために必要なすべてのイベントを、当社では提供しています:

publisher.on({
  accessDialogOpened: function (event) {
    // Show allow camera message
    pleaseAllowCamera.style.display = 'block';
  },
  accessDialogClosed: function (event) {
    // Hide allow camera message
    pleaseAllowCamera.style.display = 'none';
  }
});

また、ウェブサイトをSSLで提供するのも良いアイデアです。なぜなら、Chromeでは、SSLで提供されるドメインであれば、ユーザーがデバイスへのアクセスを許可するかどうかをクリックする必要があるのは、ドメインごとに1回だけだからです。つまり、(Chromeを使用している場合)ユーザーは、ページを読み込むたびに不便な許可/拒否ダイアログボックスに対処する必要がないのです。

OT.initPublisher()とSession.publish()を分割する。

もうひとつお勧めするのは OT.initPublisher() そして Session.publish() ステップを実行します。これは、ユーザーが許可ボタンをクリックするのを待っている間にセッションに接続するため、最初の接続時間を短縮します。ですから、代わりに

session.connect(token, function (err) {
{... your error handling code ...}
if (!err) {
    var publisher = OT.initPublisher();
    session.publish(publisher);
  }
});

を動かす。 OT.initPublisher() のように、接続する前にステップを踏む:

var publisher = OT.initPublisher();
session.connect(token, function (err) {
{... your error handling code ...}
  if (!err) {
    session.publish(publisher);
  }
});

解像度とフレームレート

パブリッシャーの解像度とフレーム・レートは、初期化時に設定できます:

OT.initPublisher(divId, {
  resolution: '320x240',
  frameRate: 15
});

デフォルトではPublisherの解像度は640x480ですが、1920x1080、1280x720、320x240に設定することもできます。解像度をビデオが表示されるサイズに合わせることをお勧めします。320x240ピクセルでしかビデオを表示しないのであれば、1280x720や1920x1080でストリーミングする意味はありません。解像度を下げることで、帯域幅を節約し、輻輳や接続の切断を減らすことができます。

デフォルトでは、ビデオのフレームレートは毎秒30フレームですが、15、7、1にも設定できます。フレームレートを下げると、必要な帯域幅を減らすことができます。解像度が低い動画は、フレームレートを低くしても、ユーザーにはそれほど違いが感じられません。そのため、低解像度を使用する場合は、低フレームレートの使用も検討するとよいでしょう。

詳細については、以下のドキュメントを参照してください。 OT.initPublisher().

トラブルシューティング

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

エラー処理

の両方にコールバック・メソッドがあります。 Session.publish() そして OT.initPublisher().これら両方のメソッドに対するエラー応答を処理することを推奨する。前述したように、これらのステップを分割して OT.initPublisher() セッションへの接続を開始する前にまた、これらのメソッドの両方を同時に呼び出さない方が、エラー処理が簡単になります。これは、エラーが発行されると、両方のエラーハンドラが発火するからです。を待つのが最善です。 OT.initPublisher() を完了し Session.connect() を呼び出す。 Session.publish().こうすることで、ハードウェアに関連するすべての問題を OT.initPublisher() コールバックと、ネットワークに関連するすべての問題を Session.publish() コールバック。

var connected = false,
  publisherInitialized = false;

var publisher = OT.initPublisher(function(err) {
  if (err) {
    // handle error
  } else {
    publisherInitialized = true;
    publish();
  }
});

var publish = function() {
  if (connected && publisherInitialized) {
    session.publish(publisher);
  }
};

session.connect(token, function(err) {
  if (err) {
    // handle error
  } else {
    connected = true;
    publish();
  }
});

アクセス拒否

のNumbersが最も多かった。 OT.initPublisher() は、エンドユーザーがカメラとマイクへのアクセスを拒否した結果である。これは accessDenied イベントか、OT.initPublisher() メソッドへのエラー・レスポンスを code プロパティを1500に設定し message プロパティが "Publisher Access Denied: "に設定されています。この場合、ユーザに対して、再度パブリッシュを試み、カメラへのアクセスを許可するようにメッセージを表示することをお勧めします。

publisher.on({
  'accessDenied': function() {
    showMessage('Please allow access to the Camera and Microphone and try publishing again.');
  }
});

デバイスアクセス

もうひとつの理由は OT.initPublisher() が失敗するのは、OpenTok がカメラやマイクにアクセスできない場合です。これは、カメラやマイクがマシンに接続されていない場合、カメラやマイクのドライバに問題がある場合、または他のアプリケーションがカメラやマイクを使用している場合に起こります (これは Windows でのみ起こります)。ハードウェア・セットアップ・コンポーネントまたは OT.getDevices() メソッドを直接呼び出します。しかし OT.initPublisher() というのも、まだ何か問題が起こる可能性があるからだ。例えば、ユーザーがカメラやマイクへのアクセスを拒否した可能性がある。この場合 error.name プロパティが "OT_USER_MEDIA_ACCESS_DENIED":

publisher = OT.initPublisher('publisher', {}, function (err) {
  if (err) {
    if (err.name === 'OT_USER_MEDIA_ACCESS_DENIED') {
      // Access denied can also be handled by the accessDenied event
      showMessage('Please allow access to the Camera and Microphone and try publishing again.');
    } else {
      showMessage('Failed to get access to your camera or microphone. Please check that your webcam'
        + ' is connected and not being used by another application and try again.');
    }
    publisher.destroy();
    publisher = null;
  }
});

ネットワークエラー

パブリッシングに失敗するその他の理由は、通常、何らかのネットワーク障害によるものです。へのコールバックで処理します。 Session.publish().ユーザーがネットワークに接続されていない場合、コールバック関数にエラーオブジェクトが渡されます。 name プロパティを "OT_NOT_CONNECTED". ユーザーがWebRTC接続を許可しない非常に制限の厳しいネットワーク環境にいる場合、パブリッシャーは接続に失敗し、パブリッシャー要素には回転中のアイコンが表示されるだけです。このエラーには name プロパティを "OT_CREATE_PEER_CONNECTION_FAILED".この場合、公開に失敗したのでネットワーク接続を確認するようにというメッセージをユーザーに表示することをお勧めします。このようなエラーの処理は次のようになります:

session.publish(publisher, function(err) {
  if (err) {
    switch (err.name) {
      case "OT_NOT_CONNECTED":
        showMessage("Publishing your video failed. You are not connected to the internet.");
        break;
      case "OT_CREATE_PEER_CONNECTION_FAILED":
        showMessage("Publishing your video failed. This could be due to a restrictive firewall.");
        break;
      default:
        showMessage("An unknown error occurred while trying to publish your video. Please try again later.");
    }
    publisher.destroy();
    publisher = null;
  }
});

接続性の喪失

パブリッシャは、接続に成功した後に接続を失うこともあります。多くの場合、セッションも接続を切断しますが、必ずしもそうなるとは限りません。をリッスンすることで、パブリッシャの切断を処理できます。 streamDestroyed イベントを reason プロパティを "networkDisconnected "に設定する:

publisher.on({
  streamDestroyed: function (event) {
    if (event.reason === 'networkDisconnected') {
      showMessage('Your publisher lost its connection. Please check your internet connection and try publishing again.');
    }
  }
});

すべてをまとめる

次のコードはパブリッシャーを作成し、セッションに接続します ( セッションの基本)、クライアントがセッションに接続したときにセッションにストリームを 発行し、パブリッシャーがストリーミングを開始したときと停止したときを 検出する:

var session;
var publisher;

// Replace with the replacement element ID:
publisher = OT.initPublisher(replacementElementId);
publisher.on({
  streamCreated: function (event) {
    console.log("Publisher started streaming.");
  },
  streamDestroyed: function (event) {
    console.log("Publisher stopped streaming. Reason: "
      + event.reason);
  }
});

// Replace apiKey and sessionID with your own values:
session = OT.initSession(apiKey, sessionID);
// Replace token with your own value:
session.connect(token, function (error) {
  if (session.capabilities.publish == 1) {
    session.publish(publisher);
  } else {
    console.log("You cannot publish an audio-video stream.");
  }
});

セッション公開の再試行の実装

Video API JS SDK では、特にモバイルブラウザにおいて、一時的な公開失敗が既知の繰り返し発生する現象として確認されています。この現象は、 session.publish() 失敗した場合、SDKはコンプリートハンドラのコールバックを通じてエラーを返します。推奨されるアプローチは、試行の間に遅延を設けたアプリケーションレベルのリトライロジックを実装することです。

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

どのように session.publish() 作品

session.publish() 呼び出し方は2通りあります:

  • あらかじめ初期化済みのパブリッシャーの場合: session.publish(publisher, callback) — 電話して OT.initPublisher() まず、その結果として得られたパブリッシャーインスタンスを session.publish(). これが 推奨されるアプローチ メディアの取得とストリームの生成を分離することで、エラー処理がより明確になります。
  • パブリッシャーインスタンスがない場合: session.publish(targetElement, options, callback) — SDKは内部で以下を呼び出します OT.initPublisher() あなたのために。この場合、メディア取得エラーとストリーム作成エラーの両方が、単一の session.publish() コールバック。

ベストプラクティス: スプリット OT.initPublisher() そして session.publish() 個別のステップに分割します。これにより、 OT.initPublisher() におけるコールバックおよびネットワーク/シグナリングエラー session.publish() コールバック — リトライ処理を大幅に簡素化し、より的確なものにします。

// Recommended: split initialization from publishing
let publisherReady = false;
let sessionConnected = false;

const publisher = OT.initPublisher('publisher-container', publisherOptions, (err) => {
  if (err) {
    handleInitPublisherError(err); // hardware/media errors — see OT.initPublisher() errors below
    return;
  }
  publisherReady = true;
  maybePublish();
});

session.connect(token, (err) => {
  if (err) { /* handle connection error */ return; }
  sessionConnected = true;
  maybePublish();
});

function maybePublish() {
  if (sessionConnected && publisherReady) {
    publishWithRetry(session, publisher);
  }
}

出版の失敗が起こる理由

一時的な公開失敗の最も一般的な根本原因は、以下の通りです:

  • StreamCreateRequest のタイムアウト(エラー 1500): パブリッシャーが妥当な時間内にストリームの作成を完了できなかった。これは通常、ICE/SDPネゴシエーション中のネットワーク遅延が原因である。
  • mediaStopped 公開フロー中のイベント、そこでメディアデバイスへのアクセスが中断される可能性があります。
  • 適切なクリーンアップを行わないままPublisherオブジェクトを再利用すること — 異なる制約で初期化されたパブリッシャーインスタンスを、呼び出さずに再利用する unpublish そして、再初期化を行います。
  • OT_NOT_CONNECTED — セッションが完全に接続される前に公開しようとしています。
  • OT_PERMISSION_DENIED — トークンには「publish」ロールが割り当てられていません(再試行不可)。

エラーの原因は OT.initPublisher()

パブリッシャーを次のように事前初期化する場合 OT.initPublisher(), すべてのハードウェアおよびメディア取得エラーは、その完了ハンドラに渡されます — 以前 session.publish() が呼び出されることがあります。このコールバック内で、以下のエラーごとの対処法に従って処理を行ってください。エラーによってはユーザーの操作やコードの修正が必要になるものもあれば、一時的なメディアエラーの場合はパブリッシャーを再初期化することで対処できる場合もあります。

注: もし電話をかけるなら session.publish() 事前に初期化されていないパブリッシャーがある場合、これらの同じエラーが session.publish() その代わりにコールバックを使用します。

error.name 説明 推奨される対応
OT_HARDWARE_UNAVAILABLE そのハードウェアは存在しますが、取得できませんでした(例:別のアプリケーションで使用中)。 ユーザーに、そのデバイスで実行中の他の Applications を閉じるよう促してから、次の関数を呼び出します。 OT.initPublisher() また。
OT_INVALID_PARAMETER に引数として渡された1つ以上のパラメータ OT.initPublisher() 無効でした。 に渡しされるオプションオブジェクトを修正する OT.initPublisher().
OT_MEDIA_ENDED について ended 初期化中にvideo要素で発生したイベント。 パブリッシャーを再初期化してください。
OT_MEDIA_ERR_ABORTED video要素のストリームの取得が中断されました。 少し時間を置いてから、パブリッシャーを再初期化してください。
OT_MEDIA_ERR_DECODE video要素でストリームを再生しようとした際に、デコードエラーが発生しました。 少し時間を置いてから、パブリッシャーを再初期化してください。
OT_MEDIA_ERR_NETWORK ネットワークエラーが発生したため、ストリームの取得が停止しました。 少し時間を置いてから、パブリッシャーを再初期化してください。
OT_MEDIA_ERR_SRC_NOT_SUPPORTED このストリームは、再生に適していないと判定されました。 パブリッシャーの映像・音声ソースの設定を確認し、再初期化してください。
OT_NOT_SUPPORTED ユーザーからのメディアリクエストに含まれる一部の要素が、このブラウザではサポートされていません。 ユーザーに通知し、再試行は行わない。
OT_NO_DEVICES_FOUND 音声または映像の入力デバイスが検出されませんでした。 再試行する前に、ユーザーにデバイスの接続を促す。
OT_NO_VALID_CONSTRAINTS 動画と音声の両方が無効になっています。少なくとも片方は有効にする必要があります。 確保する publishAudio または publishVideotrue 「パブリッシャー設定」で。
OT_PROXY_URL_ALREADY_SET_ERROR について proxyUrl すでに設定されています。再度設定しても何の効果もありません。 プロキシURLの設定は、SessionオブジェクトやPublisherオブジェクトを初期化する前に、一度だけ行ってください。
OT_REQUESTED_DEVICE_PERMISSION_DENIED 指定されたオーディオデバイスには、使用するための権限がありません。 ユーザーにデバイスの権限を許可するよう促します。
OT_USER_MEDIA_ACCESS_DENIED ユーザーは、カメラ、マイク、または画面へのアクセスを拒否しました。 ブラウザの設定でアクセスを許可するようユーザーに促す。自動的に再試行しない。
OT_SCREEN_SHARING_NOT_SUPPORTED お使いのブラウザでは、画面共有機能はサポートされていません。 ユーザーに通知し、再試行は行わない。
OT_UNABLE_TO_CAPTURE_SCREEN 画面共有の依頼がありましたが、対応していません(例: videoSource に設定する。 "screen", "application"あるいは "window"). 電話 OT.checkScreenSharingCapability() 画面共有パブリッシャーを初期化する前に。
OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED 画面共有にはブラウザ拡張機能が必要ですが、登録されているものはありません。 呼び出す前に拡張機能を登録してください OT.initPublisher().
OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED 画面共有にはブラウザ拡張機能が必要ですが、それがインストールされていません。 ユーザーに必要な拡張機能をインストールするよう案内してください。
const publisher = OT.initPublisher('publisher-container', publisherOptions, (err) => {
  if (!err) {
    publisherReady = true;
    maybePublish();
    return;
  }

  // Hardware/media errors — handle before session.publish() is called
  switch (err.name) {
    case 'OT_REQUESTED_DEVICE_PERMISSION_DENIED':
      showMessage('Please allow access to your camera and microphone and try again.');
      break;
    case 'OT_HARDWARE_UNAVAILABLE':
    case 'OT_NO_DEVICES_FOUND':
      showMessage('Could not access your camera or microphone. Please check your devices.');
      break;
    case 'OT_SCREEN_SHARING_NOT_SUPPORTED':
    case 'OT_UNABLE_TO_CAPTURE_SCREEN':
    case 'OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED':
    case 'OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED':
      showMessage('Screen sharing is not available. Please check your browser settings.');
      break;
    default:
      showMessage('Could not initialize the publisher. Please try again.');
  }

  publisher.destroy();
});

以下の原因による回復可能なエラーと回復不可能なエラー session.publish()

すべてではない session.publish() エラーはすべて同じというわけではありません。リトライロジックを実装する前に、エラーを正しく分類することが不可欠です。回復不可能なエラーに対してリトライを行うと、時間を浪費し、ユーザー体験を損なうだけでなく、別の対応を必要とする真の障害を見逃してしまう恐れがあります。

注: エラーコード 1500 分類メカニズムとしては非推奨となっています。常に error.name このプロパティは、特定の障害シナリオに対応しているため、プログラムからエラーを特定するために使用できます。

注: いつ session.publish() は、次のように呼ばれます ~なし 事前に初期化されたパブリッシャー、および OT.initPublisher() (上記に記載されたもの)は、以下の経路を通じて表面化する可能性もあります。 session.publish() コールバック。その場合は、それらを再試行不可として扱い、前述と同じ処理を適用してください。

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

これらのエラーは、プログラマーのミス、厳しい権限の制約、または無効な呼び出しコンテキストに起因するものです。再試行しても解決しません。代わりに、ユーザーにわかりやすいメッセージを表示するか、アプリケーションのロジックを修正してください。

error.name 説明 推奨される対応
OT_NOT_CONNECTED session.publish() セッションが接続される前に呼び出されました。 確保する session.connect() 公開前に正常に完了しています。
OT_PERMISSION_DENIED このトークンの役割では公開は許可されていません(必ず publisher または moderator). ユーザーに、公開権限がないことを通知してください。再試行は行わず、正しいロールを指定してトークンを生成してください。
OT_INVALID_PARAMETER 指定されたパブリッシャーは無効であるか、すでに公開されているか、あるいは別のセッションにすでに紐付けられています。 アプリケーションロジックを修正する:呼び出し session.unpublish(publisher) 再公開する前に、または新しいパブリッシャーを初期化してください。
OT_USER_MEDIA_ACCESS_DENIED ユーザーがカメラまたはマイク(画面共有ストリームの場合は画面)へのアクセスを拒否しました。 ユーザーに、ブラウザの設定でデバイスへのアクセスを許可するよう促し、再度試みてください。自動的に再試行しないでください。
OT_CHROME_MICROPHONE_ACQUISITION_ERROR 既知のブラウザの不具合により、ブラウザがマイクへのアクセスを取得できませんでした。この問題を解決するには、エンドユーザーがブラウザを再起動し、ページを再読み込みする必要があります。 ユーザーに通知し、再試行は行わない。
OT_SCREEN_SHARING_NOT_SUPPORTED お使いのブラウザでは、画面共有機能はサポートされていません。 ユーザーに通知し、再試行は行わない。
OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED 画面共有にはブラウザ拡張機能が必要ですが、登録されているものはありません。 画面共有ストリームの公開を試みる前に、拡張機能を登録してください。
OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED 画面共有にはブラウザ拡張機能が必要ですが、それがインストールされていません。 ユーザーに必要な拡張機能をインストールするよう案内してください。
OT_CONSTRAINTS_NOT_SATISFIED 要求されたメディアの制約(解像度、フレームレート、デバイス)を、このブラウザでは満たすことができませんでした。 パブリッシャーの制約条件を調整し、再初期化してください。
OT_NO_VALID_CONSTRAINTS 動画と音声の両方が無効になっています。少なくとも片方は有効にする必要があります。 確保する publishAudio または publishVideotrue を呼び出す前に session.publish().
OT_NOT_SUPPORTED ユーザーからのメディアリクエストに含まれる一部の要素が、このブラウザではサポートされていません。 ユーザーに通知し、再試行は行わない。
OT_STREAM_CREATE_FAILED ユーザーが、暗号化キーを指定せずにエンドツーエンド暗号化(E2EE)が有効なセッションで公開を試みたか、またはサーバーモデルでストリームを作成できなかった可能性があります。 E2EEセッションについては、以下を通じて暗号化シークレットが設定されていることを確認してください。 session.setEncryptionSecret() 公開する前に。
OT_INVALID_AUDIO_OUTPUT_SOURCE 無効なオーディオ出力デバイス ID が指定されました。 再試行する前に、そのデバイスIDが有効なオーディオ出力デバイスであることをVerifyしてください。
OT_UNABLE_TO_CAPTURE_MEDIA メディアをキャプチャできませんでした — 不明なエラーが発生しました。 ユーザーに通知し、デバイスの利用可能状況を確認するよう促します。

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

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

error.name 説明 推奨される対応
OT_TIMEOUT (コード 1500) session.publish() タイムアウトしました — the StreamCreateRequest 期限内に完了しなかった。最も一般的な原因は、ICE/SDPネゴシエーションの遅延、あるいは mediaStopped のイベントがある。 指数関数的なバックオフを用いて再試行する(最大3回)。パブリッシャーインスタンスが破棄されていない場合は、同じインスタンスを再利用する。
OT_ICE_WORKFLOW_FAILED ICEネゴシエーションに失敗しました — ピア接続を確立できませんでした。制限の厳しいネットワークでは、しばしば一時的な現象として発生します。 再試行してください。すべての試行を行っても問題が解決しない場合は、ネットワークまたはファイアウォールの問題の可能性があることをユーザーに伝えてください。
OT_CREATE_PEER_CONNECTION_FAILED WebRTCのピア接続を確立できませんでした。ファイアウォールの制限や、一時的なプラットフォームの問題が考えられます。 もう一度試してください。それでも問題が解決しない場合は、ユーザーにネットワーク接続を確認するよう促すメッセージを表示してください。
OT_MEDIA_ERR_ABORTED / OT_MEDIA_ERR_NETWORK ネットワークエラーにより、メディアの取得が中止または中断されました。 少し時間を置いてから、もう一度試してください。
OT_MEDIA_ERR_DECODE video要素でストリームを再生しようとした際に、デコードエラーが発生しました。 少し時間を置いてから、もう一度お試しください。それでも問題が解決しない場合は、メディアのフォーマットが互換性がない可能性があります。
OT_MEDIA_ERR_SRC_NOT_SUPPORTED このストリームは、再生に適していないと判定されました。 もう一度試してみてください。それでも問題が解決しない場合は、パブリッシャーの映像・音声ソースの設定を確認してください。
OT_SET_REMOTE_DESCRIPTION_FAILED WebRTC接続が、以下の処理中に失敗しました。 setRemoteDescription. 通常、一時的な通信の問題です。 バックオフを行いながら再試行してください。すべての試行を終えても問題が解決しない場合は、ネットワークに問題がある可能性があるとユーザーに通知してください。
OT_UNEXPECTED_SERVER_RESPONSE サーバーから予期せぬエラーが返されました。 少し時間を置いてから、もう一度試してください。それでも問題が解決しない場合は、エラーを記録し、ユーザーにその旨を伝えてください。

別の対応が必要なエラー(単純な再試行では済まないもの)

エラーの中には、単純な再試行でも完全な停止でもないものがあり、再試行を行う前に特定の是正措置を講じる必要があります。

error.name 説明 推奨される対応
OT_HARDWARE_UNAVAILABLE カメラまたはマイクが利用できません(例:別のアプリケーションで使用中、または接続が切断されています)。 ユーザーに対し、そのデバイスで実行中の他のアプリケーションを閉じるよう促し、その後、以下のコマンドでパブリッシャーを再初期化します。 OT.initPublisher() 再試行する前に。
OT_NO_DEVICES_FOUND 音声または映像の入力デバイスが検出されませんでした。 ユーザーにデバイスの接続を促します。ユーザーがデバイスが利用可能であることを確認するまで、再試行しないでください。

まとめ:エラー分類を用いた推奨リトライパターン

async function publishWithRetry(session, publisher, attempt = 1) {
  const MAX_RETRIES = 3;
  const RETRY_DELAY_MS = 2000;

  const error = await new Promise((resolve) => {
    session.publish(publisher, resolve);
  });

  if (!error) {
    console.log('Publishing started successfully.');
    return;
  }

  // Non-recoverable: programmer error or hard permission constraint
  const nonRetryable = [
    'OT_NOT_CONNECTED',
    'OT_PERMISSION_DENIED',
    'OT_INVALID_PARAMETER',
    'OT_USER_MEDIA_ACCESS_DENIED',
    'OT_CHROME_MICROPHONE_ACQUISITION_ERROR',
    'OT_SCREEN_SHARING_NOT_SUPPORTED',
    'OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED',
    'OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED',
    'OT_CONSTRAINTS_NOT_SATISFIED',
    'OT_NO_VALID_CONSTRAINTS',
    'OT_NOT_SUPPORTED',
    'OT_STREAM_CREATE_FAILED',
    'OT_INVALID_AUDIO_OUTPUT_SOURCE',
    'OT_UNABLE_TO_CAPTURE_MEDIA',
  ];

  // Requires corrective action before retrying
  const requiresAction = [
    'OT_HARDWARE_UNAVAILABLE',
    'OT_NO_DEVICES_FOUND',
  ];

  if (nonRetryable.includes(error.name)) {
    console.error('Non-retryable error — user action or code fix required:', error.name);
    handleNonRecoverableError(error);
    return;
  }

  if (requiresAction.includes(error.name)) {
    console.warn('Device error — prompting user before retrying:', error.name);
    handleDeviceError(error);
    return;
  }

  // Recoverable: retry with backoff
  if (attempt < MAX_RETRIES) {
    console.warn(`Publish attempt ${attempt} failed (${error.name}), retrying...`);
    await delay(RETRY_DELAY_MS * attempt);
    await publishWithRetry(session, publisher, attempt + 1);
  } else {
    console.error('All publish attempts failed. Disconnecting user.');
    handlePublishFailure(session);
  }
}

function handleNonRecoverableError(error) {
  // Surface a meaningful message to the user based on error.name
  // e.g. for OT_USER_MEDIA_ACCESS_DENIED: "Please allow camera/mic access"
}

function handleDeviceError(error) {
  // Prompt the user to check their device, then allow them to retry manually
}

function handlePublishFailure(session) {
  session.disconnect();
}

使用方法:

const publisher = OT.initPublisher('publisher-container', publisherOptions);

// Wait for session to be connected before publishing
session.connect(token, (err) => {
  if (err) { /* handle connection error */ return; }
  publishWithRetry(session, publisher);
});

重要:再試行前のパブリッシャーのクリーンアップ

ほとんどの障害シナリオにおいて――以下を含む OT_TIMEOUT / OT_ICE_WORKFLOW_FAILED — パブリッシャー・インスタンス 再利用可能 次の分については直接 session.publish() call。再初期化する必要はありません。

公開の試行が失敗した場合、SDK は作成しようとしていたストリームを解放し、 streamDestroyed パブリッシャーでのイベントで reason: "reset". これは想定内のクリーンアップ処理であり、 違う パブリッシャーの再初期化が必要になる場合がありますが、同じインスタンスで再試行できます。なお、 "reset" これは、「パブリッシャーのストリームが破棄された」という一般的な理由です(また、 publisher.destroy())、したがって、これを専用の公開失敗インジケーターではなく、クリーンアップのシグナルとして扱ってください。 error.name より session.publish() 再試行するかどうかを決定するためのコールバック。

このSDKは 違う 自動的に再試行する session.publish() ユーザーに代わって――上記のように、再試行ロジックはアプリケーションレベルで実装する必要があります。

以下のコマンドでパブリッシャーを再初期化しなければならないのは、次の場合のみです。 OT.initPublisher() 再試行する前に、パブリッシャー自身の destroyed イベントが発生します。このイベントは最終的なものであり、パブリッシャーオブジェクト自体が使用できなくなったことを示します。

publisher.on('destroyed', () => {
  // Publisher object is no longer usable — reinitialize before retrying
  publisher = OT.initPublisher('publisher-container', publisherOptions);
});

// A streamDestroyed event with reason 'reset' is emitted by the SDK when it tears
// down the stream (during a failed publish attempt, or when you call publisher.destroy()).
// A 'reset' during a failed publish does NOT require reinitializing the publisher.
publisher.on('streamDestroyed', (event) => {
  if (event.reason === 'reset') {
    // Expected cleanup — reuse the same publisher instance
    return;
  }
  // Handle other streamDestroyed reasons as appropriate for your application
});

やってはいけないこと

  • を行う。 違う コール OT.initPublisher() 同じパブリッシャー・オブジェクトに対して、最初にクリーンアップを行わずに異なる制約を2回適用すると(session.unpublish() → 待つ streamDestroyed → その後、再初期化します)。
  • を行う。 違う 再試行する OT_PERMISSION_DENIED (ユーザーがカメラ/マイクへのアクセスを拒否しました) — これは再試行ではなく、ユーザーによる対応が必要です。
  • を行う。 違う 再試行する OT_NOT_CONNECTED — 公開する前に、セッションが接続されていることを確認してください。
  • を行う。 違う 無制限に再試行する — 再試行回数を3回に制限し、失敗時には適切に対処する。

の取り扱いについて mediaStopped イベント

メディアトラックの再生は、公開途中で停止させることができます。このイベントを検知し、再試行のトリガーとして処理してください:

publisher.on('mediaStopped', async () => {
  console.warn('Media stopped during publish — retrying...');
  // Unpublish if already publishing, then retry
  try { session.unpublish(publisher); } catch (e) { /* ignore */ }
  await delay(2000);
  publishWithRetry(session, publisher);
});

推奨パラメータの概要

パラメータ 推奨値 備考
最大再試行回数 3 回復力とユーザーの待ち時間のバランスをとる
再試行の遅延時間 2秒 × 試行回数(2秒、4秒、6秒) プラットフォームが回復する時間を確保する
すべての再試行で失敗する ユーザーの接続を切断する 「ゴースト参加者」の状態を回避する
再試行不可能なエラー OT_NOT_CONNECTED, OT_PERMISSION_DENIED これらについては、早めに失敗しよう

音声キャプチャに関する問題の対処法: audioAcquisitionProblem そして audioAcquisitionProblemResolved

パブリッシュレベルでの再試行とは別に、アクティブなパブリッシャーに影響を及ぼす可能性のある別の種類のオーディオの問題があります。それは、パブリッシュが成功した後でも、クライアントのオーディオデバイスがオーディオデータを配信できない場合です。Video API JS SDK では、このシナリオに特化した 2 つのイベントが提供されています。

よくある原因

について audioAcquisitionProblem SDKがパブリッシャーの統計情報を通じて、オーディオトラックがピア接続へのバイト送信を停止したことを検出した際に、このイベントがトリガーされます。たとえ getUserMedia 成功し、パブリッシャーはアクティブな状態のようです。最も一般的な根本原因は以下の通りです:

  • セッションの途中でBluetoothオーディオデバイスが接続または切断された場合: セッションがアクティブな状態で、ユーザーがイヤホンを接続または取り外したり、Bluetoothヘッドホン(AirPodsなど)を接続したりすると、OSによってデフォルトのオーディオデバイスが切り替わる場合があります。その結果、ブラウザのオーディオパイプラインが新しいデバイス上のマイクを再取得できなくなり、送信されるオーディオバイト数がゼロになってしまうことがあります。
  • セッション開始時のオーディオデバイスの変更: セッションの非常に早い段階――公開後1~2秒以内――でオーディオ入力を切り替えると、この問題が発生しやすくなります。
  • ブラウザまたはOSによってオーディオトラックが終了しました(trackEndedEvent): ブラウザは、ユーザーの操作とは無関係に、基盤となるオーディオトラックを終了させることができます。SDKは、これを track.ended イベントおよびレイズ audioAcquisitionProblemmethod: trackEndedEvent.
  • 統計に基づく検出(音声バイトの流通なし): ピア間の接続が「接続済み」状態になると、SDKは約数秒ごとにパブリッシャーのステータスをポーリングします。オーディオトラックの送信 bytesSent 連続する世論調査の間で増加しない、 audioAcquisitionProblem が設定される( method: getStats). いつ bytesSent 再び増加し始め、 audioAcquisitionProblemResolved が提起される。

注: この事象が必ずしも致命的な障害を示すわけではありません。セッションによっては、音声が自然に回復することもあります(そして audioAcquisitionProblemResolved が呼び出される);一方、他のケースでは、オーディオストリームが回復せず、下流のサブスクライバーは最終的にタイムアウトとなる可能性があります。

イベント

これらのイベントは、パブリッシャーインスタンスで発生します:

  • audioAcquisitionProblem — SDKが(パブリッシャーの統計情報に基づき)パブリッシャーによる音声送信が停止したことを検出したとき、または基になるオーディオトラックが ended イベント。これは必ずしもストリームが失敗することを意味するわけではありませんが、オーディオのキャプチャが中断されたことを示す指標となります。
  • audioAcquisitionProblemResolved — 以前の…の後、音声伝送が回復した際に発火する audioAcquisitionProblem. このイベントが発生しても、是正措置は必要ありません。

注: これらのイベントは現在、 文書化済み/型指定済みの公開APIの一部ではない (これらはSDKのTypeScript定義には宣言されていません)。これらはバージョンごとに変更される可能性のある「可能な限り提供される」シグナルとして扱い、本番環境でこれらに依存する前に、お使いのSDKのバージョンで利用可能かどうかを確認してください。パブリッシャーで発行される際、これらには method 問題がどのように検出されたかを示すプロパティ('getStats' または 'trackEndedEvent').

注: オーディオ取得のチェックはパブリッシャーの統計情報に基づいているため、実際のオーディオ中断とイベントが発生するまでの間に、わずかな遅延が生じる場合があります。

推奨されるリカバリパターン

受信時にショートタイマーを開始する audioAcquisitionProblem.もし audioAcquisitionProblemResolved タイマーが切れる前に問題が解消された場合、音声は自動的に復旧しているため、何も操作する必要はありません。タイマーが切れても問題が解決しない場合は、復旧措置として音声ソースを切り替えてください。

publisher.on('audioAcquisitionProblem', () => {
  // Start a 3-second timer
  const timeout = setTimeout(() => {
    // Problem not resolved — attempt recovery by switching audio source
    publisher.setAudioSource(newDeviceId);
  }, 3000);

  publisher.on('audioAcquisitionProblemResolved', () => {
    // Audio recovered — clear the timer, no action needed
    clearTimeout(timeout);
  });
});

主な検討事項

  • 必ずしも失敗の兆候とは限らない: audioAcquisitionProblem 必ずしもサブスクリプションの失敗につながるわけではありません。これを決定的な失敗事象としてではなく、監視や必要に応じた対応を行うための早期の兆候として活用してください。
  • パブリッシャーのオーディオ統計情報を監視する: 受け取った後 audioAcquisitionProblem、また、パブリッシャーのオーディオ統計情報を監視することもできます(例: publisher.getStats()) 措置を講じる前に、音声の送信が本当に停止したかどうかを確認してください。
  • 復旧措置: 呼び出し publisher.setAudioSource(newDeviceId) これが主要な復旧メカニズムです。これにより、公開の解除と再公開という完全なサイクルを経ることなく、オーディオ入力デバイスを切り替えることができます。
  • サブスクリプションのタイムアウトとの関係: 音声が復旧せず、配信元が引き続き音声パケットを送信しない場合、加入者は最終的に OT_TIMEOUT (1501). 積極的な対応 audioAcquisitionProblem これにより、下流での不具合を防ぐことができます。