🦆

Mozilla Hubs Cloudをローカル(M1搭載Macbook)で実行してみた

2022/12/11に公開

はじめに

初めてのZennの記事です。よろしくお願いします!

Mozilla Hubsとは

ブラウザFirefoxで有名なMozilla社が開発したソーシャルWebVRサービスであり、PCからもVRデバイスからもブラウザを開いてアクセスできます。しかもオープンソース!

Mozilla Hubs

詳しい紹介は割愛します。もっと知りたい方はREALITY社 GREE VR Studio Laboratory 白井先生のスライド東京大学VRセンターの資料がおすすめです。

ユーザーが自分で管理できるサーバー(AWSなど)でHubsをホストしたければ、Hubs cloudが使えます。Hubs cloudを使えば、Hubsのフロントエンドやシーン作成ツールなど、一部のコンポーネントをカスタマイズすることもできます。

なぜこの記事を書く?

私が所属しているサークルUT-virtualも新歓活動にMozilla Hubsを使っていましたが、自分は全く別の経緯でMozilla Hubsを触り始めました。Mozilla Hubsをカスタマイズするとある学校のプロジェクトに携わり始め、ここ数日自分のパソコンで環境構築していまして、ようやくローカルで実行できるようになり、せっかくなので記事にして共有させていただきたいなと思いました。

なぜローカルで実行したい?

前述したように、Hubs cloudは一部のコンポーネントしかカスタマイズできず、もしバックエンドの方などにもカスタマイズしたければ、ローカルで実行できる環境を構築して、そこで開発しないと対応できないのではないかと思います。私が今携わり始めた学校のプロジェクトにもそういったカスタマイズの需要があります。

あと勉強のためにもなりそうですね。GREE VR Studio Laboratoryの方がHubs cloudを「解剖」するためにローカルで走らせたそうです(記事はこちら)。

環境構築を始めましょう

同じ内容の英語版も書きました

参考

今回は主にこのalbirrkarimさんの説明通りにやりつつ、Hubs cloudを構成するそれぞれのコンポーネントのレポジトリのREADMEを参考し:

そしてこれらの説明に言及されていないが自分が遭遇してしまった問題を対応してきました。

プロジェクト全体像は、albirrkarimさんが作ったグラフ、もしくはGREE VR Studio Laboratoryさんのスライド(p.35から))をご覧いただければと思います。

言っておきますが...

  • なるべく手順を細かく記述するように頑張ってみましたし、ここで書かれた手順はちゃんと自分のM1搭載のMacbookで動作できていますが、他のパソコンの環境で(例え同じくらいのスペックでも)完璧に動作することは保証できません。
  • 公式のアップデートにより、ここで書かれた手順が動作しなくなる可能性もあります。そうなりましたら、なるべくアップデートに追いついてこの記事を更新します。
  • この記事で間違ったところがありましたら、ご指摘いただければ幸いです!

スペック

ハード

  • チップ: Apple M1
  • メモリ: 16GB(8GB以上であれば大丈夫らしい)

ソフト

  • NodeJS: v16.16.0
  • npm: 9.1.3

1. インストール&初期設定

1.1 Reticulum

ElixirとPhoenix Frameworkで構築されたバックエンド

1.1.1 Clone

git clone https://github.com/mozilla/reticulum.git
cd reticulum

1.1.2 PostgreSQL

ReticulumのデータベースはPostgreSQLを使用している

  1. PostgreSQLをインストール:
brew install postgresql
  1. バージョンを確認 (11以上がおすすめ):
psql --version
  1. データベース postgres にログイン:
psql postgres
  1. ユーザを新規作成し(ユーザネームもパスワードも'postgres')、Superuserにする:
CREATE USER postgres WITH ENCRYPTED PASSWORD 'postgres';
ALTER USER postgres WITH SUPERUSER;
  1. \duでユーザ一覧を見て確認し、\qでpsqlシェルを終了する

Elixir と Erlang

今cloneしたReticulumのレポジトリにある .tool-versions というファイルに、必要なElixir と Erlangのバージョンが記載されています。

このチュートリアル に従い、該当するバージョンのElixir と Erlangをインストールしてください。

1.1.3 Reticulumのセットアップ

  1. 必要なパッケージをインストールする
mix deps.get
  1. PostgreSQLにデータベースを作成
mix ecto.create

psql -l でデータベース一覧を見て ret_dev が作られたかどうかを確認しましょう。

もしここでデータベースの作成が失敗したら、PostgreSQLのユーザのパスワードが間違った可能性があります。パスワードは config/dev.exs で記載されたのと同じ(つまりpostgres)になければならないため、ここでpsql postgresでpsqlシェルに入って、パスワードを再設定します:

ALTER USER postgres WITH PASSWORD 'postgres';

もし「データベースret_devが存在しない」のようなエラーが出ましたら、psqlシェルに入ってcreate database ret_dev;を実行してみてください。

  1. mkdir -p storage/devを実行してReticulumレポジトリの中にフォルダーを作成します

1.1.4 ローカルのDialogインスタンスに対してReticulumをセットアップ

  1. config/dev.exsでJanusのホストを変更します:
# Around the top of this file
dev_janus_host = "localhost"
  1. config/dev.exsでJanusのポートを変更します:
# line 216
config :ret, Ret.JanusLoadStatus, default_janus_host: dev_janus_host, janus_port: 4443
  1. lib/ret_web/plugs/add_csp.exでCSPルールを書き換える
# line 107
default_janus_csp_rule =
   if default_janus_host,
      do: "wss://#{default_janus_host}:#{janus_port} https://#{default_janus_host}:#{janus_port} https://#{default_janus_host}:#{janus_port}/meta",
      else: ""

1.2 Dialog

mediasoupに基づき、カメラストリーミングや画面共有など、音声や映像のリアルタイム通信を担う WebRTC SFU サービスです。

1.2.1 Cloneしてパッケージをインストール

git clone https://github.com/mozilla/dialog.git
cd dialog
npm ci

1.2.2 RSA暗号の設定

ReticulumはDialogインスタンスに対して実行する場合、RSA暗号を使用し、鍵はプライベートなリポジトリに保存されているそうです(参考)。

ローカルで実行するため、別途暗号を作って設定しましょう

  1. こちらでRSAの公開鍵と秘密鍵を作成
  2. Dialogのフォルダーの中にファイルcerts/perms.pub.pemを作成し、公開鍵をそのまま貼り付ける
  3. Reticulumのフォルダーの中にBashファイルscripts/run-local.shを作成し、以下を貼り付ける:
PERMS_KEY="-----BEGIN RSA PRIVATE KEY----- ...秘密鍵の各行の前に \n を追加し、鍵全体を1行にし、コピーしてここに貼り付けてください... -----END RSA PRIVATE KEY-----"
PERMS_KEY="$PERMS_KEY" iex -S mix phx.server

秘密鍵を他のところに保存してscripts/run-local.shに読み込まれるようにしても大丈夫です。
4. chmod +x ./scripts/run-local.shを実行し、scripts/run-local.shを実行可能なファイルにする

1.3 Spoke

Hubsの3Dシーンを作成・編集するためのGUI

1.3.1 Cloneしてパッケージをインストール

git clone https://github.com/mozilla/Spoke.git
cd Spoke
yarn install

もしこのエラー The chromium binary is not available for arm64によってyarn installが失敗したら、それはpuppeteerで設定した Chrome の実行パスが Apple M1 と一致しないからです(参考)。

以下のようにするとエラーが回避されます:

  1. (もしご自分のMacに入っていなければ)Chromiumをインストールします
brew install chromium --no-quarantine
  1. 正しい Chrome の実行パスでもう一度パッケージをインストール
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true PUPPETEER_EXECUTABLE_PATH=`which chromium` yarn install

1.4 Hubs

一般ユーザ用・管理者用のHubsのフロントエンド


1.4.1 Cloneしてパッケージをインストール

git clone https://github.com/mozilla/hubs.git
cd hubs
npm ci

1.4.2 adminフォルダーに移動してパッケージをインストール

cd admin
npm ci

/* `npm ci` が失敗したら */
npm install

2. ドメインをlocalhostにする

全てのフォルダー(reticulum・dialog・spoke・hubs・hubs/admin)でhubs.locallocalhostに置き換えましょう。

3. HTTPS (SSL)のセットアップ

HTTPS用の証明書と鍵を作成しましょう。

3.1 証明書を生成して設定する

Reticulumで:

cd reticulum
mix phx.gen.cert

selfsigned_key.pem と証明書 selfsigned.pem がフォルダー priv/cert の中に生成されます。

selfsigned_key.pemkey.pemに改名し、selfsigned.pemcert.pemに改名します。

key.pemcert.pem ができました

Finderで cert.pem をダブルクリックし、Keychain Access 画面を開きます。

cert.pem に当たる証明書をダブルクリックし、Trust タブを開き、When using this certificateAlways Trustにします。

Finderで cert.pemkey.pem をコピーしておきます。

次のステップからこの二つのファイルをhubs、hubs admin、spoke、dialog、そしてreticulumにコピペします。

3.2 reticulumで証明書と鍵のパスを修正する

reticulum/config/dev.exsの中のこの部分を:

# line 19
config :ret, RetWeb.Endpoint,
  ...
  https: [
    ...
    keyfile: "#{File.cwd!()}/priv/dev-ssl.key",
    certfile: "#{File.cwd!()}/priv/dev-ssl.cert"
  ],
  ...

以下のように、keyfileとcertfileのパスを修正します:

# line 19
config :ret, RetWeb.Endpoint,
  ...
  https: [
    ...
    keyfile: "#{File.cwd!()}/priv/cert/key.pem",
    certfile: "#{File.cwd!()}/priv/cert/cert.pem"
  ],
  ...

3.3 それぞれのレポジトリでHTTPSをセットアップ

  1. Hubs: reticulum/priv/cert/cert.pemreticulum/priv/cert/key.pemをフォルダーhubs/certsにコピペします
  2. Hubs admin: reticulum/priv/cert/cert.pemreticulum/priv/cert/key.pemをフォルダーhubs/admin/certsにコピペします
  3. Spoke: reticulum/priv/cert/cert.pemreticulum/priv/cert/key.pemをフォルダーSpoke/certsにコピペします
  4. reticulum/priv/cert/cert.pemreticulum/priv/cert/key.pemをフォルダーdialog/certsにコピペして、
  • cert.pemfullchain.pemに改名し、
  • key.pemprivkey.pemに改名します。

4. 実行

reticulum・dialog・spoke・hubs・hubs adminを同時に実行するために、五つのターミナルを開きます。

4.1 reticulum を実行する

cd reticulum
./scripts/run-local.sh

4.2 dialog を実行する

package.json を開いて以下のように編集:

"scripts": {
    ...
    "start": "MEDIASOUP_LISTEN_IP=127.0.0.1 MEDIASOUP_ANNOUNCED_IP=127.0.0.1 DEBUG=${DEBUG:='*mediasoup* *INFO* *WARN* *ERROR*'} INTERACTIVE=${INTERACTIVE:='true'} node index.js"
    ...
  },

そして npm start を実行します。

package.json を編集せず、以下のようにそのまま実行しても同じです。

MEDIASOUP_LISTEN_IP=127.0.0.1 MEDIASOUP_ANNOUNCED_IP=127.0.0.1 npm start

もし以下のようなエラーが出ましたら:

Error: listen EADDRINUSE: address already in use 7000

config.jsでadminHttpのポートを7000から7001や他のポートにします:

adminHttp:
{
   listenIp   : '0.0.0.0',
   listenPort : process.env.ADMIN_LISTEN_PORT || 7001
},

4.3 spoke を実行する

cd Spoke
./scripts/run-local-reticulum.sh

4.4 hubs と hubs admin を実行する

cd hubs
npm run local
cd hubs/admin
npm run local

5. ローカルでMozilla Hubsにアクセス

Server URL
Hubs https://localhost:4000
Hubs admin https://localhost:4000/admin
Spoke https://localhost:4000/spoke

ログイン

https://localhost:4000/ にアクセスします

右上のボタンをクリックし、メールアドレスを入力してログインします

入力されたメールアドレスに認証メールが送られるはずですが、Reticulumはローカルで動作しているため、メールは送ることが実際にはできません。

Reticulum が起動しているターミナルを開き、メールアドレス検証用のリンクを探します。そのリンクをコピーして、新しいブラウザのタブを開いて貼り付ける

検証ができたらタブを閉じて大丈夫です

Hubsのトップページに戻ると、右上にメールアドレスが表示されます

アカウントを管理者として設定する

Reticulum が起動しているターミナルを開き、Enter キーを押して Elixir's interactive shell (iex) にアクセスします

次のコマンドを実行して、最初に登録されたアカウント(先ほどサインインに使用したアカウント)を管理者として設定します:

Ret.Account |> Ret.Repo.all() |> Enum.at(0) |> Ecto.Changeset.change(is_admin: true) |> Ret.Repo.update!()

# Enum.at(0) の '0' は最初に登録されたアカウントを指します。他の番号を使用すると、他のアカウントを管理者として設定することができます

Hubsのウィンドウを更新すると、ウィンドウの上部に利用可能なリンク(Scene editor・Admin)が表示されます

Adminリンクをクリックすると管理者向け画面(hubs/adminでホストされています)に遷移されます。https://localhost:4000/adminからアクセスすることも可能です。

Scene editorリンクをクリックすると Spoke(Hubs用の3Dシーンを作成・編集するアプリケーション)の画面に遷移されます。 https://localhost:4000/spokeからアクセスすることも可能です。

Spokeを使ってみる

New project ボタンをクリックしてシーン作成画面を開きます

シーン作成画面の読み込み中、CORSの問題のせいか、一部のアセットが正常に読み込まれないことがあります。その場合は、リンクをハイライトし、URLバーにドラッグすることでアセットをダウンロードすることができます。その後、またパソコンからSpokeにインポートすることができます。

次に、先ほどインポートしたアセットを含む、任意のアセットをシーンにドラッグします。位置や回転などの属性は、GUI上で編集することができます。

完了したら、右上のPublishボタンをクリックしてシーンを公開します。公開したら、'View Your Scene'ボタンをクリックしてこの新しいシーンで直接ルームを作成することができます。(一旦Hubsのホームページへ戻ってそこからRoomを作成することもできます)

Create a room and interact with other accounts

Hubsのホームページhttps://localhost:4000から、'Create Room'ボタンをクリックすると、ルーム作成画面へ遷移されます。

'Options'ボタンをクリックし、シーンを先ほど作ったものに設定します


下までスクロールして'Apply'ボタンを押し忘れずに。

それではJoin Roomボタンをクリックしてルームに入りましょう!

別のブラウザでhttps://localhost:4000にアクセスし、別のメールアドレスで上記と同じ手順でログインし、新しく作成した部屋と同じURLにアクセスすることができます。

両方のアカウントが入室したら、WASDキーや矢印キーでアバターを動かし、マウスでドラッグして視点を回転させると、互いのアバターが見えるようになるはずです!

終わりに

今回はMozilla Hubsをローカル(M1 MacOS)で実行する手順を共有させていただきました。
ただこれらの手順は他のパソコンでもうまく動作することが保証されません。
それでも自分の経験が誰かに役に立てれば嬉しいです。
拙い日本語で出来上がった長文なので、もし読みづらいところがありましたら、どうかお許しください。
この記事でもしどこか間違ったところがありましたら、ぜひご指摘いただければ幸いです。

Mozilla Hubsについてまた他の記事を書くかもしれません(どこかにデプロイするとか、どれかのコンポーネントを置き換えてみるとか)。
XR(主にVRかな)に関連する他の記事もこれから書かせていただく予定です!
またよろしくお願いします。

GitHubで編集を提案

Discussion