Google MediaPipeのサンプルアプリをビルドしてAndroidにインストールする手順

![hand_tracking_3d_android_gpu_small.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54/186aeea8-e73c-70c3-026e-81d0f4cc9e8d.gif)

Hand Trackingが実装されたことで話題になったGoogle MediaPipeを、ビルドしてAndroidにインストールするまでの手順です。

基本的には公式README通りにやれば良いですが、何箇所が躓いたところがあるので、それを中心に書いておきます。

[google/mediapipe: MediaPipe is a cross-platform framework for building multimodal applied machine learning pipelines](https://github.com/google/mediapipe)

ちなみに、MediaPipeについてはHand Trackingの話題で存在自体を初めて知りました。日本語の解説記事があったので、合わせて読むと少しは理解が進むかも。

[GoogleのMediaPipeでMLアプリ開発が楽になる · tkat0.github.io](https://tkat0.github.io/posts/mediapipe/)

# MadiaPipeのビルド環境を整える

[公式ドキュメント](https://github.com/google/mediapipe/blob/master/mediapipe/docs/install.md)の通り進めていきます。Mac+Android Studioなら、以下の順序で読み進めていけばOKです。

1. [Installing on macOS](https://github.com/google/mediapipe/blob/master/mediapipe/docs/install.md#installing-on-macos)
2. [Setting up Android Studio with MediaPipe](https://github.com/google/mediapipe/blob/master/mediapipe/docs/install.md#setting-up-android-studio-with-mediapipe)

以下、躓いたところと解決方法です。

# `Run the Hello World desktop example.`でビルドエラー

`bazel run`で以下のようなエラーが出ました。

```bash
$ export GLOG_logtostderr=1                                                                                                                                                                       [(master) ~/Development/oss/mediapipe]
$ bazel run --define MEDIAPIPE_DISABLE_GPU=1 \                                                                                                                                                    [(master) ~/Development/oss/mediapipe]
    mediapipe/examples/desktop/hello_world:hello_world

Extracting Bazel installation...
Starting local Bazel server and connecting to it...
... still trying to connect to local Bazel server after 10 seconds ...
DEBUG: Rule 'build_bazel_rules_apple' indicated that a canonical reproducible form can be obtained by modifying arguments commit = "6c9fcae7a3597aabd43f28be89466afe0eab18de", shallow_since = "1565379803 -0700" and dropping ["tag"]
DEBUG: Call stack for the definition of repository 'build_bazel_rules_apple' which is a git_repository (rule definition at /private/var/tmp/_bazel_keita/d5c0de304ea3ae0df121006f1a08079f/external/bazel_tools/tools/build_defs/repo/git.bzl:181:18):
 - /Users/keita/Development/oss/mediapipe/WORKSPACE:251:1
ERROR: /private/var/tmp/_bazel_keita/d5c0de304ea3ae0df121006f1a08079f/external/local_config_cc/BUILD:62:5: in apple_cc_toolchain rule @local_config_cc//:cc-compiler-watchos_arm64_32: Xcode version must be specified to use an Apple CROSSTOOL. If your Xcode version has changed recently, verify that "xcode-select -p" is correct and then try: "bazel shutdown" to re-run Xcode configuration
INFO: Call stack for the definition of repository 'com_google_absl' which is a http_archive (rule definition at /private/var/tmp/_bazel_keita/d5c0de304ea3ae0df121006f1a08079f/external/bazel_tools/tools/build_defs/repo/http.bzl:237:16):
 - /Users/keita/Development/oss/mediapipe/WORKSPACE:16:1
INFO: Call stack for the definition of repository 'com_github_glog_glog' which is a http_archive (rule definition at /private/var/tmp/_bazel_keita/d5c0de304ea3ae0df121006f1a08079f/external/bazel_tools/tools/build_defs/repo/http.bzl:237:16):
 - /Users/keita/Development/oss/mediapipe/WORKSPACE:61:1
ERROR: Analysis of target '//mediapipe/examples/desktop/hello_world:hello_world' failed; build aborted: Analysis of target '@local_config_cc//:cc-compiler-watchos_arm64_32' failed; build aborted
INFO: Elapsed time: 48.317s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (24 packages loaded, 108 targets configured)
FAILED: Build did NOT complete successfully (24 packages loaded, 108 targets configured)
```

Xcodeの新しいコマンドラインツールのディレクトリを見られてないのが原因です。ちなみに、Xcodeが古い場合は最新版にしておきましょう。

```bash
$ xcode-select -p                                                                                                                                                                                 [(master) ~/Development/oss/mediapipe]
/Library/Developer/CommandLineTools
# このディレクトリだとエラーになる

$ sudo xcode-select -r
# xcode-selectをリストアする

$ xcode-select -p                                                                                                                                                                                 [(master) ~/Development/oss/mediapipe]
/Applications/Xcode.app/Contents/Developer
# このディレクトリになったらOK

$ bazel shutdown
# bazelサーバーを一度落とす

$ bazel run --define MEDIAPIPE_DISABLE_GPU=1 \                                                                                                                                                    [(master) ~/Development/oss/mediapipe]
    mediapipe/examples/desktop/hello_world:hello_world
# 再度ビルドを実行
```

[getting Xcode-related error with Bazel - Google グループ](https://groups.google.com/forum/#!topic/bazel-discuss/NoVEVP-hcs8)

# Android Studioの`Configure`って何？

`Configure | SDK Manager | SDK Platforms`みたいになってるところの`Configure`はメニューバーにある`Android Studio > Preferences`に読み替えればOKです。

# `Import Bazel Project`の最後の`Finish`を押すとエラー
<img width="410" alt="This_should_not_be_shown.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54/312581c7-416d-59bf-868b-55c8813b9548.jpeg">

最後の方にあるandroid_sdk_platformのコメントアウトを1つ外さないとエラーになります。基本的には最新の`android_sdk_platform: android-28`のコメントアウトを外せば問題ないです。

<img width="1089" alt="Import_Project_from_Bazel.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54/30c4e023-fd89-ea45-6280-9e6c25c51930.jpeg">

# Syncエラー

```
Error:Cannot run program "bazel" (in directory "/Users/keita/Development/oss/mediapipe"): error=2, No such file or directory
```
bazelコマンドのロケーションをAndroid Studioに設定する必要があります。まずはbazelコマンドの場所を特定します。

```
$ which bazel
/usr/local/bin/bazel
```

Android Studio > Preferences > Bazel SettingのBazel binaru locatiopnにパスを入力してOKを押します。
<img width="991" alt="Preferences.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54/64414d42-3636-f5b3-9d5f-849e0d737566.jpeg">
[Cannot run program "bazel".. No such file or directory · Issue #285 · bazelbuild/intellij](https://github.com/bazelbuild/intellij/issues/285)

# アプリビルドでエラー
```
ERROR: /Users/keita/Development/oss/mediapipe/WORKSPACE:243:1: //external:android/sdk depends on @androidsdk//:sdk in repository @androidsdk which failed to fetch. no such package '@androidsdk//': Either the path attribute of android_sdk_repository or the ANDROID_HOME environment variable must be set.
```

環境変数にSDKとNDKのロケーションは設定しているのに、それが見つからないというエラーです。色々試したけど、環境変数の方法では解決しなかったので、WORKSPACEファイルにそれぞれの場所を記入する方法でビルドできるようになりました。

プロジェクトルートにある`WORKSPACE`ファイルに`android_ndk_repository`と`android_sdk_repository`がすでにあるので、そこに`path = `の行を追記します。

```bash
# You may run setup_android.sh to install Android SDK and NDK.
android_ndk_repository(
    name = "androidndk",
    path = "/Users/keita/Library/Android/sdk/ndk-bundle",
)

android_sdk_repository(
    name = "androidsdk",
    path = "/Users/keita/Library/Android/sdk",
)
```

SDKのパスは Tools > SDK Manager で開く画面の`Android SDK Location`です。NDKはAndroid StudioのSDK Managerを使って入れている場合は `[SDKパス]/ndk-bundle` です。

# 現在ビルドできるアプリ一覧

[mediapipe/mediapipe/examples/android/src/java/com/google/mediapipe/apps at master · google/mediapipe](https://github.com/google/mediapipe/tree/master/mediapipe/examples/android/src/java/com/google/mediapipe/apps)

## Hand Trackingのビルドとインストール

```
bazel build -c opt --config=android_arm64 mediapipe/examples/android/src/java/com/google/mediapipe/apps/handtrackinggpu
```

```
adb install bazel-bin/mediapipe/examples/android/src/java/com/google/mediapipe/apps/handtrackinggpu/handtrackinggpu.apk
```

[mediapipe/hand_tracking_mobile_gpu.md at master · google/mediapipe](https://github.com/google/mediapipe/blob/master/mediapipe/docs/hand_tracking_mobile_gpu.md)