Chromeで、WebRTC の疑似NW環境テストを簡単に実現する方法

# これは何？

WebRTC を使った開発や製品のテストをする際に、NW環境（帯域とかパケットロスとか）のテストをやりたいことは、結構あると思います。

この手のテストは、結構めんどくさくって、Wifi をわざと混雑させてそういう環境を作るとか、間にNWエミュレータを入れるとか、かなり手間です。

また、そういった環境でテストをしようとすると、 html や js のダウンロードもままならなくなってしまい、テストにものすごく時間がかかってしまうことも・・・・エンジニア泣かせ

しかしここで朗報、 Chrome の起動オプションで、 **WebRTC通信だけ** パケロスとかを擬似的に発生させることが簡単にできます。

このポストでは、その方法について紹介したいと思います。

# パケットロスの疑似生成のやり方

## WebRTC受信だけパケロスを起こす方法

まず、WebRTC の受信だけパケロスを起こす方法です。やり方は簡単で(MacOS の場合を、例として記載)、

```
% open -a Google\ Chrome --args --force-fieldtrials=WebRTCFakeNetworkReceiveLossPercent/10/
```

と、 `--force-fieldtrials=WebRTCFakeNetworkReceiveLossPercent/10/` のコマンドラインオプションをつけて Chrome を起動するだけです。（最後の `10` のところが、パケロスの %（パーセント）を意味します）

注意点としては、同一端末内の P2P では働かないっぽいので、P2P 通信をテストするのであれば、必ず別の端末でテストするようにしてください（SFUであれば、同一端末内テストは大丈夫）。

例えば、 SkyWay の SFU サンプル ( https://example.webrtc.ecl.ntt.com/room/index.html#sfu ) で 10% ロスでテストすると、筆者の環境では、受信側でフレームレートが落ちる現象が確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83466/340839dc-405d-ebce-1509-f7cc4a82dd18.png)

上図が、そのスクリーンショットです。

* 左側が受信時 10% パケロスをかけた Chrome
* 右側が普通に動かした Firefox

となっていて、Firefox の小さい画面が送信映像、Chromeの大きい画面が受信映像に該当するのですが、フレームがあっていないことが分かると思います。（逆方向の Chrome送信 -> Firefox受信についてはパケロスがおきないため、ちゃんとフレームがあっていることが分かるかなと思います）

## WebRTC の送信／受信ともパケロスを起こす方法

以下のように、起動オプションに `WebRTCFakeNetworkSendLossPercent/10/` を追加します。

```
open -a Google\ Chrome --args --force-fieldtrials=WebRTCFakeNetworkReceiveLossPercent/10/WebRTCFakeNetworkSendLossPercent/10/
```

末尾の `10` は、受信と同様に、送信パケロスの %(パーセント) となっています。

これで、受信時と同様に SkyWay の SFU サンプルでテストしてみると、受信方向とは異なり、送信の場合は、解像度が下がる現象が確認されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83466/0d4f09af-0335-449b-9d04-53cc220ccace.png)

上に、その際のスクリーンショットを示しました。スクショなので、かなり分かりづらいですが、 Chromeの小さい画面（送信映像) => Firefoxの大きい画面（受信映像）で、解像度が下がっています。

## ここまでのまとめ

起動オプションの指定方法を変えるだけで、送信と受信で、映像に与える影響が変わるとか、色んなことが簡単に分かります。この辺の影響の出方やその具合は、今回は SkyWay の SFU の場合で例示しましたが、製品／サービスが異なれば変わってきます。

WebRTC関連の開発時テストや製品評価の際、非常に便利だと思います。今回のポストでは、その表示イメージを掲載しましたが、 chrome://webrtc-internals/ や、 [getStats()](https://www.w3.org/TR/webrtc-stats/) で得られる統計情報と併せて分析すると、更に様々な特性や傾向が分かると思います。

# その他の設定項目

ここまで、パケロスについて、その指定方法を紹介しましたが、 Chrome では以下の項目が WebRTC の疑似NW環境として設定できます。

## 送信時

* WebRTCFakeNetworkSendDelayMs
    * 送信遅延をミリ秒で指定（初期値：　0）
* WebRTCFakeNetworkSendDelayStdDevMs
    * 送信遅延の標準偏差をミリ秒で指定（初期値： 0）
* WebRTCFakeNetworkSendQueueLength
    * 送信キューのパケット長（初期値: 0）
* WebRTCFakeNetworkSendCapacityKbps
    * 送信時のNW送信可能な最大ビットレートを　kbps 単位で指定（初期値： 0）
* WebRTCFakeNetworkSendLossPercent
    * 送信時のパケットロス（ランダムロス）を、％で指定（初期値： 0）
* WebRTCFakeNetworkSendAllowReordering
    * 送信時にパケットのリオーダリングを行うフラグ。 `0` or `1` で指定（初期値: 0）
* WebRTCFakeNetworkSendAvgBurstLossLength
    * 送信時のパケットロスの平均バースト長を指定。パケット長単位（初期値： -1）

## 受信時

* WebRTCFakeNetworkReceiveDelayMs
    * 受信遅延をミリ秒で指定（初期値：　0）
* WebRTCFakeNetworkReceiveDelayStdDevMs
    * 受信遅延の標準偏差をミリ秒で指定（初期値： 0）
* WebRTCFakeNetworkReceiveQueueLength
    * 受信キューのパケット長（初期値: 0）
* WebRTCFakeNetworkReceiveCapacityKbps
    * 受信時のNW送信可能な最大ビットレートを　kbps 単位で指定（初期値： 0）
* WebRTCFakeNetworkReceiveLossPercent
    * 受信時のパケットロス（ランダムロス）を、％で指定（初期値： 0）
* WebRTCFakeNetworkReceiveAllowReordering
    * 受信時にパケットのリオーダリングを行うフラグ。 `0` or `1` で指定（初期値: 0）
* WebRTCFakeNetworkReceiveAvgBurstLossLength
    * 受信時のパケットロスの平均バースト長を指定。パケット長単位（初期値： -1）

# 最後に

ここで、紹介した方法は、 Google Chrome のサポート／マニュアルページ等には一切掲載されておらず、Chromium のソースコード該当部分
* https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/call/call_factory.cc;l=44?q=webrtcfakenetwork&ss=chromium
* https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/test/simulated_network.h;drc=d74c336647586eccbd98975a0956bda1cf5de25f;l=52

から分析し、記載したものになります。筆者は Google の人では無いので、こんなことを書くのもあれですが、このオプションを利用することによる不具合等については、一切のサポート外と思われますので、利用者の責任で利用されるようお願いします。

また、上述の通り、本ポストで記載した設定項目や初期値は、筆者が Chromium のソースコードから分析したものを掲載しており、また、各項目全てに対して細かいテストも行っていません。ですので、記載内容に関する誤りや、「実際に使ってみたらこうだったよ！」とかありましたら、是非コメントで頂けるとありがたいです。