Stage Screen Sharing
概述
Fusion舞台畫面共享 是基於 Fusion舞台 範例。
這個文檔只專注於這個範例提供的主要的功能性,也就是共享您的電腦畫面的能力。
為了了解其他功能,請先參照到主要的,Fusion舞台頁面。
在程式碼註解中直接提供更多技術細節。
技術資訊
- 這個範例使用共享模式拓撲,
- 組建可用於PC、Mac及Meta Quest,
- 專案已透過Unity 2021.3.13f1、Fusion 1.1.3f 599、Photon Video 0.10 (Photon Voice 2.51)來開發,
- 支援2個虛擬人偶解決方案(自製簡單虛擬人偶及Ready Player Me 1.9.0虛擬人偶),
在您開始之前
為了運行範例:
在Photon引擎儀表板建立一個Fusion應用程式帳號,並將它貼上到Real Time設定中的
App Id Fusion
欄位(可從Fusion選單到達)。在Photon引擎儀表板建立一個Voice應用程式帳號,並將它貼上到Real Time設定中的
App Id Voice
欄位然後載入
AvatarSelection
場景並且按下Play
。
下載
版本 | 發布日期 | 下載 | ||
---|---|---|---|---|
0.0.19 | 2023年2月2日 | Fusion舞台畫面共享0.0.19組建92 |
下載二進位檔案
以下是舞台畫面共享客戶端的一個可用的示範版本:
以下是可用的針對Windows的Fusion舞台畫面共享記錄器:
處理輸入
桌面
鍵盤
- 移動:WASD或ZQSD以行走
- 旋轉:QE或AE以旋轉
滑鼠
- 移動:以滑鼠左鍵按一下,以顯示一個指標。您將放開時傳送到任何已接受的目標
- 旋轉:持續按住滑鼠右鍵,並且移動滑鼠以旋轉檢視點
- 移動及旋轉:持續按住滑鼠左右鍵以向前移動。您仍可以移動滑鼠以旋轉
- 拿取:將滑鼠放到物件上,並且使用滑鼠左鍵來拿取它。
Meta Quest
- 傳送:按下A、B、X、Y,或任何搖桿以顯示一個指標。您將放開時傳送到任何已接受的目標
- 觸碰(也就是針對聊天氣泡鎖定按鈕):簡單地將您的手放到按鈕上以切換它
- 拿取:首先將您的手放到物件上,然後使用控制器拿取按鈕來拿取它
資料夾架構
主要資料夾/Stage
含有所有特定於這個範例的元素。
資料夾/IndustriesComponents
含有與Fusion舞台範例或Fusion展示範例共享的元件。
/Photon
資料夾含有Fusion及Photon Voice SDK的一個特別版本,其中包含Photon Voice Video SDK。
/Photon/FusionXRShared
資料夾含有來自VR共享範例的裝備及拿取邏輯,其建立一個FusionXR共享輕量SDK,這可以與其他專案共享。
/Photon/FusionXRShared/Extensions
資料夾含有針對FusionXR共享的,針對可重新使用的功能比如已同步光線的,以及運動驗證等等的擴展程式
/Plugins
資料夾含有Ready Player Me SDK
/StreamingAssets
資料夾含有預先組建的ReadyPlayerMe虛擬人偶。如果您不想使用這些預先組建的虛擬人偶,它可以被自由地移除。
/XR
資料夾含有針對虛擬實境的設置檔案。
畫面共享特定元件是可用的:
- 在
/IndustriesComponents/Screenshare
中針對只顯示如何使用PhotonVideoSDK的指令碼 - 在
/Stage/Screen/Screensharing
針對特定到舞台範例的指令碼
架構概述
這個範例仰賴於一個Photon Video SDK的初代版本,其是Photon Voice SDK的一個額外部分。
在使用者在舞台範例中啟動的正常客戶端之外,希望共享它們的畫面的使用者必須啟動一個專用Windows應用程式「記錄器客戶端」,其控制它們希望共享哪些畫面,並且請求授權來展示它。
畫面捕捉是基於u視窗捕捉,其處理桌面影像的捕捉,並且將它應用到一個材質上。
然後,Photon影片SDK透過VoiceConnection
來處理這個影片串流(現在而言,在「串流」的意義下,我們仍然使用「聲音」的用語)。
為了請求授權在主要畫面上串流,使用了類似於舞台範例的參與者系統的授權系統:作為一個ScreenSharingAttendee
,您可以請求畫面共享存取,並且在舞台上的控制畫面提供一個ScreenShareRequestHandler
以驗證這些請求。
畫面共享
畫面共享是由u視窗捕捉來捕捉,並且透過Photon影片SDK來發送到其他客戶端。
影片SDK
Photon影片SDK是Photon聲音SDK的一個特別版本,其包含支援串流影片。
更多細節可在其專用的讀我答案中找到,其位於Photon/PhotonVoice/PhotonVideoSDK_README_v0.x.md
。
影片串流的捕捉,可以透過記錄器執行IVideoRecorderPusher
來完成,並且可以透過玩家執行IVideoPlayer
來處理重播。
u視窗捕捉
u視窗捕捉提供特定的視窗捕捉,或完整的桌面捕捉。在這個範例中,為了簡化,只支援完整的桌面捕捉。
uWindowCaptureRecorder
類別執行IVideoRecorderPusher
介面,其允許針對Photon影片SDK來收集幀。
為了啟用它,U_WINDOW_CAPTURE_RECORDER_ENABLE
必須被新增到定義符號。
影片串流
發射器
ScreenSharingEmitter
在允許連線畫面共享之前,首先等待Photon聲音連線的建立。
然後它等待u視窗捕捉準備好。然後以voiceConnection.VoiceClient.CreateLocalVoiceVideo
建立影片串流:從現在開始,記錄器將串流桌面捕捉。
接收器
ScreensharingReceiver
首先以OnRemoteVoiceInfoAction
回調來等待一個聲音客戶端的連線。
然後,如果是影片聲音,它以CreateVideoPlayerUnityTexture
來建立一個影片播放器。
而最後,當影片播放器準備好,它準備一個材料,其持有影片將以VideoTexture.Shader3D.MakeMaterial
來應用到的材質。
請注意,設置ScreensharingReceiver
為只是一次串流一個影片。為了串流多個影片,應該針對各個客戶端來建立不同的轉譯器。
Android著色器與URP、VR及單一通道相容
Photon影片SDK可以處理接收材料的建立,其將展示影片材質,並且SDK提供適用於這些材料的多種著色器,其針對Android而被包含。
然而舞台範例的Quest組建有著額外的要求:
- 它使用URP圖形管道
- 我們針對VR轉譯需要單一通道
Photon\PhotonVoice\PhotonVoiceApi\Platforms\Unity\Video\Resources\PhotonVoiceApi\GLES3\VideoTextureExt3D.shader
預設著色器在這些條件下不在Android運行,所以範例含有這個著色器的一個特定版本。
它的主要特性是需要在ScreensharingReceiver
中新增額外的專用程式碼,以便在各個更新期間將遺失的位置資料(localToWorldMatrix,在附有URP的GLSL著色器中不可用)轉傳到著色器。
在著色器中的註解提供了一些額外的細節及參照。
場景邏輯
針對正常客戶端(參與者)以及針對記錄器客戶端(為了在舞台上畫面上串流一個桌面),我們必須使用相同的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舞台頁面以取得更多細節。
當記錄器應用程式加入遊戲階段時,生成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
介面以取得更多細節。
在控制桌面上顯示第一個畫面共享請求。
當ScreenShareStatus
改變(舉例而言,當發言者驗證一個畫面共享請求),它被廣播到網路,這樣擁有畫面共享的客戶端可以改變其狀態。
因此,當畫面共享請求者接收到授權,它開始串流被選擇的桌面。
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參數:
Project Settings
/Player
:- 更改
Product name
:舉例而言,新增「記錄器」
- 更改
Project Settings
/Player
/Resolution and Presentation
/Resolution
- 全螢幕模式:已視窗化
- 預設畫面寬:640
- 預設畫面高:380
- 可調整大小:否
- 允許全螢幕:否
正常客戶端編譯
所以,為了編譯正常客戶端應用程式,您必須遵循3個步驟:
1/ 開啟StageAvatarSelection
場景:在LoadMainSceneInRecorderMode
遊戲物件上,取消勾選方框Is Recorder Compilation Mode
。
2/ 開啟StageWithScreenSharing
場景:在RigSelection
遊戲物件上,RecorderAppRigSelection
類別,設定App Kind
參數到Normal
。
RecorderAppRigSelection
負責根據正常/記錄器選擇,來設置場景。
3/ 更改一些Unity參數:
Project Settings
/Player
:- 更改
Product name
:舉例而言,新增「客戶端」
- 更改
Project Settings
/Player
/Resolution and Presentation
/Resolution
- 全螢幕模式:全螢幕視窗
- 可調整大小:是
- 允許全螢幕:是
第三方元件
- Oculus整合
- Oculus唇形同步
- Oculus範例框架手
- Ready player me
- 聲音
已知問題
- Quest:如果在使用者登入之前,畫面共享已經被初始化,那麼畫面共享的顯示可能很長或可能失敗。
更改記錄
- Fusion舞台0.0.20
- 第一個版本