やりたいこと
当方ゲーマーではないのですが、HMD(ヘッドマウントディスプレイ、VRゴーグル)ってどんなんだろう、と少し興味がわきました、(想像ですが、映像にフィルタ掛ければ漫画の中に入れる体験とかできんの?2次元の世界に没入できたら楽しそうだなぁ、とか、)
とはいえVIVEとかMetaとか5万以上かかるしなぁ、貧乏人の自分がいきなり買うのは高そうだなぁ、、
そうだ!余ってるスマホを活用(Gstreamerとか組み込んで)して、VRゴーグル風に2眼分映せば何か感じ取れるんじゃね?
今回使う機材と構成
使うハード、ソフト(ライブラリ)
- 端末A Galaxy S10 (カメラ/映像送信機) ⇒眠ってたAndroid端末その1
- 端末B Pixel 6 (VRゴーグルの画面部/映像受信機) ⇒眠ってたAndroid端末その2
- ダンボールゴーグル (VRゴーグルの筐体) ⇒前に100均(セリア)で買った
- Gstreamer(Android版) https://gstreamer.freedesktop.org/ ⇒今回のキモ
※Android版Gstreamerライブラリのリンク方法や叩き方は割愛、後述の参照[2]のソース等を見てください。基本JNIで叩くだけだけ
構成とデータの流れ
端末Aで撮った映像をローカル無線(テザリングネットワーク)上にH264/RTP映像を流し、端末Bで2眼それぞれで表示してVR風に表示させることを目指します。
Gstreamerとは
GStreamerとは動画の一連の処理(デマックス、デコード、フィルタ、ストリーム分岐、など)をカスタマイズする事が容易なメディアフレームワーク。予め用意された機能(プラグイン)を'!'(接続子)で繋げる事でパイプラインとして設計し、柔軟にデータ処理をプログラミングする事が出来ます。(参照[1])
コマンドライン例
gst-launch-1.0 -v filesrc location=hoge.mp4 ! qtdemux name=demux demux.audio_0 ! queue ! decodebin ! audioconvert ! audioresample ! autoaudiosink demux.video_0 ! queue ! decodebin ! videoconvert ! videoscale ! autovideosink
解説
ローカルにある"hoge.mp4"をqtdemux(Quicktime形式のデマクス処理)で映像と音声に分岐し、decodebin(自動でコーデック判別して最適なデコーダを選択するもの)でデコードし、autovideosink/autoaudiosink(最適な映像/音声レンダラを自動で提供)で出力
※普通のMP4プレイヤを模擬すると上記のようなパイプライン処理になります
今回構成でのGstreamerパイプライン
1. 送信側
カメラで撮った映像を分岐させ、1つめはSurfaceViewへ表示、2つめはh264エンコードしてRTPで送信
※glimagesinkはAndroidのSurfaceView、ahcsrcはAndroidのカメラとリンク可能なエレメントです。(参照[2])
"ahcsrc name=ahcsrc ! capsfilter name=filter caps=video/x-raw,width=640,height=480,framerate=30/1 ! tee name=tee tee. ! queue name=video_queue ! glimagesink name=vsink tee. ! queue name=udp_queue ! videoconvert ! openh264enc bitrate=5000000 ! h264parse ! rtph264pay pt=100 mtu=1400 config-interval=3 ! udpsink host=\"192.168.xx.yy\" port=9000"
2. 受信側
port9000で受信したRTPをデコードして2分岐、それぞれを別のSurfaceViewで表示
※左右の目で見せるSurfaceViewを用意し、teeで分岐させたglimagesinkにリンクさせてます
"udpsrc port=9000 ! application/x-rtp,media=video,encoding-name=H264 ! queue ! rtph264depay ! avdec_h264 ! videoconvert ! tee name=tee tee. ! queue name=video01_queue ! glimagesink name=vsink_01 tee. ! queue name=video02_queue ! glimagesink name=vsink_02"
完成!!
動作している送信機と受信機
ゴーグル化!
あとがき(この試作の利用?発展させる方向性)
・外部から映像を受け取って、受信機(2眼)で見るってのは応用が利きそう
⇒映像ソース側でフィルタとか加工すれば面白いVRコンテンツとか作れるかも
・今回はRTPだったりWiFiのローカルNWでのP2Pだったが、別の構成やGstremaerパイプラインを使うことで、
別の映像プロトコルつかったりインターネット経由で遠距離伝送もできそう。
・本物のVRゴーグルも使ってみたいなぁ、、
参照URL
■[1] RustでもGStreamer理解がしたい! その0 〜まずはGStreamerパイプラインを書こう 〜
https://qiita.com/alivelime/items/50d796c09baabb765625
■[2] Example Android App for AHCSRC
https://github.com/justinjoy/gst-android-camera