スマホでNintendo Switchのゲームをする

スマホでNintendo Switchのゲームをする

前々回はNintendo Switch Pro ControllerのWeb対応。 前回はNintendo Switchゲーム画面のWeb対応。 今回はNintendo Switchゲーム音声のWeb対応。

何を作ろうとしてるか、だんだんワクワクしてきましたね?

前回の記事の最後に挙げたまとめです。その成果として表題の通り、スマホでNintendo Switchのゲームをすることができました。 そこまでの道筋です。

釣りタイトルっぽくなっているため、Nintendo Switch本体を持ってない人がスマホでNintendo Switchのゲームができると勘違いして迷い込んだ人はお帰りください

目次

Open 目次

  1. 振り返り
    1. Pro Controllerの模倣
    2. HDMI入力を扱う
    3. Switchの音声出力を取り込む
  2. 成果物
  3. まとめ

振り返り

これまでの振り返りです。 振り返りつつ、変更点を記します。

Pro Controllerの模倣

スマホでNintendo Switchを操作する 〜 USB GadgetでPro Controllerをシミュレート 〜 スマホでNintendo Switchを操作する 〜 USB GadgetでPro Controllerをシミュレート 〜

あつまれ どうぶつの森の配信が開始されましたね。いくつか積みゲーが増え始めたNintendo Switchも、また新たにゲームが増えて稼働時間が伸びる一方です。物をよくなくす身として、ゲームがしたいときにコントローラーが見つからないことは日常茶飯事です。 テレビやエアコンのリモコンもよく消えるので、スマートフォンから操作できるようにしています。スマート家電、文明の利器ですね。 コントローラーが...

この回ではNintendo Switch Pro Controllerの挙動を解析し、スマホから操作するところまでやりました。 libusbgxGstreamerとの相性を考え、GoやRustを使わずCで書いていたものの、h2oのWebSocket実装が未熟だっり、glibやlibevent使うの辛かったりしたのもあって、Cで書くのをやめて結局Goで書き直しました。 単純な実装ですが、コントローラーのシミュレーション部はGoモジュールとして分離して公開しました。

mzyy94/nscon: Nintendo Switch Controller simulator written in go - GitHub

HDMI入力を扱う

HDMI入力をRaspberry Piで駆使する HDMI入力をRaspberry Piで駆使する

昨今の衰えることのない技術トレンドに追従すべく、映像配信とかやりたいなーと思っていた2019年。 めっきり時間がなく何もできず、気付けば2020年になっていました。今年も時間がないだろうなぁと思っていたところ、連日の在宅勤務のおかげで通勤時間がゼロになり、余暇が生まれたので色々やってみることにしました。お題はHDMI入力で遊ぶ、です。...

HDMI入力基板を用いてHDMI入力を扱いました。 Raspberry Pi公式のCamera Moduleとして認識してくれるので、何もせずにH.264で入力を扱えて楽でしたが、これはこれで問題を抱えていました。 再接続時に問題があることがこの時点ではわかっていたんですが、もっと使い込んでいくと入力解像度がおかしくなるなど、さらに問題があることがわかりました。

使用したHDMI入力基板はTC358743XBGというチップを使ってHDMI入力をCSI2に変換していると紹介しました。 このTC358743XBGはLinuxにドライバがあり、Camera Moduleのドライバを用いずにVideo4Linux2のデバイスとして認識させることができます。

linux/tc358743.c at v4.19 · torvalds/linux

このドライバを使うことで、入力機器が転送可能な映像の種類を記すEDIDを扱え、入力解像度をはじめとする諸問題も解決できます。

Raspberry Piでこのドライバを用いるには、デバイスツリーにtc358743を認識させるだけです。 /boot/config.txtdtoverlay=tc358743を追記し、再起動することでドライバが読み込まれます。

pi@raspberrypi:~ $ dmesg | grep tc358743
[    5.718785] tc358743 0-000f: tc358743 found @ 0x1e (bcm2835 I2C adapter)
pi@raspberrypi:~ $ lsmod | grep tc358743
tc358743               40960  1
v4l2_dv_timings        36864  2 bcm2835_unicam,tc358743
v4l2_fwnode            20480  2 bcm2835_unicam,tc358743
v4l2_common            16384  3 bcm2835_unicam,bcm2835_v4l2,tc358743
videodev              200704  9 bcm2835_unicam,v4l2_fwnode,bcm2835_codec,v4l2_common,videobuf2_common,bcm2835_v4l2,v4l2_mem2mem,videobuf2_v4l2,tc358743
media                  36864  5 bcm2835_unicam,bcm2835_codec,videodev,v4l2_mem2mem,tc358743

これだけでは入力映像を扱えず、EDIDを機器側に通知して初めて使えるので、ドライバが読み込まれる度にEDIDをセットする必要があります。 このために用意した720P30EDID.txtをダウンロードし、以下のようにEDIDのセットを行うことで、V4L2で1280x720のRAW映像を扱えるようになります。

v4l2-ctl --set-edid=file=720P30EDID.txt
v4l2-ctl --set-dv-bt-timings query

繋がっているHDMI入力の情報はv4l2-ctl --query-dv-timingsで見られます。

結果としてRaspberry PiのCamera Moduleとしては認識しなくなったため、H.264圧縮はされず、YUVのRAW映像としてしか取り込めません。 H.264で遅延の少ない映像を得るにはハードウェアエンコーダーを利用する必要があります。 しかし、このドライバを用いている時は、先の記事で紹介したomxh264encは使えないため、v4l2h264encを使います。

RTPで送信する例は、こんな感じです。

gst-launch-1.0 v4l2src ! video/x-raw,width=1280,height=720,framerate=30/1 ! v4l2h264enc extra-controls="encode,h264_profile=1,h264_level=12;" ! video/x-h264,width=1280,height=720,stream-format=byte-stream,profile=constrained-baseline ! h264parse config-interval=-1 ! rtph264pay pt=96 ! udpsink host=mzyy94.local port=5678

Switchの音声出力を取り込む

UAC GadgetでNintendo Switchの音声出力をRaspberry Piに取り込む UAC GadgetでNintendo Switchの音声出力をRaspberry Piに取り込む

前回の記事 でHDMI映像入力をRaspberry Piで扱う方法を紹介し、その最後に音声の取り込みについて、まだ課題が残っていると書きました。 HDMI入力からの音声取り込みといった、本質的な課題の解決を試みているものの、なかなかに難しい問題に直面しているので、対象を限定して部分的解決に挑みます。主に今HDMI入力の対象として使おうと思っているデバイスは、Nintendo Switchです。...

UAC Gadgetでオーディオデバイスをシミュレートし、ALSA経由で取り込んでWebRTCでブラウザで見られるようにしました。 この時は、GstreamerのWebRTCを用いていましたが、WebRTCのSDPのネゴシエーションに不備があるなど、これも問題を抱えていました。 そのため、iOS SafariやAndroid Chromeなどでは映像と音声が再生されないなどの問題がありました。

Gstreamerはv4l2srcからHDMI入力を取り込み、v4l2h264encでH.264にエンコードするまでを任せ、WebRTCは別のソフトウェアを使うことにしました。 OSSのWebRTCバックエンドは、Goで実装されたPionが有名です。

pion/webrtc: Pure Go implementation of the WebRTC API

以前から使ってみたい興味はあったので、これを用いてWebRTCで転送するようにしました。 exampleにあるコードそのままではコーデック情報が正しく指定できなかったため、SDPをちゃんと読む処理を加えています。 また、GoでGstreamerを扱うため、ある程度必要なものが揃ったバインディングであるnotedit/gstを用いました。

成果物

これまでの成果を全部くっつけたものです。 遅延は0.2秒程度あるものの、どうぶつの森であれば十分にプレイできる程度です。 難点はNintendo Switchを遠隔でスリープ復帰できないので、スリープを解除した状態でDockに入れる必要があることくらいで、他は十分に求めるレベルまで達しています。

mzyy94/ns-remote: Play Nintendo Switch anyware

必要なハードウェアが多いですが、GPLv3ライセンスのもと公開しているので、よかったら遊んでみてください。

まとめ

これで湯船に浸かりながらどうぶつの森が遊べるようになりました。

WebRTCとWebSocketで実装してあるので、デバイスに依存せず、例えばWebXR/WebVRとの組み合わせもできるので、幅広い活用ができそうです。 良い自粛のお供ができました。

Related Posts

ドイツのトリ in Splatoon 2

ドイツのトリ in Splatoon 2

Q. なんやこれA. ドイツのトリ Advent Calendar 2017 - Adventar の18日目の記事。インターネットの悪いおたくたちの間で局所的に流行しているドイツのトリ。...

read more
スマホでNintendo Switchを操作する 〜 USB GadgetでPro Controllerをシミュレート 〜

スマホでNintendo Switchを操作する 〜 USB GadgetでPro Controllerをシミュレート 〜

あつまれ どうぶつの森の配信が開始されましたね。いくつか積みゲーが増え始めたNintendo Switchも、また新たにゲームが増えて稼働時間が伸びる一方です。物をよくなくす身として、ゲームがした...

read more
ブラウザでNintendo SwitchのJoy-Conの色を変える

ブラウザでNintendo SwitchのJoy-Conの色を変える

昨今、入手困難となっているNintendo Switchは、3年前のスプラトゥーン2セットモデルが発売された時も激戦でした。 各種通販サイトを廻り、運良く発売日に手に入れられた喜びは今でも鮮明に覚えて...

read more
Raspberry Pi2にOSMC入れてKodi(旧:XBMC)日本語化するまで

Raspberry Pi2にOSMC入れてKodi(旧:XBMC)日本語化するまで

今月頭の発表で一気に盛り上がりを見せた Raspberry Pi 2 Model B 。もちろん発売日に購入しました。 手元にはRaspberry Pi BとGalileo Gen2の2つのLinux...

read more
KodiとChinachuで地デジLive視聴 on Raspberry Pi2 w/ OSMC

KodiとChinachuで地デジLive視聴 on Raspberry Pi2 w/ OSMC

どうも、Raspberry Pi2で遊ぶ毎日が続いております。 Raspberry Pi model B(2ではない)にRaspbmcを入れて昨年の夏頃からChinachu経由で地上デジタル放送を視聴...

read more
KodiでChinachuの録画を観るAdd-on作った

KodiでChinachuの録画を観るAdd-on作った

Raspberry Pi2でKodi(旧:XBMC)が快適に動き、地デジのLIVE視聴環境として優れているので、 Chinachuの本領である録画した動画の視聴したみが高まってきました。Kodiに...

read more
無印良品で買えるRaspberry Pi2にぴったりのケース

無印良品で買えるRaspberry Pi2にぴったりのケース

Raspberry Pi2を発売日に2つ注文したものの、ケースを準備していなかったので手軽に買えるRaspberry Piにぴったりの入れ物はないかと 近所のショッピングモールを回ったところ、無印良品...

read more
HDMI入力をRaspberry Piで駆使する

HDMI入力をRaspberry Piで駆使する

昨今の衰えることのない技術トレンドに追従すべく、映像配信とかやりたいなーと思っていた2019年。 めっきり時間がなく何もできず、気付けば2020年になっていました。今年も時間がないだろうなぁと思っ...

read more
UAC GadgetでNintendo Switchの音声出力をRaspberry Piに取り込む

UAC GadgetでNintendo Switchの音声出力をRaspberry Piに取り込む

前回の記事 でHDMI映像入力をRaspberry Piで扱う方法を紹介し、その最後に音声の取り込みについて、まだ課題が残っていると書きました。 HDMI入力からの音声取り込みといった、本質的な課題の...

read more
LibreELECで地デジを楽しむためにMirakurunとEPGStationを一発で動かす

LibreELECで地デジを楽しむためにMirakurunとEPGStationを一発で動かす

地上デジタル放送をRaspberry Piで視聴する定番の組み合わせを、ノーコード・コマンドライン操作なしに、すなわち一発でセットアップできるようにした。...

read more
ShapewaysでreTerminal用の電子基板ケースを3Dプリントした

ShapewaysでreTerminal用の電子基板ケースを3Dプリントした

reTerminal がSeeedから発表されたのは2021年の4月のこと。 Raspberry Pi CM4にディスプレイを搭載し、立派なケースに収められてすぐに使えるように作られているとても魅力あ...

read more
Raspberry Pi CM4とCSI-2接続HDMI入力基板で音も取る

Raspberry Pi CM4とCSI-2接続HDMI入力基板で音も取る

2年前に投稿した HDMI入力をRaspberry Piで取り込む記事 では映像しか取得していませんでしたが、このHDMI入力基板には音声も取り込めるチップ TC358743 が搭載されています。 取...

read more
中華10GbEスイッチNetcore GS6を運用して1ヶ月たったレビュー

中華10GbEスイッチNetcore GS6を運用して1ヶ月たったレビュー

春に新居に越してからベストエフォートで10Gbpsのインターネット回線を引き込み利用している。 リビングに光コンセントを設置し、ONUに自作ルーターにNASやら母艦やらを集中してリビングに設置していた...

read more