FlutterでWebRTCを使ったビデオ通話アプリを試してみる

2022-06-03

はじめに

副業をやることになりました。 一年程前にせっせこ作って納品した人からオカワリ良いっすかと相談があった次第です。

直接依頼してもらうのは初めての経験で戸惑いながらも嬉しかったので了承した矢先、 本業の方で、大炎上スマッシュブラザーズへの招待状を受け取ってしまいました。 チャレンジャーです。 そして、連日8時~22時の労働が始まったのです。強く生きましょう。

さて、副業に手を出してしまった以上完遂する義務があるわけで、銭を貰った以上は働くのが人としての道理だと考えています。

ワイは、Twitterでエッチな画像ばっかRTしてますがこう見えて2児のパパなので子供たちの育児ものしかかってきます。

本業を鎮火し、副業で作るプログラムを無事納品しつつ、家庭平和を守ることが出来るのか!! おそらく全部か、一部を落とすのが最有力。 ごまかしを入れて乗り越えるのが次点ですかね。

何事も無く全て丸く収まることを切に願います。

思うところ

実際、たまにこうやって小銭欲しさに副業してるわけだけど、コンスタントに続けてる人は人間じゃないんだよ。 政府は、副業を解禁して行こうと進めていますが本業だけで生活出来るような体制を整えるのが一番いいと思います。大学まで教育費無償化とかそんなのやってくれたら貯蓄に回す額が減らせるので家計はホント助かるんですけどね…世知辛い。

あと、副業も然りですし、投資(増える前提)を政府が推し進めるのも最近不思議に思っています。必ず増えるもの見たいなトーンで話されることが多く、増えることを前提とした内容で話されているのが不思議でならんのです。

政府という巨大な力にボヤいても生活は楽にならないので、貧乏人はせっせとアプリ作っていきましょう。

ざっくり方針

前提条件としてざっくりとこれだけあります。

  • Android,iOS,Windowsで動かしたい
  • 開発費はできる限り抑えたい
  • 速度が出る動画配信サービスを作りたい
  • 動画配信は1対1で良い。

このような前提条件のもと検討しましたが、Flutterを使ったWebRTCを試してみるのが良いかと考えてます。 P2Pと言いつつも、繋ぐためのServerを間に噛ませる必要があり、本番環境でこのの部分をどうやって作るのかが課題となりそうです。

Flutter + WebRTCを使ってみる。

Sampleがあるものはとりあえず動かして見て弄るのが理解するにはちょうど良いかと。 githubにサンプルコードとしておいてくれている先人がいますので肩を貸していただきます。

今回のソフトの構成はこんなイメージです。

厳密ではない上に怪しいですが、ざっくりとした解釈の上動かして理解していきましょう。 開発用PC上に、サーバを立てたうえで、Windows applicationと、Android Emulatorを繋いでカメラ画像を配信するサンプルを動かします。

Flutter Server

flutter-webrtc-server

git clone https://github.com/flutter-webrtc/flutter-webrtc-server.git
cd flutter-webrtc-server
mkcert -key-file configs/certs/key.pem -cert-file configs/certs/cert.pem  localhost 127.0.0.1 ::1 0.0.0.0
go run cmd/server/main.go

これでサーバが立ち上がれば成功です。

mkcertが入っていない場合

もしmkcertが入っていない場合はchocolateから入れることができます。 Linuxでいうところのapt、Macでいうところのbrewというところでしょうか。 chocolatey

choco install mkcert

mkcretのインストールについてはこの記事を参考にしました。 Windows10にmkcertをインストールする

Flutter Client

WebRTCを調べると一番最初に出てくるのがこちらです。

flutter-webrtc-demo

git clone https://github.com/cloudwebrtc/flutter-webrtc-demo
cd flutter-webrtc-demo
flutter packages get
flutter run

実行結果

上手く起動するとこのような画面になります。

P2P Call Sampleをタップして、接続先サーバを指定して実行します。

Windows Applicationなどで動かす場合は下記の通りです

localhost

Android Emulatorの場合はlocalhostの変わりにこうします。

10.0.2.2

一台目を接続した状態ですとこのような画面になります。

このサンプルでは2台以上をServerに繋いで動作させる必要があるため、繋いでいきます。

2台目のアプリケーションの実行

Androidで動かしても、Windows Applicationで動かしてもなんでも良いですが… スマホ間通信を前提にしているのでEmulatorを立ち上げます。

PC上に2台のAndroid Emulatorが動いてるような状況です。

Flutte-webrtc-demoのフォルダを別のTerminalで開いて下記を実行します。

flutter run
Multiple devices found:
Android SDK built for x86 (mobile) • emulator-5554 • android-x86    • Android 7.0 (API 24) (emulator)
Android SDK built for x86 (mobile) • emulator-5556 • android-x86    • Android 11 (API 30) (emulator)
Windows (desktop)                  • windows       • windows-x64    • Microsoft Windows [Version 10.0.25126.1000]
Chrome (web)                       • chrome        • web-javascript • Google Chrome 102.0.5005.63
Edge (web)                         • edge          • web-javascript • Microsoft Edge 101.0.1210.53
[1]: Android SDK built for x86 (emulator-5554)
[2]: Android SDK built for x86 (emulator-5556)
[3]: Windows (windows)
[4]: Chrome (chrome)
[5]: Edge (edge)
Please choose one (To quit, press "q/Q"):

Android Emulatorが複数立ち上がっているとどれに対してアプリを流すかの設定が出ます。 正直、知りませんでした。

二台立ち上がったらこんな感じになると思います。 P2P Call Sampleを呼び出します。

接続します。

接続できたらこのような画面になります。

Video callボタンを押して、接続先デバイスから承認ボタンを押します。

繋げた結果このような画面になります。 Android Emulatorのカメラにはなぜかサボテンダーが居ますので、そこそこ動いてそうな感触です。

AndroidとAndroidでやった以外にもAndroidとWindows Applicationの組み合わせでも動かしてみました。

Webカメラの映像が配信されていることが確認できましたね。

エラー祭り

これを動かすに当たって色んなエラーに出くわしたので解決策を残しておきます。

One or more plugins require a higher Android SDK version.

よく出くわすタイプのエラーです。解決方法をおいておきます。

flutter-webrtc-demo\android\app\build.gradle

を編集します。編集箇所は、ログにあるようにcompaileSdkVersionです。

Using hardware rendering with device Android SDK built for x86. If you notice graphics artifacts, consider enabling software rendering with "--enable-software-rendering".
Launching lib\main.dart on Android SDK built for x86 in debug mode...
I/flutter ( 4192): Received data: {}
Warning: The plugin flutter_webrtc requires Android SDK version 31.
For more information about build configuration, see https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
Warning: The plugin path_provider_android requires Android SDK version 31.
For more information about build configuration, see https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
Warning: The plugin shared_preferences_android requires Android SDK version 31.
For more information about build configuration, see https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
One or more plugins require a higher Android SDK version.
Fix this issue by adding the following to C:\src\Flutter\flutter-webrtc-demo\android\app\build.gradle:
android {
  compileSdkVersion 31
  ...
}

Warning: Mapping new ns http://schemas.android.com/repository/android/common/02 to old ns http://schemas.android.com/repository/android/common/01
Warning: Mapping new ns http://schemas.android.com/repository/android/generic/02 to old ns http://schemas.android.com/repository/android/generic/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/02 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/03 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/02 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/03 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/03 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/02 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01

build.gradleのファイルを眺めるとandroid{}の中にcompilieSdkVersionがありますので、この数値をログの値に書き換えます。

apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
    compileSdkVersion 31

    lintOptions {
        disable 'InvalidPackage'
    }

これでビルドが進めることができるはずです。

No version of NDK matched the requested version 21.0.6113669. Versions available locally: 24.0.8215888

この手のエラーが出たときに困った経験がある方いらっしゃいますか。

flutter run
Using hardware rendering with device Android SDK built for x86. If you notice graphics artifacts, consider enabling software rendering with "--enable-software-rendering".
Launching lib\main.dart on Android SDK built for x86 in debug mode...

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:stripDebugDebugSymbols'.
> No version of NDK matched the requested version 21.0.6113669. Versions available locally: 24.0.8215888

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 3s

解決方法

ネットでググる前にエラーログを読めとはいうものの、あまりこの手の話って情報ないので困りました。

NDKの古いバージョンがないので動いてませんよということですので、要求されているVersionのNDKをインストールしたら解決します。

導入はAndoird Studioを立ち上げ、SDK Managerから開きます。 SDK Toolsのタブを開いて、右下のShow Package Detailsにチェックを入れると良いです。 画像のように、NDKの過去バージョンも含めて表示されるので、要求バージョンをDLします。

これでビルドが成功しました。

Using hardware rendering with device Android SDK built for x86. If you notice graphics artifacts, consider enabling software rendering with "--enable-software-rendering".
Launching lib\main.dart on Android SDK built for x86 in debug mode...
Running Gradle task 'assembleDebug'...                             14.8s
√  Built build\app\outputs\flutter-apk\app-debug.apk.
Installing build\app\outputs\flutter-apk\app.apk...              1,872ms
Syncing files to device Android SDK built for x86...               150ms

Flutter run key commands.
r Hot reload.
R Hot restart.
h List all available interactive commands.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).

 Running with sound null safety

Android EmulatorでローカルPCに接続する方法について

Android Emulator上で通常のPCと同じようにlocalhostとか指定してもAndroidのローカルホストに繋ぐだけで動かしているPCとは繋ぐことができないです。

当然、このような打ち方をしてもだめです。

http://127.0.0.1/

解決方法

Android Emulator のネットワークを設定する こちらのサイトに解答がありました。

10.0.2.2

を使うと、開発PCのローカルホストに繋ぐことができます。 Android Emulatorの割付だとこのようになっているようです。

ネットワーク アドレス 説明
10.0.2.1 ルーター / ゲートウェイ アドレス
10.0.2.2 ホスト ループバック インターフェースへの特殊エイリアス(開発マシンの 127.0.0.1 など)
10.0.2.3 1 番目の DNS サーバー
10.0.2.4 / 10.0.2.5 / 10.0.2.6 オプションの 2 番目、3 番目、4 番目の DNS サーバー(存在する場合)
10.0.2.15 エミュレートしたデバイスのネットワーク / イーサネット インターフェース
127.0.0.1 エミュレートしたデバイスのループバック インターフェース

まとめ

WebRTCが何者かわかっておらず、Serverに対してdemoアプリを繋ぐもんだと思ってましたが Serverは仲介するようなイメージなんですね。

demoアプリ1つだけ動かして永遠とわからんなぁとやってました。

平日の深夜こんなコトやってたので昼間会議中とかめっちゃ眠たかったです。 眠たいまま次の日も調べて作業してたので悪循環に陥りましたね。

ちゃんと寝て、スッキリしてやればすんなり行けました。動いて良かったです。 スタートラインに立てたので、コード読んで作りたいアプリに作り変えていきましょう。

今日はここまで!!