開発ガイド

TypeScript で AI Noise Canceller を利用する際の注意点

TypeScript を用いた開発に AI Noise Canceller を利用する場合、連携しようとする JavaScript SDK のバージョンによって型の互換性に伴うエラーや警告が表示される場合がございます。 対処が必要な場合は、AI Noise Canceller もしくは JavaScript SDK のどちらかを、他方に適合するバージョンへ更新してご利用ください。 なお、AI Noise Canceller と連携可能な JavaScript SDK のバージョンは、リリースノートからご確認いただけます。

未対応ブラウザ利用時のハンドリング

AI Noise Canceller は Chrome / Edge / Safari で動作します。
それ以外のブラウザはサポートしておらず、動作保証はありません。そのため、動作するかどうかは、isSupported メソッドを使用して判定してください。

if (SkyWayNoiseCanceller.isSupported() === false) { console.warn("SkyWay Noise Canceller is not supported"); return; }

エラーハンドリング

AI Noise Canceller は、短時間のネットワーク切断時には自動的に再接続処理を行います。しかし、長時間のネットワーク切断など回復不可能なエラーが発生した場合には、onFatalError イベントが発火します。このイベントが発火した場合、一時的に AI Noise Canceller が利用できなくなる可能性が高いため、元の Audio Stream を利用するなど、アプリケーション側での対応が必要です。

// 元のStream const audio = await SkyWayStreamFactory.createMicrophoneAudioStream({ noiseSuppression: false, }); noiseCanceller.onFatalError((event: CustomEvent<SkyWayNCError>) => { const error = event.detail; // connect中に発生するのはProcessErrorのみ if (error.type === "ProcessError") { myAudioPublication.replaceStream(audio, { releaseOldStream: false, }); } });

ブラウザのノイズ抑制機能の無効化

getUserMedia()SkyWayStreamFactory.createMicrophoneAudioStream を使用して Audio Stream を取得する場合、 noiseSuppression を設定できます。 しかし、AI Noise Canceller を利用する際は音声ノイズを抑制する機能が競合するため、 noiseSuppression の設定を false にすることを推奨します。

const audio = await SkyWayStreamFactory.createMicrophoneAudioStream({ noiseSuppression: false, // AI Noise Cancellerと競合しないようにfalseに設定 });

また、開発中に自身で動作確認するようなユースケースで Publish した音声を Subscribe してループバックする場合は、echoCancellationfalse に設定すると音声が聞き取りやすくなります。

const audio = await SkyWayStreamFactory.createMicrophoneAudioStream({ echoCancellation: false, // 1 人で動作確認する際に聞き取りやすくするための設定であり、実環境では true を推奨 noiseSuppression: false, });

課金対象期間について

AI Noise Canceller の課金対象期間は、connect を呼び出してから dispose を呼び出すまでの期間です。

Billing

AI Noise Canceller 自体はミュートの API を提供していないため、AI Noise Canceller の処理を一時的に停止して課金を止める場合は、必ず以下のように dispose を呼び出してリソースを解放してください。 なお、JavaScript SDK のミュートと併用することは可能ですが、ミュート中も課金は継続します。実装方法は次のミュートと併用する場合を参照してください。

// replaceStreamで適用前のAudio Streamにreplaceする myAudioPublication.replaceStream(audio, { releaseOldStream: false, }); noiseCanceller.dispose();

また、onFatalError イベントが発火した際は内部で自動的に dispose が呼び出され課金集計処理が止まります。

ミュートと併用する場合

前述のとおり AI Noise Canceller 自体はミュートの API を提供していませんが、JavaScript SDK の Publication.enable() / Publication.disable() によるミュートと併用できます。 ただし、どの Publication をミュートするかによって挙動が変わるため、以下のとおり実装してください。 なお、enable / disable 自体の仕様は、クックブックのミュートの実装を参照してください。

ミュート操作は加工後の Audio Stream の Publication に対して行う

connect の戻り値である加工後の Audio Stream を Publish し、その Publication に対して disable / enable を呼び出してください。 こうしておけば、アンミュート後もノイズ抑制が効いた状態で音声が復帰します。 初期化から Publish までの手順は、クイックスタートを参照してください。

// audio はミュートしていない状態のマイクの Audio Stream const processedAudio = await noiseCanceller.connect(audio); const publication = await person.publish(processedAudio); // ミュート / アンミュートは加工後の Audio Stream の Publication に対して行う await publication.disable(); await publication.enable(); // ノイズ抑制が効いた状態で音声が復帰する

replaceStream で Stream を差し替えた場合も、Publication の状態を参照してアプリケーション側のミュート状態を同期してください。

await publication.disable(); publication.replaceStream(anotherProcessedAudio); const isMuted = publication.state === "disabled"; // true

注意事項

ミュート中に connect を呼び出す

ミュート中の LocalAudioStream のトラックは、JavaScript SDK の内部で無音のトラックに差し替えられています。 connect は呼び出した時点のトラックを保持し続けるため、無音のトラックを掴んだまま固定されます。

const audioPublication = await person.publish(audio); // 元のマイクの Audio Stream を Publish await audioPublication.disable(); // ミュートする const processedAudio = await noiseCanceller.connect(audio); // NG: 無音のトラックを掴んだまま固定される await audioPublication.enable(); // ミュートを解除しても、加工後の音声は復帰しない

マイクの切り替えや onFatalError からの復旧で作り直す場合は、enable でミュートを解除してから connect するか、新しく取得した Audio Stream に対して connect してください。

正しい実装は、connect の前にミュートを解除し、加工後の Publication をミュートします。

await audioPublication.enable(); // connect の前にミュートを解除する const processedAudio = await noiseCanceller.connect(audio); const processedPublication = await person.publish(processedAudio); await processedPublication.disable(); // ミュートは加工後の Publication に対して行う

元のマイクの Audio Stream 側を disable する

AI Noise Canceller は connect に渡された Audio Stream のトラックを保持し続けるため、SkyWayStreamFactory.createMicrophoneAudioStreamstopTrackWhenDisabled に応じて次のようになります。

  • デフォルト(true): 加工後の音声は無音になるが、アンミュートしても音声が復帰しない
  • false: ミュートにならず音声が送信され続ける

いずれも意図どおりには動かないため、このオプションの値では解決できません。加工後の Audio Stream の Publication をミュートしてください。

const audioPublication = await person.publish(audio); // 元のマイクの Audio Stream を Publish const processedAudio = await noiseCanceller.connect(audio); const processedPublication = await person.publish(processedAudio); await audioPublication.disable(); // NG: ミュートするのは processedPublication 側

次のように、加工後の Publication をミュートしてください。

await processedPublication.disable(); // OK: 加工後の Audio Stream をミュートする await processedPublication.enable();

元のマイクの Audio Stream を Publish したあとに、既定値(stopTrackWhenDisabled: true)で元の Stream をミュートしてから replaceStream で加工後の Audio Stream に差し替えると、差し替え後も加工後の音声が復帰しません。

const audioPublication = await person.publish(audio); // 元のマイクの Audio Stream を Publish const processedAudio = await noiseCanceller.connect(audio); await audioPublication.disable(); // NG: 差し替え前のミュートは元のマイクの Audio Stream への操作になる audioPublication.replaceStream(processedAudio, { releaseOldStream: false }); // 元の audio を解放しない await audioPublication.enable(); // stopTrackWhenDisabled: false なら復帰、true(既定値)では復帰しない

ここで releaseOldStream: false は差し替え前の audio を解放しないための指定です。enable 後に音声が復帰するかどうかは、元の Audio Stream の stopTrackWhenDisabled の値によって決まります。ミュート操作は加工後の Audio Stream の Publication に対して行ってください。

ミュートは replaceStream で差し替えたあとに呼び出してください。差し替え後の disable / enable は、加工後の Audio Stream への操作になります。

次のように、差し替え後の Publication をミュートしてください。

audioPublication.replaceStream(processedAudio, { releaseOldStream: false }); await audioPublication.disable(); // OK: 差し替え後の Publication をミュートする await audioPublication.enable();

破棄済みの Audio Stream を connect に渡す

replaceStream はデフォルト(releaseOldStream: true)で差し替え前の Stream を破棄します。破棄済みの Stream を新しい AI Noise Canceller の connect に渡してはいけません。

audioPublication.replaceStream(processedAudio); // audio が破棄される await newNoiseCanceller.connect(audio); // NG: 破棄済みの Stream

次のように、取得し直した Audio Stream を connect に渡してください。

const newAudio = await SkyWayStreamFactory.createMicrophoneAudioStream({ noiseSuppression: false, }); const newProcessedAudio = await newNoiseCanceller.connect(newAudio); // OK

SkyWayStreamFactory.createMicrophoneAudioStream で Audio Stream を取得し直してから connect に渡してください。 再開までの流れは、後述のミュートの代わりに dispose するのコード例を参照してください。

ミュート中の挙動に関する注意点

  • ミュート中も AI Noise Canceller は動作し続けるため、前述の課金対象期間についてのとおり課金が継続します。
  • ミュートするのは加工後の Audio Stream の Publication であり、元のマイクの Audio Stream のトラックは停止しません。そのため、AI Noise Canceller を使わない場合と異なり、ミュート中もマイクのデバイスは解放されず、ブラウザや OS のマイク使用中の表示は点灯したままになります。

いずれも解消したい場合は、ミュートではなく次の手順で停止してください。

ミュートの代わりに dispose する

課金の停止とマイクのデバイスの解放まで行いたい場合は、ミュートではなく dispose してください。 以下の順に呼び出します。dispose の前に disable を呼び出さないと、Publication が enabled のまま残り、相手側にミュートが通知されません。

await publication.disable(); // 相手側にミュートを通知する noiseCanceller.dispose(); // 課金を止める audio.release(); // マイクのデバイスを解放する

再開するときは、Audio Stream の取得と AI Noise Canceller の初期化からやり直します。 dispose した AI Noise Canceller と release した Audio Stream はどちらも再利用できないため、enable だけでは音声は復帰しません。

// マイクの Audio Stream を取得し直す const newAudio = await SkyWayStreamFactory.createMicrophoneAudioStream({ noiseSuppression: false, }); // AI Noise Canceller も新しいインスタンスを初期化する const newNoiseCanceller = new SkyWayNoiseCanceller(context); newNoiseCanceller.onReady(async () => { const newProcessedAudio = await newNoiseCanceller.connect(newAudio); publication.replaceStream(newProcessedAudio); await publication.enable(); // ミュートを解除して送信を再開する // 次回の停止処理では、再開後のリソースを解放する audio = newAudio; noiseCanceller = newNoiseCanceller; }); newNoiseCanceller.init();

再開後に作成した Audio Stream と AI Noise Canceller を、以降の停止処理で使用する現在のリソースとして管理してください。

マイクの切り替え

現在 Stream の変更機能は提供しておりません。 マイクの切り替えに伴う Stream の変更が必要な場合は、新たにインスタンスを生成してご利用ください。

// インスタンス化と初期化を行う関数 const setupNoiseCanceller = async (context: SkyWayContext, audio: LocalAudioStream): Promise< [noiseCanceller: SkyWayNoiseCanceller, processedAudio: LocalAudioStream] > => { const noiseCanceller = new SkyWayNoiseCanceller(context); return new Promise((resolve) => { noiseCanceller.onReady(async () => { const processedAudio = await noiseCanceller.connect(audio); resolve([noiseCanceller, processedAudio]); }); noiseCanceller.onFatalError(...); noiseCanceller.init(); }); }; const devices = await SkyWayStreamFactory.enumerateInputAudioDevices(); // 元のマイクの音声を Publish let audio = await SkyWayStreamFactory.createMicrophoneAudioStream({ deviceId: devices[0].id, noiseSuppression: false, }); let [noiseCanceller, processedAudio] = await setupNoiseCanceller(context, audio); const publication = await person.publish(processedAudio); // 別のマイクへの切り替え const anotherAudio = await SkyWayStreamFactory.createMicrophoneAudioStream({ deviceId: devices[1].id, noiseSuppression: false, }); const [anotherNoiseCanceller, anotherProcessedAudio] = await setupNoiseCanceller(context, anotherAudio); // 新たに SkyWayNoiseCanceller を初期化する publication.replaceStream(anotherProcessedAudio); // 元の SkyWayNoiseCanceller を破棄する noiseCanceller.dispose(); audio.release(); // 元のマイクのデバイスを解放する noiseCanceller = anotherNoiseCanceller; audio = anotherAudio;

ノイズ抑制強度(strength)の調整

strength はノイズ抑制の強度を設定するための値です。インスタンス生成時に設定できるほか、changeStrength メソッドを使用して任意のタイミングでの変更も可能です。

// インスタンス生成時に設定する場合 noiseCanceller = new SkyWayNoiseCanceller(context, { strength: 80 }); // changeStrengthで変更する場合 const strength = 80; noiseCanceller.changeStrength(strength);

何も指定しなかった場合は 100 が設定されます。

モデルタイプについて

モデルタイプは small , medium , large の 3 種類があり、インスタンス生成時に設定できます。 何も指定しなかった場合は small が設定されます。 small が最も処理負荷を抑えられるため、スマートフォンなどを含む様々なデバイスで活用されるユースケースでは small の利用を推奨します。 モデルタイプを変更したい場合は、インスタンスを dispose して新しいインスタンスを作成してください。

// 初期化時にモデルを'medium'に設定 noiseCanceller = new SkyWayNoiseCanceller(context, { modelType: "medium" });

AI Noise Canceller 利用時の SkyWay Auth Token に関する注意

AI Noise Canceller は、version プロパティが 12 、 未指定となっている旧バージョンの SkyWay Auth Token ではご利用いただけません。旧バージョンの SkyWay Auth Token をご利用中の方は、 version 3 へ移行してください。なお、SkyWay Auth Token version 3 の詳しい仕様を知りたい方は、SkyWay Auth Token(各種SDK用)のページをご参照ください。

ログの設定

SkyWayNoiseCanceller のインスタンスを生成する際に、出力されるログのログレベルを設定できます。

noiseCanceller = new SkyWayNoiseCanceller(context, { logLevel: 'debug', });

設定可能なログレベルは、APIリファレンスを参照してください。 なお、ログレベルを指定しなかった場合はerrorに設定されます。

アプリケーション開発時は、不具合の調査やテクニカルサポートとのやり取りを円滑に行うために、ログレベルを debug に設定することをおすすめします。 アプリケーションをプロダクションで運用する際は、ログレベルを error に設定することをおすすめします。

開発用リポジトリでの利用

以下のようなユースケースにより開発用のリポジトリで本ライブラリを利用したい場合、インストール用スクリプトを活用したワークフローをご使用ください。

  • 公開リポジトリで開発しているソフトウェアで利用したい場合
  • 常に最新版のライブラリを用いてテストを実行したい場合