Stageの画面共有
Industries Circle の会員になると、スイート全体に加えて、専用のライセンス オプションが提供されます。
概要
Fusion Stage画面共有は、Fusion Stage のサンプルをベースにしています。
このドキュメントでは、このサンプルが提供する主な機能、つまりコンピュータの画面を共有する機能のみに焦点を当てています。
その他の機能を理解するためには、まずメインとなるFusion Stageのページを参照してください。
より技術的な詳細は、コードコメントに直接記載されています。
技術情報
- このサンプルは Shared Mode トポロジーを使用しています。
- PC、Mac、MetaQuest用のビルドがあります。
- このプロジェクトは、Unity 2021.3.13f1, Fusion 1.1.3f 599 と Photon voice 2.31 で開発されています。
- 2種類のアバター(自作のシンプルなアバターとReady Player Me 1.9.0アバター)に対応しています。
始める前に
サンプルを実行するには :
PhotonEngine Dashboard](https://dashboard.photonengine.com/en-us) で Fusion AppId を作成し、Real Time Settings (Fusion メニュー) の
App Id Fusion
欄に貼り付けます。PhotonEngine Dashboard で Voice AppId を作成し、Real Time Settings の
App Id Voice
欄に貼り付けます。次に、
AvatarSelection
シーンを読み込んで、Play
を押してください。
ダウンロード
バージョン | リリース日 | ダウンロード | ||
---|---|---|---|---|
0.0.19 | Feb 02, 2023 | Fusion Stage Screen Sharing 0.0.19 Build 92 |
バイナリのダウンロード
ステージ画面共有のデモ版は、以下からダウンロードできます。
入力処理
デスクトップ
キーボード
- 移動:WASD または ZQSD による歩行
- 回転: QE または AE で回転
マウス
- 移動:マウスを左クリックするとポインターが表示されます。ポインターを離すと、受け付けたターゲットにテレポートします。
- 回転 : マウスの右ボタンを押したまま、マウスを動かすと視点が回転します。
- 移動&回転 : 左ボタンと右ボタンを押したまま前進します。マウスを動かしても回転させることができます
- つかむ : マウスをオブジェクトの上に置き、マウスの左ボタンでつかみます。
メタクエスト
- テレポート : A、B、X、Y、またはいずれかのスティックを押してポインターを表示します。放す時に任意の受け入れられたターゲットにテレポートされます。
- タッチ (チャットバブルのロックボタンなど) : 単純にボタンに手をかざすとトグルします。
- 掴む:まず手をオブジェクトの上に置き、コントローラのグラブボタンを使用してそれを掴みます。
フォルダ構成
メインフォルダ /Stage
には、このサンプルに特化した全ての要素が含まれています。
Fusion Stage サンプル または Fusion Expo サンプル と共通のコンポーネントが入った /IndustriesComponents
フォルダーがあります。
/Photon
フォルダには、Fusionと、Photon Voice Video SDKを含む特別バージョンのPhoton Voice SDKが含まれています。
/Photon/FusionXRShared
フォルダには、VR共有サンプルから来るリグとグラブロジックが含まれており、他のプロジェクトと共有できるFusionXRShared light SDKが作成されています。
/Photon/FusionXRShared/Extensions
フォルダには、FusionXRSharedの拡張機能が入っており、同期光線、ロコモーション検証などの再利用可能な機能があります。
/Plugins
フォルダーには、Ready Player Me SDK が含まれています。
/StreamingAssets
フォルダには、あらかじめ作成されたReadyPlayerMeのアバターが格納されています。これらのアバターを使用しない場合は、自由に削除することができます。
/XR
フォルダにはバーチャルリアリティのための設定ファイルが含まれています。
スクリーンシェアリングに特化したコンポーネントが用意されています。
- PhotonVideoSDKの使用方法のみを表示するスクリプトは
/IndustriesComponents/Screenshare
にあります。 - ステージサンプルに特化したスクリプトは
/Stage/Screen/Screensharing
にあります。
アーキテクチャーの概要
本サンプルは、Photon Voice SDKに加え、Photon Video SDKのα版を使用しています。
画面共有を行うには、Stageサンプルでユーザが起動する通常のクライアントに加え、専用のWindowsアプリケーション「Recorder client」を起動し、共有したい画面を制御し、表示権限を要求する必要があります。
画面キャプチャは、uWindowCaptureをベースに、デスクトップ画像のキャプチャを行い、テクスチャに貼り付けます。
そして、Photon Video SDKは、VoiceConnectionを通じて、このビデオストリームを処理します(ここでは、"Voice "を "Stream "の意味で使用します)。
メイン画面でのストリーム配信の権限を要求するために、ステージサンプルのアテンディーシステムに似た権限システムが使用されます: ScreenSharingAttendee
として、画面共有アクセスを要求でき、ステージ上のコントロール画面はこれらのリクエストを検証するために ScreenShareRequestHandler
が提供されます。
画面共有
画面共有は、uWindowCaptureでキャプチャし、PhotonVideo SDKを通じて他のクライアントに送信されます。
Video SDK
Photon Video SDKは、Photon Voice SDKの特別バージョンで、ストリーミングビデオのサポートが含まれています。
詳細は、Photon/PhotonVoice/PhotonVideoSDK_README_v0.x.md
にある専用のREADMEに記載されています。
ビデオストリームのキャプチャは IVideoRecorderPusher
を実装したレコーダーで、再生は IVideoPlayer
を実装したプレイヤーで行うことができます。
uWindowCapture
uWindowCaptureは特定のウィンドウをキャプチャしたり、デスクトップ全体をキャプチャすることができます。このサンプルでは、簡略化のため、フルデスクトップキャプチャーのみをサポートしています。
IVideoRecorderPusher
インターフェースを実装した uWindowCaptureRecorder
クラスにより、PhotonVideo SDK 用にフレームを収集することができます。
これを有効にするには、U_WINDOW_CAPTURE_RECORDER_ENABLE
をdefine symbolsに追加する必要があります。
ビデオストリーム
エミッター
ScreenSharingEmitter
は、まずPhoton Voiceの接続が確立されるのを待ってから、スクリーンシェアリングの接続を許可します。
そして、uWindowCaptureの準備ができるのを待ちます。次に、voiceConnection.VoiceClient.CreateLocalVoiceVideo
でビデオストリームが作成されます。これ以降、レコーダーはデスクトップのキャプチャーのストリームを送信するようになります。
レシーバー
ScreensharingReceiver
は、まず OnRemoteVoiceInfoAction
コールバックで、音声クライアントの接続を待ちます。
次に、ビデオ音声の場合は CreateVideoPlayerUnityTexture
でビデオプレーヤーを作成します。
そして最後に、ビデオプレーヤーの準備ができたら VideoTexture.Shader3D.MakeMaterial
で映像が適用されるテクスチャを保持するマテリアルを用意します。
ScreensharingReceiver
は一度に一つのビデオしかストリーミングできないように設定されていることに注意してください。複数のビデオをストリーミングするには、クライアントごとに異なるレンダラーを作成する必要があります。
URP、VR、シングルパスに対応したAndroidシェーダー
Photon Video SDKは、ビデオテクスチャを表示する受信素材の作成を行うことができ、それらの素材に適したシェーダをいくつか提供しており、その中にはAndroid用も含まれています。
しかし、ステージサンプルのQuestビルドには、追加の要件があります。
- URPグラフィカルパイプラインを使用する
- VRレンダリングのためにシングルパスが必要
デフォルトのシェーダーである PhotonPhotonVoice@PhotonVoiceApi@PlatformsUnity@Video@Resources@PhotonVoiceApi@GLES3@VideoTextureExt3D.shader
はこの条件下ではAndroidで動かないため、サンプルにはこのシェーダーの特定バージョンが含まれています。
その主な特徴は、ScreensharingReceiver
に専用のコードを追加し、更新のたびに足りない位置情報データ(URP付きのGLSLシェーダでは利用できないlocalToWorldMatrix)をシェーダーに転送する必要があることです。
シェーダー内のコメントには、いくつかの追加的な詳細と参考文献が記載されています。
シーンロジック
通常のクライアント(参加者)とレコーダーのクライアント(ステージ画面のデスクトップを流す)には、同じUnityのシーンを使う必要があります。
そのため、使用するクライアントモードに応じて、いくつかの変更が必要です。
StageWithScreenSharing
のシーンでは、RigSelection
ゲームオブジェクトは RecorderAppRigSelection
クラスを含んでいます。
App Kind
パラメータは、アプリケーションを通常のクライアント(参加者)またはレコーダークライアント(ステージ画面上のデスクトップをストリーミングする)として設定するために使用されます。
C#
protected override void Awake()
{
...
if (appKind == AppKind.Normal) ConfigureAsNormalApp();
if (appKind == AppKind.Recorder) ConfigureAsRecorderApp();
}
コンパニオンアプリ (レコーダー)
ConfigureAsRecorderApp()
関数は、アプリケーションをレコーダーモードに設定する役割を担っているのです。それはつまり、
- デフォルトのユーザープレファブを、特定のエミッタープレファブに変更する。
- アンビエントサウンドを無効にする。
- 録音に必要なオブジェクト(特定のリグ、UI、エミッタ)を有効にし、無駄なオブジェクトを隠す。
- 参加者レジストリにアプリケーションを登録する。
レコーダー リグには ScreenShareManager
クラスが含まれています。
画面共有ボタンを表示し、メニューとのユーザー インタラクションに従って、またはscreenShareAttendee
値 (以下を参照) に従ってテキスト欄を更新する役割を担います。
画面共有リクエスト管理
ユーザーがステージ上でデスクトップ画面を共有する方法は、出席者がプレゼンターと会話するために行う方法に似ています。
詳しくは、メインの、Fusion Stageのページを参照してください。
レコーダーアプリケーションがセッションに参加すると、StageNetworkRigRecorder
プレハブが生成されます。
このプレハブには、ScreenShareAttendee
クラスが含まれており、[Networked]
変数 ScreenShareStatus
をホストしています。
C#
[Networked(OnChanged = nameof(OnChangedScreenShareStatus))]
public ScreenShareStatus ScreenShareStatus { get; set; }
このステータスは、以下を説明します:
- 画面共有の要求がまだなされていない場合。
- 画面共有の要求があった場合。
- リクエストが受け入れられたかどうか。
- 中止された場合。
- 拒否されたことを表します。
C#
public enum ScreenShareStatus
{
NoScreenShareRequested,
ScreenShareRequested,
ScreenShareInProgress,
ScreenShareStopped,
ScreenShareRejected
}
ステージ上のデスクに関連付けられた ScreenShareRequestHandler
は、画面共有を要求するユーザのリストを保存し、それに応じてUIを更新します。
詳しくは IScreenShare
インターフェースを参照してください。
最初の画面共有リクエストは、コントロールデスクに表示されます。
画面共有のステータスが変更されると(たとえば、プレゼンターが画面共有の要求を検証したとき)、画面共有を所有するクライアントがそのステータスを変更できるように、ネットワークにブロードキャストされます。
このように、画面共有のリクエスタが認証を受けると、選択されたデスクトップのストリーミングを開始します。
C#
if (ScreenShareStatus == ScreenShareStatus.ScreenShareInProgress)
{
Debug.Log("Starting Screen Sharing !");
screenSharingEmitter.ConnectScreenSharing();
}
コンパイル
通常のクライアント(参加者)とレコーダーのクライアント(ステージ画面にデスクトップを流す)には同じUnityのシーンを使用しています。
そのため、コンパイルするクライアントによって手動で修正する必要があります。
レコーダーのクライアントコンパイル
レコーダーアプリケーションをコンパイルするには、次の3つのステップを踏む必要があります。
1/ StageAvatarSelection
シーンを開く : LoadMainSceneInRecorderMode
ゲームオブジェクトで、Is Recorder Compilation Mode
ボックスをチェックすると、アバター選択シーンを読み込まずにメインシーンを直接読み込むことができます。
これは、シーンリストが通常のクライアント用とレコーダー用で同一である必要があるためです。
2/ StageWithScreenSharing
シーンを開きます。RigSelection
ゲームオブジェクトの RecorderAppRigSelection
クラスで、App Kind
パラメータを Recorder
にセットしてください。
RecorderAppRigSelection
は、ノーマル/レコーダーの選択に応じてシーンを構成する役割を担っています。
3/ Unityのパラメータを変更します。
プロジェクトの設定
/プレイヤー
:
-製品名
の変更 : 例えば 'Recorder' を追加します。プロジェクトの設定
/プレイヤー
/解像度と表示
/解像度
- フルスクリーンモード : ウィンドウモード
- デフォルトの画面幅 : 640
- デフォルトの画面の高さ : 380
- リサイズ可能 : いいえ
- フルスクリーンを許可する : いいえ
通常のクライアントのコンパイル
通常のクライアントアプリケーションをコンパイルするには、次の3つのステップを踏んでください。
1/
StageAvatarSelection
シーンを開く :LoadMainSceneInRecorderMode
ゲームオブジェクトで、Is Recorder Compilation Mode
ボックスをオフにします。2/
StageWithScreenSharing
シーンを開く :RigSelection
ゲームオブジェクトのRecorderAppRigSelection
クラスで、App Kind
パラメータをNormal
に設定します。
RecorderAppRigSelection
は、ノーマル/レコーダーの選択に応じてシーンを構成する役割を担っています。3/ Unityのパラメータを変更します。
プロジェクトの設定
/プレイヤー
:
-製品名
の変更 : 例えば 'Client' を追加します。プロジェクトの設定
/プレイヤー
/解像度と表示
/解像度
- フルスクリーンモード : フルスクリーンウィンドウ
- サイズ変更可能 : はい
- フルスクリーンを許可する : はい
サードパーティーコンポーネント
- Oculus Integration
- Oculus Lipsync
- Oculus Sample Framework hands
- Ready player me
- Sounds
Changelog
- Fusion Stage 0.0.19
- First version