Stage 스크린 쉐어링
개요
Fusion Stage 스크린 쉐어링은 Fusion Stage 샘플 기반입니다.
이 설명서는 이 샘플에서 제공하는 주요 기능, 즉 컴퓨터 화면을 공유하는 기능에만 초점을 맞춥니다.
다른 기능들을 이해하기 위해서, 먼저 메인 Fusion Stage 페이지 참고하세요.
상세한 기술 설명은 코드 주석으로 직접 제공되어 있습니다.
기술 정보
- 이 샘플은 공유 모드 토폴로지를 사용합니다,
- PC, Mac 및 Meta Quest용 빌드를 사용할 수 있습니다,
- 프로젝트는 유니티 2021.3.13f1, Fusion 1.1.3f 599, Photon Video 0.10 (Photon Voice 2.51)으로 개발되었습니다,
- 2개의 아바타 솔루션이 지원됩니다(홈메이드 심플 아바타 & Ready Player Me 1.9.0 아바타),
시작하기 전에
샘플 실행을 위해:
PhotonEngine 관리 화면에서 Fusion AppId를 생성 후 Real Time 설정(Fusion 메뉴에서 접근 가능)에서
App Id Fusion
필드에 붙여 넣습니다.PhotonEngine 관리 화면에서 Voice AppId를 생성 후 Real Time 설정(Fusion 메뉴에서 접근 가능)에서
App Id Voice
필드에 붙여 넣습니다.AvatarSelection
씬을 로드하고Play
를 누릅니다.
다운로드
버전 | 릴리즈 일자 | 다운로드 | ||
---|---|---|---|---|
0.0.19 | Feb 02, 2023 | Fusion Stage Screen Sharing 0.0.19 Build 92 |
바이너리 다운로드
Stage Screen Sharing 클라이언트의 데모 버전은 아래에서 다운로드할 수 있습니다:
- Meta Quest용 Fusion Stage Screen Sharing
- Windows 용 Fusion Stage Screen Sharing
- Mac용 Fusion Stage Screen Sharing
Windows용 Stage Screen Sharing Recorder는 다음과 같습니다:
입력 처리
데스크톱
키보드
- 이동 : WASD 또는 ZQSD를 이용하여 걷기
- 회전 : QE 또는 AE를 이용하여 회전
마우스
- 이동 : 마우스 왼쪽 버튼을 클릭하여 포인터를 표시합니다. 해제 시 승인된 대상을 텔레포트합니다
- 회전 : 마우스 오른쪽 버튼을 누른 채로 마우스를 움직여 시점을 회전합니다
- 이동 & 회전 : 앞으로 나아가려면 왼쪽 및 오른쪽 버튼을 모두 누른 상태로 유지합니다. 마우스를 계속 움직여 회전할 수 있습니다
- 잡기 : 마우스를 물체 위에 놓고 마우스 왼쪽 버튼을 사용하여 물체를 잡습니다.
Meta Quest
- 텔레포트 : A, B, X, Y 또는 임의의 스틱을 눌러 포인터를 표시합니다. 해제 시 승인된 대상을 텔레포트합니다
- 터치 (채팅 버블 잠금 버튼용) : 버튼 위에 손을 올려놓으면 전환됩니다
- 잡기 : 먼저 물체 위에 손을 얹고 컨트롤러 그립 버튼을 사용하여 잡습니다
폴더 구조
메인 폴더 /Stage
에는 이 샘플에 관련된 모든 요소가 포함되어 있습니다.
/IndustriesComponents
에는 Fusion Stage 샘플 또는 Fusion Expo 샘플과 공유되는 컴포넌트들이 포함되어 있습니다.
/Photon
폴더에는 Fusion과 Photon Voice Video SDK를 포함한 Photon Voice SDK의 특별 버전이 들어 있습니다.
/Photon/FusionXRShared
폴더에는 다른 프로젝트와 공유할 수 있는 FusionXRShared light SDK를 생성하는 VR 공유 샘플에서 가져온 리그 및 잡기 로직이 포함되어 있습니다.
/Photon/FusionXRShared/Extensions
폴더에 동기화된 광선, 이동 유효성 검사와 같은 재사용 가능한 FusionX에 대한 확장이 포함되어 있습니다...
/Plugins
폴더에는 Ready Player Me SDK가 들어 있습니다
/StreamingAssets
폴더에는 사전 구축된 ReadyPlayerMe 아바타가 포함되어 있습니다. 미리 제작된 아바타를 사용하고 싶지 않으면 자유롭게 제거할 수 있습니다.
/XR
폴더에는 가상 현실에 대한 구성 파일이 들어 있습니다.
화면 공유 관련 구성 요소를 사용할 수 있습니다:
/IndustriesComponents/Screenshare
에는 PhotonVideo 사용 방법만 표시하는 스크립트의 경우 SDK/Stage/Screen/Screensharing
에는 스테이지 샘플에 특화된 스크립트
아키텍처 개요
이 샘플은 Photon Voice SDK를 추가한 Photon Video SDK의 알파 버전에 의존합니다.
Stage 샘플에서 사용자가 시작한 일반 클라이언트 외에도 화면을 공유하려는 사용자는 공유할 화면을 제어하는 전용 Windows 애플리케이션 "Recorder 클라이언트"를 시작하고 이를 표시할 권한을 요청해야 합니다.
화면 캡처는 데스크톱 이미지의 캡처를 처리하여 텍스처에 적용하는 uWindowCapture를 기반으로 합니다.
그런 다음 Photon Video SDK는 VoiceConnection
을 통해 이 비디오 스트림을 처리합니다(현재는 "Stream"의 의미로 "Voice"라는 용어를 사용하고 있습니다).
메인 화면에서 스트리밍을 할 수 있는 권한을 요청하려면 스테이지 샘플의 참석자 시스템과 유사한 권한 시스템을 사용합니다: ScreenSharingAttendee
로 화면 공유 액세스를 요청하면, 그리고 스테이지의 제어 화면에는 이러한 요청을 확인할 수 있는 ScreenShareRequestHandler
가 제공됩니다.
화면 공유
화면 공유는 uWindowCapture로 화면이 캡처되고 PhotonVideo SDK를 통해 다른 클라이언트에게로 전송됩니다.
VideoSDK
Photon Video SDK는 비디오 스트리밍 지원을 포함한 Photon Voice SDK의 특별 버전입니다.
자세한 내용은 README에 있으며 Photon/PhotonVoice/PhotonVideoSDK_README_v0.x.md
위치에서 확인할 수 있습니다.
비디오 스트림의 캡처는 IVideoRecorderPusher
를 구현하는 레코더로 만들 수 있습니다 IVideoPlayer
를 구현하여 플레이백을 플레이어들이 다룰 수 있습니다.
uWindowCapture
uWindowCapture는 특정 창 캡처 또는 전체 데스크톱 캡처를 제공합니다. 이 예제에서는 단순화를 위해 전체 데스크톱 캡처만 지원됩니다.
uWindowCaptureRecorder
클래스에서 IVideoRecorderPusher
인터페이스를 구현하면 PhotonVideo SDK용 프레임을 수집할 수 있습니다.
사용하기 위해서, U_WINDOW_CAPTURE_RECORDER_ENABLE
을 정의된 심볼에 추가해야 합니다.
동영상 스트립
Emitter
ScreenSharingEmitter
는 먼저 Photon Voice 연결이 설정될 때까지 기다렸다가 화면 공유를 허용합니다.
그런 다음 uWindowCapture가 준비될 때까지 기다립니다. 그런 다음 voiceConnection.VoiceClient.CreateLocalVoiceVideo
으로 비디오 스트림이 생성됩니다: 이제부터 레코더가 데스크톱 캡처를 스트리밍 합니다.
Receiver
ScreensharingReceiver
는 먼저 OnRemoteVoiceInfoAction
콜백과 함께 음성 클라이언트의 연결을 기다립니다.
그런 다음 비디오 음성이면 CreateVideoPlayerUnityTexture
로 비디오 플레이어를 만듭니다.
그리고 마지막으로, 비디오 플레이어가 준비되면, VideoTexture.Shader3D.MakeMaterial
가 적용된 비디오 텍스처를 가진 머터리얼을 준비합니다.
ScreensharingReceiver
는 한 번에 하나의 비디오만 스트리밍하도록 구성되어 있습니다. 여러 비디오를 스트리밍 하려면 각 클라이언트에 대해 다른 렌더러를 만들어야 합니다.
URP, VR 및 싱글 패스와 호환되는 Android Shader
Photon Video SDK는 비디오 텍스처를 표시하는 수신 머터리얼의 생성을 처리할 수 있으며, SDK는 Android용으로 포함된 해당 재료에 적합한 몇 가지 셰이더를 제공합니다.
그러나 스테이지 샘플의 퀘스트 빌드에는 다음과 같은 추가 요구 사항이 있습니다:
- URP 그래픽 파이프라인을 사용합니다
- VR 렌더링을 위해서는 싱글 패스가 필요합니다
이 환경 기반으로 안드로이드에서는 Photon\PhotonVoice\PhotonVoiceApi\Platforms\Unity\Video\Resources\PhotonVoiceApi\GLES3\VideoTextureExt3D.shader
기본 셰이더가 작동하지 않으므로 샘플에 이 셰이더의 특정 버전이 포함되어 있습니다.
주요 특징은 매 업데이트 동안 누락된 위치 데이터(URP가 있는 GLSL 셰이더에서는 사용할 수 없는 로컬 ToWorldMatrix)를 셰이더로 전달하기 위해 ScreensharingReceiver
에 추가 전용 코드를 요구하는 것입니다.
셰이더의 주석은 몇 가지 추가 세부 정보와 참조를 제공합니다.
씬 로직
일반 클라이언트(참석자)와 레코더 클라이언트(무대 화면에서 데스크톱을 스트리밍 하기 위해)에 동일한 유니티 씬을 사용해야 합니다.
그래서 우리가 사용하고자 하는 클라이언트 모드에 따라 약간의 수정이 필요합니다.
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 페이지를 참조하시기 바랍니다.
The StageNetworkRigRecorder
프리팹은 세션에 레코드 신청자가 참여했을 때 스폰 됩니다.
이 프리팹은 [Networked]
변수 ScreenShareStatus
를 호스팅 하는 ScreenShareAttendee
클래스를 포함하고 있습니다.
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();
}
컴파일
일반 클라이언트(참석자)와 레코더 클라이언트(무대 화면에서 데스크톱을 스트리밍 하기 위해)에 동일한 유니티 씬을 사용합니다.
따라서 컴파일할 클라이언트에 따라 수동으로 수정해야 합니다.
Recorder 클라이언트 컴파일
따라서 레코더 애플리케이션을 컴파일하려면 다음 3단계를 수행해야 합니다:
1/ StageAvatarSelection
씬 열기 : LoadMainSceneInRecorderMode
게임 객체에서 Is Recorder Compilation Mode
확인란을 선택하면 아바타 선택 씬을 로드하지 않고 메인 씬을 직접 로드할 수 있습니다.
씬 목록은 일반 클라이언트와 레코더에 대해 동일해야 하므로 이 팁이 필요합니다.
2/ StageWithScreenSharing
씬 열기 : RigSelection
게임 객체인 RecorderAppRigSelection
클래스에서 App Kind
파라미터를 Recorder
로 설정합니다.
RecorderAppRigSelection
은 일반/녹음기 선택에 따라 씬을 구성하는 역할을 담당합니다.
3/ 일부 유니티 매개 변수 변경:
프로젝트 설정
/플레이어
:제품 이름
변경: 예를 들어 'Recorder' 추가
프로젝트 설정
/플레이어
/해상도 및 표시
/해상도
- 전체 화면 모드 : Windowed
- 기본 화면 폭 : 640
- 기본 화면 높이 : 380
- 크기 조정 가능 : No
- 전체 화면 허용 : No
일반 클라이언트 컴파일
따라서 일반 클라이언트 애플리케이션을 컴파일하려면 다음 3단계를 수행해야 합니다:
1/ StageAvatarSelection
씬 열기 : LoadMainSceneInRecorderMode
게임 객체에서 Is Recorder Compilation Mode
확인란의 선택을 취소합니다.
2/ StageWithScreenSharing
씬 열기 : RigSelection
게임 객체인 RecorderAppRigSelection
클래스에서 App Kind
파라미터를 Normal
로 설정합니다.
RecorderAppRigSelection
은 일반/녹음기 선택에 따라 씬을 구성하는 역할을 담당합니다.
3/ 일부 유니티 매개 변수 변경
프로젝트 설정
/플레이어
:제품 이름
변경 : 예를 들어 'Client' 추가
프로젝트 설정
/플레이어
/해상도 및 표시
/해상도
- 전체 화면 몯, : Fullscreen Windows
- 크기 조정 가능 : Yes
- 전체 화면 허용 : Yes
타사 컴포넌트
- Oculus Integration
- Oculus Lipsync
- Oculus 샘플 Framework
- Ready player me
- 사운드
알려진 문제점
- Quest : 사용자가 로그인하기 전에 화면 공유가 시작된 경우 화면 공유 표시가 길거나 실패할 수 있습니다.
Changelog
- Fusion Stage 0.0.20
- 첫 번째 버전