#ChannelPlayer · Go · Quest2 · Rift · Unity · VRソフト

Youtube DL Video Playerアセットを使ったUnityアプリをOculus Quest 2で動作させる

ここ2か月ほどかけて、Youtube DL Video Player というUnity Asset Storeで公開されているAssetを試していた。これは内部に aarファイルの形式で、PythonバイナリとPythonで書かれたyoutube-dlを動作させ、Youtubeのコンテンツの実際のURLを引っ張り出して再生できるようにするもので、これをChannel Playerに組み込むか、あるいは単体アプリとしてYoutubeの動画再生機能をOculus Quest2で動作させるのが目的であった。(ちなみにUnity Asset Storeでは、Youtube Video Player + Youtube APIというAssetも存在し以前使ったこともあるが、古い昔のバージョンとは異なり、近年のバージョンではherokuapp.comを内部で呼んでいてアーキテクチャが理解できていないので保留している)

当初、サンプルアプリを作って、Oculus Goでも動くようにとARMv7向けにbuildしたら、Goで動くことが確認出来た。しかし、これをそのままQuest 2にインストールしても動かず、またARM64向けにbuildしても同様で動作せず、そこからが迷走の始まりであった。

まずエラーメッセージを見ると、ARMv7版とARM64版ではどちらも同じエラーであり、以下のようなものであった。

10-19 00:13:01.571: E/YoutubeDLPlugin(31518): java.io.IOException: Cannot run program “/data/user/0/com.Applet_LLC.myTube/files/youtubedl-android/packages/usr/bin/python”: error=13, Permission denied

Youbue DL Video PlayerのAsset Storeのレビューでは、IL2CPPではbuildできないとか、Android 10ではダメだとかしか書かれておらず、要するにARM64なOculus Quest 2では出来そうにないことが書かれていて断念していたのだが、実行できないのは、このaarプラグイン形式がダメなのだろうと思い、Youtube DL Video Playerアセットを使うのをやめて、NuGetから、NYoutubeDLというyoutube-dlをC#から呼び出すラッパーを試してみた。結論はOculus Riftでは動作できるようにできるが、このラッパーは、youtube-dl.exeを実行するものであるので、解決策からは、ほど遠いものであった。

Pythonが実行できないとダメだと思い、調べてみるとTermuxというアプリで、shellを起動しpythonを実行して、youtube-dlスクリプトを動作させることが出来ることが判った。しかしこれは、Linux Shellが使えるようになるだけで、UnityのC#から呼び出すことはできない。そこで、今度はIronPython for Unityとpython-for-androidを試すことにした。これらは、pythonスクリプトを実行できるが、前者はUnity Editor環境でPythonスクリプトが使えるようにするもので、アプリには出来ない。後者は、もっと調べてみると、Buildozerというpython-for-android を組み込んで書かれたPythonスクリプトを、kivyと呼ばれるGUIを持ったPythonスクリプトをAndroidで動作できるようにAPKファイルを作るものがあったので、それをWSLのUbuntu環境でbuildして、APKを作ることが出来るようになった。ここでBuildozerで、kivy GUIを使わないコードにすればGUIを持たず良いのではと思い、youtube-dlの派生版である yt-dlpを inportするようにしてAPKを作成した。Buildozerは良く出来ていて、Pythonスクリプトや buildozer.spcに yt-dlpのキーワードを書くだけで、勝手にyt-dlpをgetしてbuildしてしまう。このAPKをインストールして、Unityで作ったサンプルアプリから、Intentにyt-dlpの引数を渡して、Pythonスクリプトでは、Intentをyt-dlpの引数に渡すようにして、yt-dlpが実行した際の標準出力をファイル出力させれば、UnityのVideoPlayerやAVPro VideoのPlayerが解釈できるURLを吐き出すことが出来るはず。その後、Unity側から、そのファイルを読み込んで、Playerに渡せば、どうにか動くようにできるのではと作っていたが、Unityから引数が渡せて、Pythonとyt-dlpが動作するようになった時点で、困った事態が発生していることが判った。それは、Unity側のアプリから呼び出したyt-dlpのActivityは、要するに別アプリなので画面が遷移してブラックアウトしてしまう。これではアプリとして成立せずダメだと思いAndroidのサービスプログラムにしなければと、さらなる深みに入ろうとしていた。これが先週末あたりの出来事である。

ここで、迷ったら最初に戻るよろしく、最初のエラーメッセージから解決策が他にないのかを探ることにした。まず、なぜ先のエラーメッセージになっているのかを調べることにした。

そもそもエラーメッセージは、実行権限が無いと言っているだけで、実行ファイルでは無いとかファイルが存在しないと言っているわけでは無い。そこでこのエラーメッセージで検索して調べてみると以下の情報が得られた。

What path to put executable to run on Android 29? – Stack Overflow https://stackoverflow.com/questions/64786837/what-path-to-put-executable-to-run-on-android-29/64792194#64792194

これは、Androidのlevelが29以降だと、アプリのフォルダに置かれたバイナリを実行することが出来ないというものであり、これに該当していたことになる。Google Playとは異なり、Oculus Quest 2の場合は、TargetSDK level は29以上である必要は無いので(25以上であれば良い。ただしAppLabに登録するなら29となります。)、TargetSDKを下げてやれば、実はQuest 2でも先の Youtube DL Video Playerをそのまま使って動作できるのではと考え、実行に移してみた。

Unityの場合、TargetSDKは、Plugin/Androidに置いた AndroidManifest.xmlにも記載場所があるが、実際にbuildする際は、UnityのPlayerSettingsのTargetAPI Levelの指定が有効となる。ここをAutoにしていると環境に依存し、使えるAndroid SDKの一番高いレベルのものでbuildしてしまう。そこで、ここを28にして、ARM64向けにbuildしたら、エラーメッセージは発生せず、無事にYoutubeのコンテンツがサンプルアプリでOculus Quest 2の中で再生できた。

入手したスキル。Ubuntu環境にてBuildozerでAPKの作り方。Pythonスクリプトの書き方(触りだけだけど)。UnityのC#コードから他のAndroid Activityを呼び出しIntentを渡す方法。Pythonスクリプト側で受け取ったIntentを引数として解釈する方法、Pythonでstdin/stdoutをファイル出力に変える方法と、intentをsplitしてsys.argに代入すると、そこから呼び出したPythonスクリプトは、引数が存在していることを想定しているので、うまく渡る。

広告
#ChannelPlayer · FOVE · Go · Rift · VRソフト

Channel Player 1.11リリース

2か月以上空いてしまいましたが、Channel Playerの新しいバージョンをリリースしました。
今回のバージョンからは、SteamVR対応版のみとしました。XBoxゲームコントローラーとキーボードにて操作可能です。また仰向けで寝ている場合の表示モードに対応し、お気に入りや検索機能も実装しました。ソフトウェアのページでご案内しています。

SteamVRを用いた FOVE 0や、Oclus Rift での動作確認を実施しています。

#ChannelPlayer · Go · Unity

ALVR導入と#ChannelPlayer

#ChannelPlayerのOculus Go版の開発において、Webdavを使えるようにしてサーバーの動画ファイルアクセスの実装を進めていたけれども、.Netのhttpアクセスは、UnityのAndroid向けbuildでは現在サポートされておらず、こちら一旦保留にしました。

そのかわりALVRの存在を知り、#ChannelPlayerのSteamVR版を試しに作ったところ、すんなりGoで実行できることが判明しました。これだとGoの使いにくいコントローラーを使わずに、PC側でX-Boxのコントローラーを使うことが可能なのでより利便性は高いかなと思います。もっともGoがすぐ熱くなるので、映像をずっとデコードするというのは重いのかなとも思います。

#ChannelPlayer · Go · Unity

WebDav対応(2)

Oculud Go版の#ChannelPlayer(まだ公開していない)から、WebDavのコンテンツをソースコード上で指定して再生することは出来ている。問題は、BASIC認証を通すことができない。以下のAVProVideoに関する質疑応答では、AndroidでExoPlayerを使用している場合にはCustom httpヘッダーを付けることが出来るという現在進行形の話題があるが、どうもhttp接続ではなく、rtsp接続の場合じゃないのだろうかと思う。

Request video url with header · Issue #87 RenderHeads/UnityPlugin-AVProVideo https://github.com/RenderHeads/UnityPlugin-AVProVideo/issues/87

BASIC認証はあきらめ、とりあえずファイル一覧を取得する方を進めようと思う。

#ChannelPlayer · Go · Unity · VRソフト

WebDav対応を考える

#ChannelPlayerのOculus Go版では、内蔵ストレージ容量が小さいので、外部のサーバーへのアクセスが必要となる。他のプレイヤーアプリでは、DLNAクライアントだったり、SMB/Cifs対応していたりするが、いずれも実装コストが高い。

DLNAの方はあまり調べていないが、SMBの方を実装しようと当初考えていた。SMBの実装には、smbjやJCIFS などがあるが、いずれもjarなので、Unityのソースに組み込むには、JAR プラグインを使う必要があり、まずそこに課題があった。またうまくコードに組み込んだとしても、デコーダーであるAVPro Video Playerで、どのように読み込ませるかも課題であった。例えばYoutube API Assetでは、Youtube APIによるYoutubeサイトに対しコンテンツをアクセスし、それをUnityのPlayerやAVPro Video Playerに渡すことが出来るので、そのようなことを、SMBサーバーに対してアクセスして、動画ファイルのデーターをVideo Playerに渡すような実装を考えれば実現できるかもと考えていた。

しかし、それは少し面倒そうだし、性能が出るかどうかも怪しい。そこでWebDavはどうだろうかと調査してみた。WebDavは、Windows 10 Home版でもIISを組み込めばサーバーを立てることが可能だし、その他Linuxサーバーでも実現可能である。またクライアントも概ねWebアクセスと同じと考え、ソースコードを自前でゴリゴリ書くか、WebDav Asset(まだbuildできないので、コメントを先日投稿した。)を導入しても良い。

ここで、WebDavサーバーを立て、動画コンテンツを置いたときに、示されるURLをAVPro VideoPlayerにファイルパスではなく、URLを記述して再生が可能か試してみた。

結論は良好である。PlayerがURLで示された動画ファイルの再生に対応しているから、あとはWebDavサーバーにログインして動画コンテンツへのURLを取得すれば、再生アプリとして外部サーバーアクセス出来ることになる。

#ChannelPlayer · Go · VRソフト

#ChannelPlayer Oculus Go対応

Oculus Go上でも、#ChannelPlayer 1.08相当では動いていますが、1.09のFishEye180対応を入れていないことや、Oculus Goのコントローラーでは、ほとんどまともに操作できないので、他のアプリのように小さいところをレーザーポインターでクリックするようなUIを不本意ながら実装するなど進めるか思案中です。不本意というのは、テレビのリモコンのように、どこに向けても、その位置には関係なく操作したいという思いがあります。またストレージ容量が小さいので、ローカルファイルのファイル再生機能だけでは訴求力が足りないこともリリース阻害要因のひとつです。それを解決するために、SAMBA対応にトライする予定です。