購読する診断
このガイドを使用して、ストリームの詳細を検査し、ストリームの終了を検出し、一般的な加入者の問題を解決します。また、UI で接続の問題を処理するためのガイダンスも含まれています。
ストリーム情報
Vonage Video SDKは、ほとんどのユースケースで推奨される高レベルの統計APIを通じて、詳細なストリーム品質メトリクスを公開します。このAPIは、音声、ビデオ、ネットワーク、および送信者側の統計を、ピア接続の遷移をまたいで安定したまま、統一されたセッション認識形式で提供します。高度なデバッグのために、SDKは未処理のピア接続データを反映する生のWebRTC統計レポートへのアクセスも提供します。
参照 クライアント観測可能性開発者ガイド をご覧ください。
また、デバッグや分析を支援するために、アクティブなストリームの診断詳細を取得することもできます。
サブスクライバーのオーディオとビデオの統計情報を取得するには、以下のイベントハンドラを追加します。 audioNetworkStats そして videoNetworkStats イベントは、OTSubscriber によってディスパッチされる。これらは、以下を含むサブスクライバのストリームに関する情報を提供する:
- 失われたオーディオおよびビデオパケットの総数。
- 受信したオーディオパケットとビデオパケットの総数。
- 受信したオーディオとビデオの合計バイト数。
- 現在の平均ビデオフレームレート。
<OTSubscriber
eventHandlers={{
audioNetworkStats: event => {
console.log('subscriber audioNetworkStats event', event);
},
videoNetworkStats: event => {
console.log('subscriber videoNetworkStats event', event);
},
}}
/>
より詳細なストリーム統計を取得するには Subscriber.getRtcStatsReport() メソッドを呼び出します。このメソッドはプロミスを返し、成功すると、JSON表現の RtcStatsReport オブジェクトを返します:
<OTSubscriber
eventHandlers={{
connected: event => {
setTimeout(() => {
this.subscriber.getRtcStatsReport();
}, 4000);
},
rtcStatsReport: event => {
console.log('subscriber rtcStatsReport event', event);
},
}}
/>
Streamオブジェクトには、ストリームを定義する以下のプロパティがあります:
connection- ストリームを公開している接続に対応する Connection オブジェクト。これを Session オブジェクトの connection プロパティと比較することで、ストリームがローカルの Web ページから発行されているかどうかを確認できます。creationTime- ストリーム作成のタイムスタンプ(数値)。この値はミリ秒単位で計算されます。この値を Date オブジェクトに変換するにはnew Date(stream.creationTime).hasAudio- 論理値) ストリームに音声があるかどうか。このプロパティは、パブリッシャーがオーディオをオンまたはオフにした場合に変更できます ( Publisher.publishAudio()).こうなると セッション オブジェクトはstreamPropertyChangedイベントを開催する。hasVideo- 論理値) ス ト リ ームが動画を持つかど う か。 initials-(Boolean) ストリームのイニシャル。 初期化).name- (String) ストリームの名前。これは、デフォルトでは、ユーザーがHTML DOMのサブスクライバーの上にマウスオーバーすると表示されます。ただし、UI をカスタマイズして、名前を非表示にしたり、マウスオーバーせずに表示したりすることができます。videoDimensions- このオブジェクトには2つのプロパティがある:widthそしてheight.どちらもNumbersだ。そのwidthプロパティはエンコードされたストリームの幅です。heightプロパティは、エンコードされたストリームの高さです。(これらは、ストリームに対応するPublisherオブジェクトとSubscriberオブジェクトの実際の幅とは無関係です)。このプロパティは、iOSデバイスからパブリッシュされたストリームのサイズが変更された場合、デバイスの向きの変更に基づいて変更される可能性があります。videoType- 動画のタイプ: "camera"、"screen"、"custom"、または未定義のいずれか。screen "動画は、パブリッシャーの画面共有を動画ソースとして使用します。"custom "動画は、パブリッシャーの VideoTrack 要素を動画ソースとして使用します。またvideoTypeはundefinedストリームが音声のみの場合 ( 音声ガイド).このプロパティは、モバイル機器から公開されるストリームがカメラから画面共有ビデオタイプに変更された場合に変更される可能性があります。詳細については 画面共有 - Web.
について hasAudio, hasVideo, videoDimensionsそして videoType プロパティが変更されることがあります (例えば、パブリッシャーがビデオの電源を入れたり切ったりした場合など)。このような場合、Session オブジェクトは streamPropertyChanged イベントをディスパッチします ( StreamPropertyChangedイベント).
Streamオブジェクトには、ストリームを定義する値を返す以下のメソッドがあります:
getConnection()- (Connection) ストリームを公開している接続に対応する Connection オブジェクトを返します。この値をgetConnection()メソッドを呼び出して、ストリームがクライアントによって公開されているかどうかを確認します。getCreationTime()- Date) ス ト リ ームの作成時刻の タ イ ムス タ ンプ。hasAudio()- 論理値) ス ト リ ームが音声を持つかど う か。hasVideo()- 論理値) ス ト リ ームが動画を持つかど う か。getName()- 文字列) ストリームの名前を返します。これは、ストリームのパブリッシャを初期化するときに設定されます ( パブリッシャー・オブジェクトの初期化).getStreamId()- 文字列)ストリームの一意のID。getVideoHeight()- int) ス ト リ ームの高 さ を ピ ク セル単位で指定 し ます。getVideoType()- StreamVideoType) ス ト リ ームがカ メ ラ ビデオ ソ ース を用いているかど う か。StreamVideoTypeCamera.StreamVideoTypeCamera)、スクリーン共有ビデオソース(StreamVideoTypeScreen.StreamVideoTypeScreen)、またはカスタム・ビデオ・ソース(StreamVideoTypeScreen.StreamVideoTypeScreen).
参照 画面共有.
getVideoWidth()- int) ス ト リ ームの幅を ピ ク セル単位で指定 し ます。
OTStreamオブジェクトは、ストリームを定義する以下のプロパティを持つ:
connection-ストリームを公開している接続に対応するOTConnectionオブジェクト。これをconnectionプロパティを使用して、ストリームがクライアントによって公開されているかどうかを確認します。creationTime-ストリームの作成時刻の日付タイムスタンプ。hasAudio-(Bool) ストリームに音声があるかどうか。hasVideo-(Bool) ストリームがビデオを持っているかどうか。name-ストリームの名前。これは、ストリームのパブリッシャを初期化する際に設定されます ( OTPublisherオブジェクトの初期化).session-(OTSession) ストリームがバインドされている Vonage Video セッション。streamId-文字列) ストリームの一意のID。videoDimensions-このストリームのビデオメディアトラックの現在の寸法を定義する CGSize オブジェクト。videoType-OTStreamVideoType) ストリームがカメラ映像ソースを使うかどうか (OTStreamVideoTypeCamera)、スクリーン共有ビデオソース(OTStreamVideoTypeScreen)、またはカスタム・ビデオ・ソース(OTStreamVideoTypeCustom).
参照 画面共有.
OTStreamオブジェクトは、ストリームを定義する以下のプロパティを持つ:
connection-ストリームを公開している接続に対応するOTConnectionオブジェクト。これをconnectionプロパティを使用して、ストリームがクライアントによって公開されているかどうかを確認します。creationTime-ストリームの作成時刻のNSDateタイムスタンプ。hasAudio-論理値) ストリームに音声があるかどうか。hasVideo-論理値) ストリームに動画があるかどうか。name-ストリームの名前。これは、ストリームのパブリッシャを初期化するときに設定されます ( OTPublisherオブジェクトの初期化).session-(OTSession) ストリームがバインドされている Vonage Video セッション。streamId-(NSString) ストリームの一意のID。videoDimensions-このストリームのビデオメディアトラックの現在の寸法を定義する CGSize オブジェクト。videoType-OTStreamVideoType) ストリームがカメラ映像ソースを使うかどうか (OTStreamVideoTypeCamera)、スクリーン共有ビデオソース(OTStreamVideoTypeScreen)、またはカスタム・ビデオ・ソース(OTStreamVideoTypeCustom).
参照 画面共有.
Streamオブジェクトには、ストリームを定義する以下のプロパティがあります:
Connection- Connection)ストリームを公開している接続に対応するConnectionオブジェクト。これをConnectionプロパティを使用して、ストリームがクライアントによって公開されているかどうかを確認します。CreationTime- DateTime) ス ト リ ームの作成時刻の DateTime タ イ ムス タ ンプ。HasAudio- (bool) ストリームに音声があるかどうか。HasVideo- (bool) ストリームがビデオを持っているかどうか。Name- 文字列)ストリームの名前。これはストリームのパブリッシャを初期化する際に設定されます ( パブリッシャー・オブジェクトの初期化).Id- 文字列)ストリームのユニークID。Height- int) ス ト リ ームの高 さ を ピ ク セル単位で指定 し ます。VideoSourceType- VideoSourceType) ス ト リ ームがカ メ ラ ビデオ ソ ース を用いるかど う か。VideoSourceType.StreamVideoTypeCamera)、スクリーン共有ビデオソース(VideoSourceType.StreamVideoTypeScreen)、またはカスタム・ビデオ・ソース(VideoSourceType.StreamVideoTypeCustom).
参照 画面共有.
Width- int) ス ト リ ームの幅を ピ ク セル単位で指定 し ます。
ストリームに関する情報を得るには、以下の関数を呼び出す:
otc_stream_get_connection()- を返します。otc_connectionインスタンスを作成します。このコネクション ID をotc_connectionインスタンスを返します。otc_session_get_connection()関数を使用して、ストリームがクライアントによって公開されているかどうかを確認します。otc_stream_get_creation_time()- ストリームの作成時刻のタイムスタンプを返します。otc_stream_has_audio()- ストリームが現在オーディオを公開しているかどうか。otc_stream_has_video()- ストリームが現在ビデオを公開しているかどうか。otc_stream_has_audio_track()- ストリームにオーディオトラックがあるかどうか。otc_stream_has_video_track()- ストリームにビデオトラックがあるかどうか。otc_stream_get_name()- ストリームの名前を返します。これは、ストリームのパブリッシャを初期化するときに設定されます ( otc_publisher 構造体の初期化とパブリッシャーコールバックの設定).otc_stream_get_id()- ストリームの一意な ID を返します。otc_stream_get_video_height()- ストリームの高さをピクセル単位で指定する。otc_stream_get_video_type()- ストリームがカメラのビデオソースを使用しているかどうか (OTC_STREAM_VIDEO_TYPE_CAMERA)または画面共有ビデオソース(OTC_STREAM_VIDEO_TYPE_SCREEN).otc_stream_get_video_width()- ストリームの幅をピクセル単位で指定する。
ストリームの終了とビデオの無効を検出
ストリームの終了を検出し、クリーンアップやUIの調整を行うことができます。
サブスクライバーのビデオが無効化されると、OTSubscriberオブジェクトは videoDisabled イベントを開催する:
<OTSubscriber
eventHandlers={{
videoDisabled: (event) => {
console.log('stream video disabled -- stream ID:', event.streamId);
// Display a user interface notification.
},
}}/>
メディアルータが加入者のビデオを無効にする場合、加入者に関連するユーザーインターフェイスを調整することができます。
について reason プロパティの videoDisabled イベントオブジェクトは、ビデオが無効になった理由を定義します。以下の値のいずれかを設定する:
-
"PublisherPropertyChanged"- 出版社はビデオの公開を中止した。 -
"QualityChanged"- メディアルーターが、ストリーム品質の変化に基づいて加入者へのビデオ送信を停止した。メディアルータのこの機能は、接続性が低下すると、加入者がビデオストリームを停止する。(加入者は、音声ストリームがある場合は受信を継続する)。
このイベントを送信する前に、加入者のストリームの品質が、ビデオストリームが使用不可 になる危険性があるほど低いレベルまで劣化したとき OTSubscriber オブジェから videoDisableWarning イベントを開催する。
接続性が改善され、再びビデオをサポートするようになった場合 OTSubscriber オブジェクトは videoEnabled イベントが発生し、加入者はビデオの受信を再開する。
を使用するセッションでのみ利用可能です。 メディア・ルーター (メディアモードがルーティングに設定されたセッション)であり、メディアモードがリレーに設定されたセッションではない。
ストリームを公開する際、ストリームの画質が原因でビデオが無効化されるのを防ぐことができます。設定 audioFallbackEnabled への false での properties プロパティを OTPublisher コンポーネントに渡します。
-
"SubscriberPropertyChanged"- に渡されるプロパティ・プロパティで subscribeToVideo を false に設定することで、サブスクライバは動画の購読を開始または停止します。OTSubscriberコンポーネントを使用している。 -
"CodecNotSupported"- コーデックに互換性がないため、ビデオの購読が停止されました。 ビデオコーデック開発者ガイド).
について OTSubscriber オブジェクトのディスパッチ videoEnabled イベントを発生させる:
videoEnabled イベントオブジェクトの reason プロパティは、ビデオが有効になった理由を定義する。以下の値のいずれかを設定する:
-
"PublisherPropertyChanged"- 出版社はビデオの公開を再開した。 -
"QualityChanged"- メディアルーターは、ストリーム品質の変化に基づいて、加入者へのビデオ送信を再開した。メディアルーターのこの機能により、加入者は接続性が低下するとビデオストリームを停止し、ストリーム品質が向上するとビデオストリームを再開する。
この機能は、メディアルーターを使用するセッション(メディアモードがルーティングに設定されたセッション)のみで使用可能であり、メディアモードがリレーに設定されたセッションでは使用できない。
-
"SubscriberPropertyChanged"- 加入者がビデオの購読を開始または停止した。subscribeToVideoをfalseに設定します。 -
"CodecNotSupported"- 加入者ビデオは、互換性のないコーデックからコーデックを変更した後に有効になりました ( ビデオコーデック開発者ガイド).
自分のストリーム以外のストリームがセッションから抜けるとき、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 要素を調整 (または削除) することができます。
他のクライアントから発行されたストリームがセッションから離れると onStreamDropped(Session session, Stream stream) メソッドが呼び出されます。ストリームが削除されると、そのストリームのサブスクライバ・オブジェクトのビューは、そのスーパー ビューから削除されます。
加入者のビデオが無効になっていることを検知する
Vonage ビデオ・メディア・ルーターは、接続性が低下したことを検出すると、加入者へのビデオ送信を停止します。加入者は、音声ストリームがある場合は、引き続き受信します。この場合 onVideoDisabled(加入者, 加入者) メソッドは、Vonage Video Media Router がビデオの送信を停止したときに呼び出されます:
@Override
public void onVideoDisabled(subscriber, reason) {
// Video is disabled for the subscriber
}
について reason パラメータは、加入者がビデオストリーミングを停止した理由を特定する。
Vonage Video Media Router が加入者のビデオを無効にする場合、加入者に関連するユーザーインターフェイスを調整したい場合があります。
について onVideoEnabled(subscriber, reason) メソッドが呼び出されます:
@Override
public void onVideoEnabled(subscriber, reason) {
// Video is resumes for the subscriber
}
について reason パラメータは、加入者のビデオが再開された理由を特定する。
ストリームを公開する際、ストリームの画質が原因で動画が無効化されるのを防ぐことができます。ストリームを公開する前に Session.publish(publisher) メソッドを呼び出す。 setAudioFallbackEnabled(boolean enabled) Publisherオブジェクト(またはPublisherKitオブジェクト)のメソッドに false.
ストリームがセッションを離れると OTSession session(_:streamDestroyed:) メッセージが送信される。ストリームが削除されると、そのストリームの OTSubscriber オブジェクトのビューはそのスーパービューから削除されます。ストリームが自分のクライアントによって発行されていないかどうかを確認し、そのビューをスーパービューから削除します。
func session(_ session: OTSession, streamDestroyed stream: OTStream) {
print("Session streamDestroyed: \(stream.streamId)")
if subscriber?.stream?.streamId == stream.streamId {
subscriber?.view?.removeFromSuperview()
subscriber = nil
}
}
加入者のビデオが無効になっていることを検知する
サブスクライバーのデリゲートは OTSubscriberDelegate subscriberVideoDisabled(_:reason:) 加入者のビデオが無効化されたときのメッセージ:
func subscriberVideoDisabled(_ subscriber: OTSubscriberKit, reason: OTSubscriberVideoEventReason) {
print("subscriber video disabled.")
}
について reason パラメータには、OTSubscriberVideoEventReason 列挙型で定義されている以下の定数のいずれかを設定する:
OTSubscriberVideoEventPublisherPropertyChanged- このビデオイベントは、ストリームのパブリッシャーがビデオストリームを停止したために発生した。OTSubscriberVideoEventQualityChanged- ビデオ・イベントは、ビデオ・ストリームの画質の変化によって発生しました。ストリームの品質は、サブスクライバまたはパブリッシャのネットワーク状 況やCPU使用率によって変化する可能性がある。この理由は、メディアモードが "routed "に設定されているセッションでのみ使用される。(以下を参照のこと。 Vonage ビデオ・メディア・ルーターとメディア・モード.)Vonage Video Media Routerのこの機能は、ビデオストリームの品質が低下したときに加入者がビデオストリームをドロップし、メッセージが送信されます。状況が改善されると、ビデオストリームが再開され、メッセージが送信されます。OTSubscriberDelegate subscriberVideoEnabled(_:reason:)メッセージが送信される。ビデオストリームがドロップされたとき、加入者は、オーディオストリームがあれば、それを受信し続ける。OTSubscriberVideoEventSubscriberPropertyChanged- ビデオイベントは、この加入者のOTSubscriber subscribeToVideo財産である。
ビデオストリームが再開すると OTSubscriberDelegate subscriberVideoEnabled(_:reason:) メッセージが送信される。
ストリームを公開する際、ストリームの画質が原因で動画が無効化されるのを防ぐことができます。ストリームを公開する前に OTSession publish(_:error:) メソッドで audioFallbackEnabled プロパティをfalseに設定する。
について [OTSessionDelegate session:streamCreated:] メッセージは、セッションに新しいストリームが作成されたときに送信される。(ストリームは、クライアント 出版 ストリームをセッションに送る)。その OTStreamオブジェクト にはストリームを定義するプロパティがある。ストリームを定義するプロパティを connection OTStreamオブジェクトの connection OTSessionオブジェクトのプロパティを使用して、そのストリームがクライアントが公開したものであるかどうかを判断します:
- (void)session:(OTSession*)session streamCreated:(OTStream*)stream
{
NSLog(@"session streamCreated (%@)", stream.streamId);
// See the declaration of subscribeToSelf above.
if ([stream.connection.connectionId isEqualToString: session.connection.connectionId]) {
// This is my own stream
} else {
// This is a stream from another client.
}
}
他のクライアントから発行されたストリームがセッションから抜けるとき、Sessionオブジェクトは StreamDropped イベントを開催する:
session.StreamDropped += Session_StreamDropped;
public void Session_StreamDropped(object sender, EventArgs e)
{
// Stream dropped
}
これに渡されるイベント引数オブジェクトは、OpenTok.Session.StreamEventArgs クラスで定義されます。このクラスには Stream プロパティを使用します。比較する Stream オブジェクトを Stream プロパティを使用して、ストリームのサブスクライバを識別します。
加入者のビデオが無効になっていることを検知する
Vonage Video Media Router は、接続性が低下したことを検出すると、加入者へのビデオ送信を停止します。音声ストリームがある場合、加入者は引き続き受信します。Vonage Video Media Router がビデオの送信を停止すると、加入者オブジェクトは VideoDisabled イベントを開催する:
subscriber.VideoDisabled += Subscriber_VideoDisabled;
public void Subscriber_VideoDisabled(object sender)
{
// Display a user interface notification.
}
Vonage Video Media Router が加入者のビデオを無効にする場合、加入者に関連するユーザーインターフェイスを調整したい場合があります。
サブスクライバーオブジェクトは VideoDisabled イベントを発生させる:
subscriber.VideoEnabled += Subscriber_VideoEnabled;
public void Subscriber_VideoEnabled(object sender)
{
// Video resumes for the subscriber.
}
について on_stream_dropped のコールバック関数である。 otc_session_callbacks struct は、他のクライアントのストリームが Vonage Video セッションからドロップされたときに呼び出されます。この構造体は stream この関数に渡されるパラメータは otc_stream 構造体をストリームのを呼び出す。 otc_stream_get_id() メソッドに otc_stream 構造体を使用してストリームIDを取得する。
ストリームのビデオが無効になっていることを検出する
について on_stream_has_video_changed のコールバック関数である。 otc_session_callbacks struct は、他のクライアントのストリームが Vonage Video セッションからドロップされたときに呼び出されます。この構造体は stream この関数に渡されるパラメータは otc_stream 構造体をストリームのを呼び出す。 otc_stream_get_id() メソッドに otc_stream 構造体を使用してストリームIDを取得する。
トラブルシューティング(JavaScript)
サブスクライブエラーと接続性の問題を処理するためのヒント。
トラブルシューティングの一般的な情報については、以下を参照してください。 ビデオ・インスペクター.
エラー処理
購読する方法は1つだけ。 Session.subscribe()-ほとんどのエラーはネットワーク関連です。サブスクライバが接続に失敗した場合、独自のエラーメッセージが表示されますが、明確なメッセージを自分で表示する方が良いでしょう:
session.subscribe(event.stream, 'subscriber', {insertMode: 'append'}, function (err) {
if (err) {
showMessage('Streaming connection failed. This could be due to a restrictive firewall.');
}
});
接続性の喪失
サブスクライバは、接続後に接続を失うことがある。その場合は streamDestroyed イベントが発生する。 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);
subscriber.innerHTML = 'Lost connection. This could be due to your internet connection or because the other party lost their connection.';
event.preventDefault();
}
}
}
});
加入者のイベント処理とランタイム調整(オーディオブロック、ビデオ無効、統計)については、以下を参照してください。 購読するマネジメント&イベント.
セッションサブスクライブの再試行の実装
次のような場合、一時的な購読の失敗が発生することがあります。 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() 再試行の前に |
必須 — パブリッシャーとは異なり、サブスクライバーインスタンスは再利用できません |