出版する診断学
このガイドでは、パブリッシャーの診断を収集し、一般的な問題を解決する方法を説明します。
パブリッシャーのストリームに関する統計情報の取得
Vonage Video SDKは、ほとんどのユースケースで推奨される高レベルの統計APIを通じて、詳細なストリーム品質メトリクスを公開します。このAPIは、音声、ビデオ、ネットワーク、および送信者側の統計を、ピア接続の遷移をまたいで安定したまま、統一されたセッション認識形式で提供します。高度なデバッグのために、SDKは未処理のピア接続データを反映する生のWebRTC統計レポートへのアクセスも提供します。
参照 クライアント観測可能性開発者ガイド をご覧ください。
テストストリーム
テストストリームを公開し、そのオーディオとビデオの統計情報を確認することで、接続でサポートされるストリームのタイプ(高解像度やオーディオのみなど)を判断できます。
ローカルクライアントがパブリッシュしたストリームの統計情報を取得するには、メディアルーターを使用するセッション(メディアモードがroutedに設定されたセッション)を使用する必要があります。 testNetwork プロパティ true での options オブジェクトに渡します。 Session.subscribe() メソッドを使用します。その後 getStats() メソッドを使用して、公開するストリームのオーディオとビデオの統計情報を取得します。
を使用することができます。 SubscriberKit.setAudioStatsListener(AudioStatsListenerリスナー) そして SubscriberKit.setVideoStatsListener(VideoStatsListener listener) メソッドを使用して、公開するストリームのオーディオとビデオの統計情報を取得します。
参照 本題 をご覧ください。
を使用することができます。 networkStatsDelegate メソッドを使用して、公開するストリームのオーディオとビデオの統計情報を取得します。
について Vonage-Video-API-Network-テストサンプル レポには、セッションに公開する前にテストストリームの統計情報を使用する方法を示すサンプルコードが含まれています。
を使用することができます。 networkStatsDelegate メソッドを使用して、公開するストリームのオーディオとビデオの統計情報を取得します。
について Vonage-Video-API-Network-テストサンプル レポには、セッションに公開する前にテストストリームの統計情報を使用する方法を示すサンプルコードが含まれています。
その後、ストリームを購読して Subscriber.AudioStatsUpdated そして Subscriber.VideoStatsUpdated イベントを使用して、公開したストリームのオーディオとビデオの統計情報を取得できます。
出版時のベストプラクティス
このセクションでは、ストリームをうまく公開するためのヒントを紹介します。
デバイスへのアクセスを許可する
カメラとマイクへのアクセスを許可するよう求められることをユーザーに知らせるのがベストプラクティスです。
公開に失敗するのは、ユーザーが "拒否 "ボタンをクリックしたり、"許可 "ボタンをまったくクリックしなかったりした結果です。私たちは、ユーザーをこのプロセスに導くために必要なすべてのイベントを提供します:
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にも設定できます。フレームレートを下げると、必要な帯域幅を減らすことができます。解像度が低い動画は、フレームレートを低くしても、ユーザーにはそれほど違いが感じられません。そのため、低解像度を使用する場合は、低フレームレートの使用も検討するとよいでしょう。
トラブルシューティング
このセクションのヒントに従って、公開時の接続性の問題を回避してください。トラブルシューティングの一般的な情報については、「デバッグ - 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接続を許可しない非常に制限されたネットワーク接続を使用している場合、Publisherは接続に失敗し、Publisher要素にクルクル回る車輪が表示されます。このエラーには 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.');
}
}
});
セッション公開の再試行の実装
Video API JS SDK では、特にモバイルブラウザにおいて、一時的な公開失敗が既知の繰り返し発生する現象として確認されています。この現象は、 session.publish() 失敗した場合、SDKはコンプリートハンドラのコールバックを通じてエラーを返します。推奨されるアプローチは、試行の間に遅延を設けたアプリケーションレベルのリトライロジックを実装することです。
注: 以下の機能に対するリトライ機能の組み込みサポート session.publish() これはSDKのロードマップに含まれています。それがリリースされるまでは、ご自身で実装する必要があります。
出版の失敗が起こる理由
一時的な公開失敗の最も一般的な根本原因は、以下の通りです:
- StreamCreateRequest のタイムアウト(エラー 1500):
OT.Publisher妥当な時間内に公開できなかった — 通常、ICE/SDPネゴシエーション中のメディア停止イベントやネットワーク遅延が原因である。 mediaStopped公開フロー中のイベント、そこでメディアデバイスへのアクセスが中断される可能性があります。- 適切なクリーンアップを行わないままPublisherオブジェクトを再利用すること — 異なる制約で初期化されたパブリッシャーインスタンスを、呼び出さずに再利用する
unpublishそして、再初期化を行います。 OT_NOT_CONNECTED— セッションが完全に接続される前に公開しようとしています。OT_USER_MEDIA_ACCESS_DENIED— デバイスへのアクセスに関する問題(再試行不可)。
回復可能なエラーと回復不可能なエラー
すべてではない session.publish() エラーはすべて同じというわけではありません。リトライロジックを実装する前に、エラーを正しく分類することが不可欠です。回復不可能なエラーに対してリトライを行うと、時間を浪費し、ユーザー体験を損なうだけでなく、別の対応を必要とする真の障害を見逃してしまう恐れがあります。
注: エラーコード 1500 分類メカニズムとしては非推奨となっています。常に error.name このプロパティは、特定の障害シナリオに対応しているため、プログラムからエラーを特定するために使用できます。
回復不可能なエラー — 再試行しないでください
これらのエラーは、プログラマーのミス、厳しい権限の制約、または無効な呼び出しコンテキストに起因するものです。再試行しても解決しません。代わりに、ユーザーにわかりやすいメッセージを表示するか、アプリケーションのロジックを修正してください。
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 または publishVideo は true を呼び出す前に 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の内部リトライ機能(v2.35で導入)の一環として、パブリッシュの試行が失敗した場合、SDKは内部的にストリームを破棄するようになりました。これにより、 streamDestroyed イベント reason: reset パブリッシャーで発火します。これは想定された動作であり、 違う パブリッシャーの再初期化が必要になる場合がありますが、同じインスタンスで再試行できます。
以下のコマンドでパブリッシャーを再初期化しなければならないのは、次の場合のみです。 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 internally by the SDK
// during a failed publish attempt — this does NOT require reinitializing the publisher
publisher.on('streamDestroyed', (event) => {
if (event.reason === 'reset') {
// Expected during retry flow — 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イベントおよびレイズaudioAcquisitionProblemとmethod: trackEndedEvent. - 統計に基づく検出(音声バイトの流通なし): SDKは、ピア接続が確立された後、パブリッシャーの統計情報を継続的に監視します。接続が「接続済み」状態になってから30秒以内にオーディオバイトが検出されない場合、
audioAcquisitionProblemは、以下の方法で呼び出されますmethod: getStats.
注: この事象が必ずしも致命的な障害を示すわけではありません。セッションによっては、音声が自然に回復することもあります(そして audioAcquisitionProblemResolved が呼び出される);一方、他のケースでは、オーディオストリームが回復せず、下流のサブスクライバーは最終的にタイムアウトとなる可能性があります。
イベント
これらのイベントは、パブリッシャーインスタンスで発生します:
audioAcquisitionProblem— SDKが、パブリッシャーによる音声送信が停止したことを検出した場合(パブリッシャーの統計情報に基づいて)、このイベントが発生します。これは必ずしもストリームが失敗することを意味するわけではありませんが、音声のキャプチャが中断されたことを示す指標となります。audioAcquisitionProblemResolved— 以前の…の後、音声伝送が回復した際に発火するaudioAcquisitionProblem. このイベントが発生しても、是正措置は必要ありません。
注: オーディオ取得のチェックはパブリッシャーの統計情報に基づいているため、実際のオーディオ中断とイベントが発生するまでの間に、わずかな遅延が生じる場合があります。
推奨されるリカバリパターン
受信時にショートタイマーを開始する 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これにより、下流での不具合を防ぐことができます。