5
4

MetaQuestでローカルwebサーバを立ててスタンドアロンでWebXRアプリを動かす

Last updated at Posted at 2023-12-24

Meta Quest上にローカルwebサーバを立てて、そこでWebXRアプリを動かそうという記事です。
これで完全スタンドアロンでWebXRアプリを動かすことができます。

以下MetaQuestで記述ですが、PICO4でもほぼ同様に動作します。

Quest上でのWebサーバは、TermuxというAndroidのターミナルアプリを使います。これはターミナルエミュレータではあるのですが、なんとLinuxのコマンド類も普通に動かすことができます。phpも動くので、phpのデバッグ用webサーバ機能を使えば簡単にローカルサーバを立てることができるというわけです。

Termux自体が普通のAndroidアプリなので、ルート化等も必要なく、サンドボックスで安全に動かすことができます。

Termuxについては以下の記事も参考にどうぞ。

手順はおよそ以下のようになりなす。

  1. F-Droidをインストール
  2. F-DroidからTermuxをインストール
  3. 起動してシェルが使えることを確認
  4. termux-change-repo でリポジトリを更新
  5. pkg install で必要なツールをインストール
  6. php は pkg install phpでok
  7. phpのdebugモードでwebサーバを起動
  8. ストレージのアクセスを許可
  9. ストレージをdocument rootにsymlinkすると見えるようになる
  10. file一覧を取得するapiを作る
  11. ファイル一覧ページが動いた
  12. WebXRアプリの動作

Termuxのインストール

Termuxの最新版は、AndroidのOSSサイトであるF-Droidで配布されているので、まずF-Droidアプリをインストールします。

apkがダウンロードできるので、sideQuestやMQDH等でQuest本体にインストールしてください。

F-Droidがインストールできたら、Termuxを検索して以下のアプリをインストールします。

518dc4b716d05ca983d3cc92e6756630.jpeg

Termuxをインストールして起動すると、以下のような画面でシェルが起動します。

a53daff4154d5626d0c5cae92e1208ea.jpeg

ここで、実はすでにLinuxライクのシステムが動いていて、シェル内蔵コマンドや基本的なコマンドはそのまま動作します。
バーチャルキーボードも使えますが、BTキーボードを繋いだほうが実用的でしょう。

Linuxのプログラムはpkgコマンドでインストールできます。
最初にリポジトリを最新にするために、以下のコマンドを実行します。

$ termux-change-repo

リポジトリを選択する画面になるので、適当に選びます。

これで、pkg install で各種プログラムがインストールできるようになります。
vimやgit,unzip,curl等いれておくと良いでしょう。

phpとWebサーバの設定

phpは

$ pkg install php

でインストールできます。

phpの内蔵デバッグ用Webサーバを動かします。デバッグ用ではありますが、一人でローカルで使う分には十分です。

document root となる適当なディレクトリを作って、そこに移動して

$ php -S localhost:8080 2> /dev/null &

でwebサーバが起動します。リダイレクトをファイルに落とせばアクセスログになります。

document rootに

info.php
<?php
phpinfo() ;

を作って、Questブラウザで http://localhost:8080/info.php を開いてみましょう。

08483633387e772a83f187079ec614cd.jpeg

これでwebサーバとphpが動きました。ここまでくればあとは何でもできますねw

phpはサーバとして動いてはいるものの、Termuxアプリが何らかの原因で停止すると、当然ながらphpサーバも止まります。バックグラウンドで動いてるアプリは、メモリ不足等によりいつ殺されるかわからないのですが、実際には結構しぶとく残ります。他のVRアプリを起動しても残っているので、システムレベルで落ちるようなことがない限り動き続けるのかもしれません。

2024/2/23 追記。

Questメニューの「通知」にあるTermuxのプロセスのところで、"Acquire wakelock"ができることを発見しました。これをセットしておくと、バックグラウンドでの動作が保証されるはずなので、webサーバも落ちなくなることが期待されます。

com.oculus.shellenv-20240223-183206.jpg

共有ストレージエリアにアクセスする

Termuxのhome以下は、Termuxアプリのサンドボックス領域にあり、このままでは、共有ストレージにはアクセスできません。

アクセスするためには、Questの設定のアプリの項目で、ストレージアクセスを許可する必要があります。

b57396f6c617a16c86376a63bad048e6.jpeg

これをonにすると、 /storage/emulated/0 のパスで、DownloadやMoviesのフォルダのある共有ストレージにアクセスすることができます。

Webからアクセスする場合は、document rootの下に

$ ln -s /storage/emulated/0 share

のようにリンクを張っておくとよいでしょう。これでブラウザから共有ストレージに直接アクセスすることができるようになります。

ファイル一覧アプリを作ってみる

ストレージの中身をリストして、動画や静止画の簡単なビュアーを作ってみます。

まずフォルダの一覧を取得するための、APIを作ります。 pathで指定したフォルダの一覧をjsonで返します。

dir.php
<?php
$path = $_GET['path']	;
$dp = @opendir($path) ;
if(!$dp) {
	echo json_encode(array('status:-1'));
	exit;
}
$files = [] ;
while(($f = readdir($dp))!==false) {
	if(substr($f,0,1)==".") continue ;
	$st = stat($path."/".$f) ;
	$files[] = array(
		'name'=>$f,
		'isdir'=>(($st['mode']&0770000)==040000),
		'size'=>$st['size'],
		'mtime'=>$st['mtime']
	); 
}
echo json_encode(array('status'=>0,'path'=>$path,'files'=>$files),JSON_UNESCAPED_UNICODE) ;

このdir.phpを使って、指定したフォルダにあるメディアファイルを一覧してリンクするwebアプリを作りました。

files.html
<!DOCTYPE html>
<html  lang="jp">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width">
<title>files</title>
<script type="text/javascript">
const path = location.search.substring(1)
onload = function() {
	let result = ""
	api("dir.php",{'path':path}).then(d=>{
		if(d.status==0) {
			d = d.files.filter(d=>{
				return d.name.match(/\.mp4|\.mp3|\.jpg|\.png|\.webm$/)
			})
			console.log(d) ;
			const l = [] 
			for(let i in d) {
				l.push(`<a href="${path+d[i].name}">${d[i].name}</a>`)
			}
			result = "<ul><li>"+l.join("</li><li>")+"</li></ul>"
		} else {
			result = "no files"
		}
		document.getElementById("list").innerHTML = result

	})
}
function api(path,param) {
		return new Promise((resolve,reject) => {
			const req = new XMLHttpRequest();
			const p = [] 
			for(let k in param) {
				p.push(`${k}=${encodeURIComponent(param[k])}`)
			}
			req.open("get",path+"?"+p.join("&"),true) ;
			req.responseType = "json" ;
			req.onload = () => {
				if(req.status==200) {
					resolve(req.response) ;
				} else {
					reject("Ajax error:"+req.statusText) ;
				}
			}
			req.onerror = ()=> {
				reject("Ajax error:"+req.statusText)
			}
			req.send() ;
		})
}
</script>
</head>
<body>
<div id=list></div>
</body>
</html>

これで、Downloadフォルダにある動画や静止画を一覧して、ブラウザで開くことができました。

e28cc809e547dce90406a28fa0f4c1ef.jpeg

WebXR アプリを動かす

さていよいよ本題のWebXRアプリです。といっても、ここまでできていれば、あとは普通にWebXRのアプリをドキュメントルートに配置するだけです。

WebXRは、本来https環境でなければ動作しませんが、localhostは例外的にhttpでも動作します。

URLに注目。

e510bee43d330b2dcb7ded287f76e5c1.jpeg

実際の開発では、さすがにTermux上でコードを編集するのはつらいので、別なサーバで開発して、githubを経由して同期するのが良いでしょう。QuestのTermux上ではgit pullするだけで更新することができます。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4