@yang__yj/pixelstreaming-core 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cspell.json +48 -0
- package/.eslintignore +8 -0
- package/.eslintrc.js +8 -0
- package/.prettierignore +0 -0
- package/.prettierrc.json +6 -0
- package/coverage/clover.xml +3480 -0
- package/coverage/coverage-final.json +62 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +356 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/src/AFK/AFKController.ts.html +559 -0
- package/coverage/lcov-report/src/AFK/index.html +116 -0
- package/coverage/lcov-report/src/Config/Config.ts.html +2764 -0
- package/coverage/lcov-report/src/Config/SettingBase.ts.html +280 -0
- package/coverage/lcov-report/src/Config/SettingFlag.ts.html +382 -0
- package/coverage/lcov-report/src/Config/SettingNumber.ts.html +418 -0
- package/coverage/lcov-report/src/Config/SettingOption.ts.html +424 -0
- package/coverage/lcov-report/src/Config/SettingText.ts.html +331 -0
- package/coverage/lcov-report/src/Config/index.html +191 -0
- package/coverage/lcov-report/src/DataChannel/DataChannelController.ts.html +499 -0
- package/coverage/lcov-report/src/DataChannel/DataChannelSender.ts.html +262 -0
- package/coverage/lcov-report/src/DataChannel/InitialSettings.ts.html +268 -0
- package/coverage/lcov-report/src/DataChannel/LatencyTestResults.ts.html +313 -0
- package/coverage/lcov-report/src/DataChannel/index.html +161 -0
- package/coverage/lcov-report/src/FreezeFrame/FreezeFrame.ts.html +427 -0
- package/coverage/lcov-report/src/FreezeFrame/FreezeFrameController.ts.html +427 -0
- package/coverage/lcov-report/src/FreezeFrame/index.html +131 -0
- package/coverage/lcov-report/src/Inputs/FakeTouchController.ts.html +682 -0
- package/coverage/lcov-report/src/Inputs/GamepadController.ts.html +985 -0
- package/coverage/lcov-report/src/Inputs/HoveringMouseEvents.ts.html +688 -0
- package/coverage/lcov-report/src/Inputs/InputClassesFactory.ts.html +505 -0
- package/coverage/lcov-report/src/Inputs/KeyboardController.ts.html +1048 -0
- package/coverage/lcov-report/src/Inputs/LockedMouseEvents.ts.html +946 -0
- package/coverage/lcov-report/src/Inputs/MouseButtons.ts.html +160 -0
- package/coverage/lcov-report/src/Inputs/MouseController.ts.html +1171 -0
- package/coverage/lcov-report/src/Inputs/SpecialKeyCodes.ts.html +133 -0
- package/coverage/lcov-report/src/Inputs/TouchController.ts.html +712 -0
- package/coverage/lcov-report/src/Inputs/XRGamepadController.ts.html +463 -0
- package/coverage/lcov-report/src/Inputs/index.html +266 -0
- package/coverage/lcov-report/src/Logger/Logger.ts.html +325 -0
- package/coverage/lcov-report/src/Logger/index.html +116 -0
- package/coverage/lcov-report/src/PeerConnectionController/AggregatedStats.ts.html +1018 -0
- package/coverage/lcov-report/src/PeerConnectionController/CandidatePairStats.ts.html +136 -0
- package/coverage/lcov-report/src/PeerConnectionController/CandidateStat.ts.html +124 -0
- package/coverage/lcov-report/src/PeerConnectionController/DataChannelStats.ts.html +136 -0
- package/coverage/lcov-report/src/PeerConnectionController/InboundRTPStats.ts.html +547 -0
- package/coverage/lcov-report/src/PeerConnectionController/OutBoundRTPStats.ts.html +163 -0
- package/coverage/lcov-report/src/PeerConnectionController/PeerConnectionController.ts.html +1795 -0
- package/coverage/lcov-report/src/PeerConnectionController/SessionStats.ts.html +115 -0
- package/coverage/lcov-report/src/PeerConnectionController/StreamStats.ts.html +118 -0
- package/coverage/lcov-report/src/PeerConnectionController/index.html +236 -0
- package/coverage/lcov-report/src/PixelStreaming/PixelStreaming.ts.html +2269 -0
- package/coverage/lcov-report/src/PixelStreaming/index.html +116 -0
- package/coverage/lcov-report/src/UI/OnScreenKeyboard.ts.html +376 -0
- package/coverage/lcov-report/src/UI/index.html +116 -0
- package/coverage/lcov-report/src/UeInstanceMessage/ResponseController.ts.html +226 -0
- package/coverage/lcov-report/src/UeInstanceMessage/SendDescriptorController.ts.html +346 -0
- package/coverage/lcov-report/src/UeInstanceMessage/SendMessageController.ts.html +364 -0
- package/coverage/lcov-report/src/UeInstanceMessage/StreamMessageController.ts.html +862 -0
- package/coverage/lcov-report/src/UeInstanceMessage/ToStreamerMessagesController.ts.html +271 -0
- package/coverage/lcov-report/src/UeInstanceMessage/TwoWayMap.ts.html +241 -0
- package/coverage/lcov-report/src/UeInstanceMessage/index.html +191 -0
- package/coverage/lcov-report/src/Util/CoordinateConverter.ts.html +952 -0
- package/coverage/lcov-report/src/Util/EventEmitter.ts.html +1705 -0
- package/coverage/lcov-report/src/Util/EventListenerTracker.ts.html +172 -0
- package/coverage/lcov-report/src/Util/FileUtil.ts.html +505 -0
- package/coverage/lcov-report/src/Util/WebGLUtils.ts.html +232 -0
- package/coverage/lcov-report/src/Util/WebXRUtils.ts.html +160 -0
- package/coverage/lcov-report/src/Util/index.html +191 -0
- package/coverage/lcov-report/src/VideoPlayer/StreamController.ts.html +349 -0
- package/coverage/lcov-report/src/VideoPlayer/VideoPlayer.ts.html +799 -0
- package/coverage/lcov-report/src/VideoPlayer/index.html +131 -0
- package/coverage/lcov-report/src/WebRtcPlayer/WebRtcPlayerController.ts.html +6199 -0
- package/coverage/lcov-report/src/WebRtcPlayer/index.html +116 -0
- package/coverage/lcov-report/src/WebSockets/MessageReceive.ts.html +352 -0
- package/coverage/lcov-report/src/WebSockets/MessageSend.ts.html +604 -0
- package/coverage/lcov-report/src/WebSockets/SignallingProtocol.ts.html +622 -0
- package/coverage/lcov-report/src/WebSockets/WebSocketController.ts.html +844 -0
- package/coverage/lcov-report/src/WebSockets/index.html +161 -0
- package/coverage/lcov-report/src/WebXR/WebXRController.ts.html +1042 -0
- package/coverage/lcov-report/src/WebXR/index.html +116 -0
- package/coverage/lcov-report/src/__test__/index.html +161 -0
- package/coverage/lcov-report/src/__test__/mockMediaStream.ts.html +457 -0
- package/coverage/lcov-report/src/__test__/mockRTCPeerConnection.ts.html +1126 -0
- package/coverage/lcov-report/src/__test__/mockRTCRtpReceiver.ts.html +151 -0
- package/coverage/lcov-report/src/__test__/mockWebSocket.ts.html +475 -0
- package/coverage/lcov-report/src/index.html +116 -0
- package/coverage/lcov-report/src/pixelstreamingfrontend.ts.html +232 -0
- package/coverage/lcov.info +6458 -0
- package/jest.config.js +18 -0
- package/package.json +46 -18
- package/readme.md +15 -0
- package/src/AFK/AFKController.test.ts +162 -0
- package/src/AFK/AFKController.ts +158 -0
- package/src/Config/Config.test.ts +222 -0
- package/src/Config/Config.ts +909 -0
- package/src/Config/SettingBase.ts +65 -0
- package/src/Config/SettingFlag.ts +99 -0
- package/src/Config/SettingNumber.ts +111 -0
- package/src/Config/SettingOption.ts +124 -0
- package/src/Config/SettingText.ts +82 -0
- package/src/DataChannel/DataChannelController.ts +138 -0
- package/src/DataChannel/DataChannelLatencyTestController.ts +129 -0
- package/src/DataChannel/DataChannelLatencyTestResults.ts +67 -0
- package/src/DataChannel/DataChannelSender.ts +59 -0
- package/src/DataChannel/InitialSettings.ts +61 -0
- package/src/DataChannel/LatencyTestResults.ts +76 -0
- package/src/FreezeFrame/FreezeFrame.ts +114 -0
- package/src/FreezeFrame/FreezeFrameController.ts +114 -0
- package/src/Inputs/FakeTouchController.ts +199 -0
- package/src/Inputs/GamepadController.ts +300 -0
- package/src/Inputs/GamepadTypes.ts +10 -0
- package/src/Inputs/HoveringMouseEvents.ts +192 -0
- package/src/Inputs/IMouseEvents.ts +64 -0
- package/src/Inputs/ITouchController.ts +29 -0
- package/src/Inputs/InputClassesFactory.ts +140 -0
- package/src/Inputs/KeyboardController.ts +318 -0
- package/src/Inputs/LockedMouseEvents.ts +287 -0
- package/src/Inputs/MouseButtons.ts +25 -0
- package/src/Inputs/MouseController.ts +362 -0
- package/src/Inputs/SpecialKeyCodes.ts +16 -0
- package/src/Inputs/TouchController.ts +253 -0
- package/src/Inputs/XRGamepadController.ts +126 -0
- package/src/Logger/Logger.ts +80 -0
- package/src/PeerConnectionController/AggregatedStats.ts +311 -0
- package/src/PeerConnectionController/CandidatePairStats.ts +17 -0
- package/src/PeerConnectionController/CandidateStat.ts +13 -0
- package/src/PeerConnectionController/CodecStats.ts +19 -0
- package/src/PeerConnectionController/DataChannelStats.ts +17 -0
- package/src/PeerConnectionController/InboundRTPStats.ts +154 -0
- package/src/PeerConnectionController/InboundTrackStats.ts +34 -0
- package/src/PeerConnectionController/OutBoundRTPStats.ts +26 -0
- package/src/PeerConnectionController/PeerConnectionController.ts +563 -0
- package/src/PeerConnectionController/SessionStats.ts +10 -0
- package/src/PeerConnectionController/StreamStats.ts +11 -0
- package/src/PixelStreaming/PixelStreaming.test.ts +624 -0
- package/src/PixelStreaming/PixelStreaming.ts +847 -0
- package/src/UI/OnScreenKeyboard.ts +97 -0
- package/src/UeInstanceMessage/ResponseController.ts +47 -0
- package/src/UeInstanceMessage/SendMessageController.ts +154 -0
- package/src/UeInstanceMessage/StreamMessageController.ts +233 -0
- package/src/UeInstanceMessage/ToStreamerMessagesController.ts +62 -0
- package/src/Util/CoordinateConverter.ts +289 -0
- package/src/Util/EventEmitter.ts +595 -0
- package/src/Util/EventListenerTracker.ts +29 -0
- package/src/Util/FileUtil.ts +140 -0
- package/src/Util/RTCUtils.ts +41 -0
- package/src/Util/WebGLUtils.ts +49 -0
- package/src/Util/WebXRUtils.ts +25 -0
- package/src/VideoPlayer/StreamController.ts +89 -0
- package/src/VideoPlayer/VideoPlayer.ts +246 -0
- package/src/WebRtcPlayer/WebRtcPlayerController.ts +2144 -0
- package/src/WebSockets/MessageReceive.ts +89 -0
- package/src/WebSockets/MessageSend.ts +185 -0
- package/src/WebSockets/SignallingProtocol.ts +180 -0
- package/src/WebSockets/WebSocketController.ts +267 -0
- package/src/WebXR/WebXRController.ts +319 -0
- package/src/__test__/mockMediaStream.ts +124 -0
- package/src/__test__/mockRTCPeerConnection.ts +347 -0
- package/src/__test__/mockRTCRtpReceiver.ts +22 -0
- package/src/__test__/mockWebSocket.ts +130 -0
- package/src/pixelstreamingfrontend.ts +50 -0
- package/tsconfig.jest.json +8 -0
- package/tsconfig.json +24 -0
- package/webpack.common.js +35 -0
- package/webpack.dev.js +35 -0
- package/webpack.prod.js +36 -0
- package/yang__yj-pixelstreaming-core-1.0.1.tgz +0 -0
- /package/{library/dist → dist}/lib-pixelstreamingfrontend.esm.js +0 -0
- /package/{library/dist → dist}/lib-pixelstreamingfrontend.js +0 -0
- /package/{library/types → types}/AFK/AFKController.d.ts +0 -0
- /package/{library/types → types}/Config/Config.d.ts +0 -0
- /package/{library/types → types}/Config/SettingBase.d.ts +0 -0
- /package/{library/types → types}/Config/SettingFlag.d.ts +0 -0
- /package/{library/types → types}/Config/SettingNumber.d.ts +0 -0
- /package/{library/types → types}/Config/SettingOption.d.ts +0 -0
- /package/{library/types → types}/Config/SettingText.d.ts +0 -0
- /package/{library/types → types}/DataChannel/DataChannelController.d.ts +0 -0
- /package/{library/types → types}/DataChannel/DataChannelSender.d.ts +0 -0
- /package/{library/types → types}/DataChannel/InitialSettings.d.ts +0 -0
- /package/{library/types → types}/DataChannel/LatencyTestResults.d.ts +0 -0
- /package/{library/types → types}/FreezeFrame/FreezeFrame.d.ts +0 -0
- /package/{library/types → types}/FreezeFrame/FreezeFrameController.d.ts +0 -0
- /package/{library/types → types}/Inputs/FakeTouchController.d.ts +0 -0
- /package/{library/types → types}/Inputs/GamepadController.d.ts +0 -0
- /package/{library/types → types}/Inputs/GamepadTypes.d.ts +0 -0
- /package/{library/types → types}/Inputs/HoveringMouseEvents.d.ts +0 -0
- /package/{library/types → types}/Inputs/IMouseEvents.d.ts +0 -0
- /package/{library/types → types}/Inputs/ITouchController.d.ts +0 -0
- /package/{library/types → types}/Inputs/InputClassesFactory.d.ts +0 -0
- /package/{library/types → types}/Inputs/KeyboardController.d.ts +0 -0
- /package/{library/types → types}/Inputs/LockedMouseEvents.d.ts +0 -0
- /package/{library/types → types}/Inputs/MouseButtons.d.ts +0 -0
- /package/{library/types → types}/Inputs/MouseController.d.ts +0 -0
- /package/{library/types → types}/Inputs/SpecialKeyCodes.d.ts +0 -0
- /package/{library/types → types}/Inputs/TouchController.d.ts +0 -0
- /package/{library/types → types}/Inputs/XRGamepadController.d.ts +0 -0
- /package/{library/types → types}/Logger/Logger.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/AggregatedStats.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/CandidatePairStats.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/CandidateStat.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/CodecStats.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/DataChannelStats.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/InboundRTPStats.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/InboundTrackStats.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/OutBoundRTPStats.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/PeerConnectionController.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/SessionStats.d.ts +0 -0
- /package/{library/types → types}/PeerConnectionController/StreamStats.d.ts +0 -0
- /package/{library/types → types}/PixelStreaming/PixelStreaming.d.ts +0 -0
- /package/{library/types → types}/UI/OnScreenKeyboard.d.ts +0 -0
- /package/{library/types → types}/UeInstanceMessage/ResponseController.d.ts +0 -0
- /package/{library/types → types}/UeInstanceMessage/SendDescriptorController.d.ts +0 -0
- /package/{library/types → types}/UeInstanceMessage/SendMessageController.d.ts +0 -0
- /package/{library/types → types}/UeInstanceMessage/StreamMessageController.d.ts +0 -0
- /package/{library/types → types}/UeInstanceMessage/ToStreamerMessagesController.d.ts +0 -0
- /package/{library/types → types}/UeInstanceMessage/TwoWayMap.d.ts +0 -0
- /package/{library/types → types}/Util/CoordinateConverter.d.ts +0 -0
- /package/{library/types → types}/Util/EventEmitter.d.ts +0 -0
- /package/{library/types → types}/Util/EventListenerTracker.d.ts +0 -0
- /package/{library/types → types}/Util/FileUtil.d.ts +0 -0
- /package/{library/types → types}/Util/WebGLUtils.d.ts +0 -0
- /package/{library/types → types}/Util/WebXRUtils.d.ts +0 -0
- /package/{library/types → types}/VideoPlayer/StreamController.d.ts +0 -0
- /package/{library/types → types}/VideoPlayer/VideoPlayer.d.ts +0 -0
- /package/{library/types → types}/WebRtcPlayer/WebRtcPlayerController.d.ts +0 -0
- /package/{library/types → types}/WebSockets/MessageReceive.d.ts +0 -0
- /package/{library/types → types}/WebSockets/MessageSend.d.ts +0 -0
- /package/{library/types → types}/WebSockets/SignallingProtocol.d.ts +0 -0
- /package/{library/types → types}/WebSockets/WebSocketController.d.ts +0 -0
- /package/{library/types → types}/WebXR/WebXRController.d.ts +0 -0
- /package/{library/types → types}/pixelstreamingfrontend.d.ts +0 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
import { Logger } from '../Logger/Logger';
|
|
4
|
+
import * as MessageReceive from './MessageReceive';
|
|
5
|
+
import * as MessageSend from './MessageSend';
|
|
6
|
+
import { SignallingProtocol } from './SignallingProtocol';
|
|
7
|
+
|
|
8
|
+
// declare the new method for the websocket interface
|
|
9
|
+
declare global {
|
|
10
|
+
interface WebSocket {
|
|
11
|
+
onmessagebinary?(event?: MessageEvent): void;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The controller for the WebSocket and all associated methods
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export class WebSocketController {
|
|
20
|
+
WS_OPEN_STATE = 1;
|
|
21
|
+
webSocket: WebSocket;
|
|
22
|
+
onOpen: EventTarget;
|
|
23
|
+
onClose: EventTarget;
|
|
24
|
+
signallingProtocol: SignallingProtocol;
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
this.onOpen = new EventTarget();
|
|
28
|
+
this.onClose = new EventTarget();
|
|
29
|
+
this.signallingProtocol = new SignallingProtocol();
|
|
30
|
+
SignallingProtocol.setupDefaultHandlers(this);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 连接发信服务器
|
|
35
|
+
* @param connectionURL——发信服务器的地址
|
|
36
|
+
* @returns—是否存在连接
|
|
37
|
+
*/
|
|
38
|
+
connect(connectionURL: string): boolean {
|
|
39
|
+
Logger.Log(Logger.GetStackTrace(), connectionURL, 6);
|
|
40
|
+
try {
|
|
41
|
+
this.webSocket = new WebSocket(connectionURL);
|
|
42
|
+
this.webSocket.onopen = (event) => this.handleOnOpen(event);
|
|
43
|
+
this.webSocket.onerror = () => this.handleOnError();
|
|
44
|
+
this.webSocket.onclose = (event) => this.handleOnClose(event);
|
|
45
|
+
this.webSocket.onmessage = (event) => this.handleOnMessage(event);
|
|
46
|
+
this.webSocket.onmessagebinary = (event) =>
|
|
47
|
+
this.handleOnMessageBinary(event);
|
|
48
|
+
return true;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
Logger.Error(error, error);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 处理以二进制形式接收消息时发生的情况
|
|
57
|
+
* @param event - Message Received
|
|
58
|
+
*/
|
|
59
|
+
handleOnMessageBinary(event: MessageEvent) {
|
|
60
|
+
// if the event is empty return
|
|
61
|
+
if (!event || !event.data) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// handle the binary and then handle the message
|
|
66
|
+
event.data
|
|
67
|
+
.text()
|
|
68
|
+
.then((messageString: unknown) => {
|
|
69
|
+
// build a new message
|
|
70
|
+
const constructedMessage = new MessageEvent(
|
|
71
|
+
'messageFromBinary',
|
|
72
|
+
{
|
|
73
|
+
data: messageString
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// 将新的字符串化事件发送回`onmessage`
|
|
78
|
+
this.handleOnMessage(constructedMessage);
|
|
79
|
+
})
|
|
80
|
+
.catch((error: Error) => {
|
|
81
|
+
Logger.Error(
|
|
82
|
+
Logger.GetStackTrace(),
|
|
83
|
+
`从websocket解析二进制blob失败,原因: ${error}`
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 处理接收到消息时发生的事情
|
|
90
|
+
* @param event - Message Received
|
|
91
|
+
*/
|
|
92
|
+
handleOnMessage(event: MessageEvent) {
|
|
93
|
+
// 检查websocket消息是否为二进制,如果是,将其字符串化。
|
|
94
|
+
if (event.data && event.data instanceof Blob) {
|
|
95
|
+
this.handleOnMessageBinary(event);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const message: MessageReceive.MessageRecv = JSON.parse(event.data);
|
|
100
|
+
Logger.Log(
|
|
101
|
+
Logger.GetStackTrace(),
|
|
102
|
+
'received => \n' +
|
|
103
|
+
JSON.stringify(JSON.parse(event.data), undefined, 4),
|
|
104
|
+
6
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// 发送到我们的信号协议来处理传入的消息
|
|
108
|
+
this.signallingProtocol.handleMessage(message.type, event.data);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* 处理Websocket打开时的事件
|
|
113
|
+
* @param event - Not Used
|
|
114
|
+
*/
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
116
|
+
handleOnOpen(event: Event) {
|
|
117
|
+
Logger.Log(
|
|
118
|
+
Logger.GetStackTrace(),
|
|
119
|
+
'通过WebSocket连接到信令服务器',
|
|
120
|
+
6
|
|
121
|
+
);
|
|
122
|
+
this.onOpen.dispatchEvent(new Event('open'));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 在websocket中处理错误
|
|
127
|
+
* @param event - Error Payload
|
|
128
|
+
*/
|
|
129
|
+
handleOnError() {
|
|
130
|
+
Logger.Error(Logger.GetStackTrace(), 'WebSocket error');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 当Websocket关闭时处理
|
|
135
|
+
* @param event - Close Event
|
|
136
|
+
*/
|
|
137
|
+
handleOnClose(event: CloseEvent) {
|
|
138
|
+
console.log(event);
|
|
139
|
+
|
|
140
|
+
Logger.Log(
|
|
141
|
+
Logger.GetStackTrace(),
|
|
142
|
+
'通过WebSocket与信令服务器断开连接: ' +
|
|
143
|
+
JSON.stringify(event.code) +
|
|
144
|
+
' - ' +
|
|
145
|
+
event.reason
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// 被踢下线
|
|
149
|
+
if (event.code == 4004) {
|
|
150
|
+
this.onOpen.dispatchEvent(new Event('close', event));
|
|
151
|
+
this.onClose.dispatchEvent(new CustomEvent('close', { 'detail': event }));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
requestStreamerList() {
|
|
157
|
+
const payload = new MessageSend.MessageListStreamers();
|
|
158
|
+
this.webSocket.send(payload.payload());
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
requestStreamerObject(streamerid: string) {
|
|
162
|
+
const payload = new MessageSend.requestStreamerObject(streamerid);
|
|
163
|
+
this.webSocket.send(payload.payload());
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
sendSubscribe(streamerid: string) {
|
|
167
|
+
const payload = new MessageSend.MessageSubscribe(streamerid);
|
|
168
|
+
this.webSocket.send(payload.payload());
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
sendUnsubscribe() {
|
|
172
|
+
const payload = new MessageSend.MessageUnsubscribe();
|
|
173
|
+
this.webSocket.send(payload.payload());
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
sendWebRtcOffer(offer: RTCSessionDescriptionInit) {
|
|
177
|
+
const payload = new MessageSend.MessageWebRTCOffer(offer);
|
|
178
|
+
this.webSocket.send(payload.payload());
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
sendWebRtcAnswer(answer: RTCSessionDescriptionInit) {
|
|
182
|
+
const payload = new MessageSend.MessageWebRTCAnswer(answer);
|
|
183
|
+
this.webSocket.send(payload.payload());
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
sendWebRtcDatachannelRequest() {
|
|
187
|
+
const payload = new MessageSend.MessageWebRTCDatachannelRequest();
|
|
188
|
+
this.webSocket.send(payload.payload());
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
sendSFURecvDataChannelReady() {
|
|
192
|
+
const payload = new MessageSend.MessageSFURecvDataChannelReady();
|
|
193
|
+
this.webSocket.send(payload.payload());
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
*向服务器发送一个RTC Ice候选项
|
|
198
|
+
* @param candidate—RTC Ice候选
|
|
199
|
+
*/
|
|
200
|
+
sendIceCandidate(candidate: RTCIceCandidate) {
|
|
201
|
+
Logger.Log(Logger.GetStackTrace(), 'Sending Ice Candidate(发送Ice候选人)');
|
|
202
|
+
if (
|
|
203
|
+
this.webSocket &&
|
|
204
|
+
this.webSocket.readyState === this.WS_OPEN_STATE
|
|
205
|
+
) {
|
|
206
|
+
//ws.send(JSON.stringify({ type: 'iceCandidate', candidate: candidate }));
|
|
207
|
+
const IceCandidate = new MessageSend.MessageIceCandidate(candidate);
|
|
208
|
+
|
|
209
|
+
this.webSocket.send(IceCandidate.payload());
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Closes the Websocket connection
|
|
215
|
+
*/
|
|
216
|
+
close() {
|
|
217
|
+
this.webSocket?.close();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The Message Contains the payload of the peer connection options used for the RTC Peer hand shake
|
|
222
|
+
* @param messageConfig - Config Message received from he signaling server
|
|
223
|
+
*/
|
|
224
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
|
225
|
+
onConfig(messageConfig: MessageReceive.MessageConfig) { }
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* The Message Contains the payload of the peer connection options used for the RTC Peer hand shake
|
|
229
|
+
* @param messageConfig - Config Message received from he signaling server
|
|
230
|
+
*/
|
|
231
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
|
232
|
+
onStreamerList(messageStreamerList: MessageReceive.MessageStreamerList) { }
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @param iceCandidate - Ice Candidate sent from the Signaling server server's RTC hand shake
|
|
236
|
+
*/
|
|
237
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
|
238
|
+
onIceCandidate(iceCandidate: RTCIceCandidateInit) { }
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Event is fired when the websocket receives the answer for the RTC peer Connection
|
|
242
|
+
* @param messageAnswer - The RTC Answer payload from the signaling server
|
|
243
|
+
*/
|
|
244
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
|
245
|
+
onWebRtcAnswer(messageAnswer: MessageReceive.MessageAnswer) { }
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Event is fired when the websocket receives the offer for the RTC peer Connection
|
|
249
|
+
* @param messageOffer - The sdp offer
|
|
250
|
+
*/
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
|
252
|
+
onWebRtcOffer(messageOffer: MessageReceive.MessageOffer) { }
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Event is fired when the websocket receives the data channels for the RTC peer Connection from the SFU
|
|
256
|
+
* @param messageDataChannels - The data channels details
|
|
257
|
+
*/
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
|
259
|
+
onWebRtcPeerDataChannels(messageDataChannels: MessageReceive.MessagePeerDataChannels) { }
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Event is fired when the websocket receives the an updated player count from cirrus
|
|
263
|
+
* @param MessagePlayerCount - The new player count
|
|
264
|
+
*/
|
|
265
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
|
266
|
+
onPlayerCount(playerCount: MessageReceive.MessagePlayerCount) { }
|
|
267
|
+
}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
2
|
+
|
|
3
|
+
import { Logger } from '../Logger/Logger';
|
|
4
|
+
import { WebRtcPlayerController } from '../WebRtcPlayer/WebRtcPlayerController';
|
|
5
|
+
import { WebGLUtils } from '../Util/WebGLUtils';
|
|
6
|
+
import { Controller } from '../Inputs/GamepadTypes';
|
|
7
|
+
import { XRGamepadController } from '../Inputs/XRGamepadController';
|
|
8
|
+
import { XrFrameEvent } from '../Util/EventEmitter'
|
|
9
|
+
import { Flags } from '../pixelstreamingfrontend';
|
|
10
|
+
|
|
11
|
+
export class WebXRController {
|
|
12
|
+
private xrSession: XRSession;
|
|
13
|
+
private xrRefSpace: XRReferenceSpace;
|
|
14
|
+
private gl: WebGL2RenderingContext;
|
|
15
|
+
|
|
16
|
+
private positionLocation: number;
|
|
17
|
+
private texcoordLocation: number;
|
|
18
|
+
private resolutionLocation: WebGLUniformLocation;
|
|
19
|
+
private offsetLocation: WebGLUniformLocation;
|
|
20
|
+
|
|
21
|
+
private positionBuffer: WebGLBuffer;
|
|
22
|
+
private texcoordBuffer: WebGLBuffer;
|
|
23
|
+
|
|
24
|
+
private webRtcController: WebRtcPlayerController;
|
|
25
|
+
private xrGamepadController: XRGamepadController;
|
|
26
|
+
private xrControllers: Array<Controller>;
|
|
27
|
+
|
|
28
|
+
onSessionStarted: EventTarget;
|
|
29
|
+
onSessionEnded: EventTarget;
|
|
30
|
+
onFrame: EventTarget;
|
|
31
|
+
|
|
32
|
+
constructor(webRtcPlayerController: WebRtcPlayerController) {
|
|
33
|
+
this.xrSession = null;
|
|
34
|
+
this.webRtcController = webRtcPlayerController;
|
|
35
|
+
this.xrControllers = [];
|
|
36
|
+
this.xrGamepadController = new XRGamepadController(
|
|
37
|
+
this.webRtcController.streamMessageController
|
|
38
|
+
);
|
|
39
|
+
this.onSessionEnded = new EventTarget();
|
|
40
|
+
this.onSessionStarted = new EventTarget();
|
|
41
|
+
this.onFrame = new EventTarget();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public xrClicked() {
|
|
45
|
+
if (!this.xrSession) {
|
|
46
|
+
navigator.xr
|
|
47
|
+
.requestSession('immersive-vr')
|
|
48
|
+
.then((session: XRSession) => {
|
|
49
|
+
this.onXrSessionStarted(session);
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
this.xrSession.end();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
onXrSessionEnded() {
|
|
57
|
+
Logger.Log(Logger.GetStackTrace(), 'XR Session ended');
|
|
58
|
+
this.xrSession = null;
|
|
59
|
+
this.onSessionEnded.dispatchEvent(new Event('xrSessionEnded'));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
onXrSessionStarted(session: XRSession) {
|
|
63
|
+
Logger.Log(Logger.GetStackTrace(), 'XR Session started');
|
|
64
|
+
|
|
65
|
+
this.xrSession = session;
|
|
66
|
+
this.xrSession.addEventListener('end', () => {
|
|
67
|
+
this.onXrSessionEnded();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const canvas = document.createElement('canvas');
|
|
71
|
+
this.gl = canvas.getContext('webgl2', {
|
|
72
|
+
xrCompatible: true
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
this.xrSession.updateRenderState({
|
|
76
|
+
baseLayer: new XRWebGLLayer(this.xrSession, this.gl)
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// setup vertex shader
|
|
80
|
+
const vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
|
|
81
|
+
this.gl.shaderSource(vertexShader, WebGLUtils.vertexShader());
|
|
82
|
+
this.gl.compileShader(vertexShader);
|
|
83
|
+
|
|
84
|
+
// setup fragment shader
|
|
85
|
+
const fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
|
|
86
|
+
this.gl.shaderSource(fragmentShader, WebGLUtils.fragmentShader());
|
|
87
|
+
this.gl.compileShader(fragmentShader);
|
|
88
|
+
|
|
89
|
+
// setup GLSL program
|
|
90
|
+
const shaderProgram = this.gl.createProgram();
|
|
91
|
+
this.gl.attachShader(shaderProgram, vertexShader);
|
|
92
|
+
this.gl.attachShader(shaderProgram, fragmentShader);
|
|
93
|
+
this.gl.linkProgram(shaderProgram);
|
|
94
|
+
this.gl.useProgram(shaderProgram);
|
|
95
|
+
|
|
96
|
+
// look up where vertex data needs to go
|
|
97
|
+
this.positionLocation = this.gl.getAttribLocation(
|
|
98
|
+
shaderProgram,
|
|
99
|
+
'a_position'
|
|
100
|
+
);
|
|
101
|
+
this.texcoordLocation = this.gl.getAttribLocation(
|
|
102
|
+
shaderProgram,
|
|
103
|
+
'a_texCoord'
|
|
104
|
+
);
|
|
105
|
+
// Create a buffer to put three 2d clip space points in
|
|
106
|
+
this.positionBuffer = this.gl.createBuffer();
|
|
107
|
+
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
|
|
108
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
|
|
109
|
+
|
|
110
|
+
// Turn on the position attribute
|
|
111
|
+
this.gl.enableVertexAttribArray(this.positionLocation);
|
|
112
|
+
// Create a texture.
|
|
113
|
+
const texture = this.gl.createTexture();
|
|
114
|
+
this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
|
|
115
|
+
// Set the parameters so we can render any size image.
|
|
116
|
+
this.gl.texParameteri(
|
|
117
|
+
this.gl.TEXTURE_2D,
|
|
118
|
+
this.gl.TEXTURE_WRAP_S,
|
|
119
|
+
this.gl.CLAMP_TO_EDGE
|
|
120
|
+
);
|
|
121
|
+
this.gl.texParameteri(
|
|
122
|
+
this.gl.TEXTURE_2D,
|
|
123
|
+
this.gl.TEXTURE_WRAP_T,
|
|
124
|
+
this.gl.CLAMP_TO_EDGE
|
|
125
|
+
);
|
|
126
|
+
this.gl.texParameteri(
|
|
127
|
+
this.gl.TEXTURE_2D,
|
|
128
|
+
this.gl.TEXTURE_MIN_FILTER,
|
|
129
|
+
this.gl.NEAREST
|
|
130
|
+
);
|
|
131
|
+
this.gl.texParameteri(
|
|
132
|
+
this.gl.TEXTURE_2D,
|
|
133
|
+
this.gl.TEXTURE_MAG_FILTER,
|
|
134
|
+
this.gl.NEAREST
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
this.texcoordBuffer = this.gl.createBuffer();
|
|
138
|
+
// lookup uniforms
|
|
139
|
+
this.resolutionLocation = this.gl.getUniformLocation(
|
|
140
|
+
shaderProgram,
|
|
141
|
+
'u_resolution'
|
|
142
|
+
);
|
|
143
|
+
this.offsetLocation = this.gl.getUniformLocation(
|
|
144
|
+
shaderProgram,
|
|
145
|
+
'u_offset'
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
session.requestReferenceSpace('local').then((refSpace) => {
|
|
149
|
+
this.xrRefSpace = refSpace;
|
|
150
|
+
this.xrSession.requestAnimationFrame(
|
|
151
|
+
(time: DOMHighResTimeStamp, frame: XRFrame) =>
|
|
152
|
+
this.onXrFrame(time, frame)
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
this.onSessionStarted.dispatchEvent(new Event('xrSessionStarted'));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
onXrFrame(time: DOMHighResTimeStamp, frame: XRFrame) {
|
|
160
|
+
const pose = frame.getViewerPose(this.xrRefSpace);
|
|
161
|
+
if (pose) {
|
|
162
|
+
const matrix = pose.transform.matrix;
|
|
163
|
+
const mat = [];
|
|
164
|
+
for (let i = 0; i < 16; i++) {
|
|
165
|
+
mat[i] = new Float32Array([matrix[i]])[0];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// prettier-ignore
|
|
169
|
+
this.webRtcController.streamMessageController.toStreamerHandlers.get('XRHMDTransform')([
|
|
170
|
+
mat[0], mat[4], mat[8], mat[12],
|
|
171
|
+
mat[1], mat[5], mat[9], mat[13],
|
|
172
|
+
mat[2], mat[6], mat[10], mat[14],
|
|
173
|
+
mat[3], mat[7], mat[11], mat[15]
|
|
174
|
+
]);
|
|
175
|
+
|
|
176
|
+
const glLayer = this.xrSession.renderState.baseLayer;
|
|
177
|
+
// If we do have a valid pose, bind the WebGL layer's framebuffer,
|
|
178
|
+
// which is where any content to be displayed on the XRDevice must be
|
|
179
|
+
// rendered.
|
|
180
|
+
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, glLayer.framebuffer);
|
|
181
|
+
|
|
182
|
+
// Upload the image into the texture. WebGL knows how to extract the current frame from the video element
|
|
183
|
+
this.gl.texImage2D(
|
|
184
|
+
this.gl.TEXTURE_2D,
|
|
185
|
+
0,
|
|
186
|
+
this.gl.RGBA,
|
|
187
|
+
this.gl.RGBA,
|
|
188
|
+
this.gl.UNSIGNED_BYTE,
|
|
189
|
+
this.webRtcController.videoPlayer.getVideoElement()
|
|
190
|
+
);
|
|
191
|
+
this.render(this.webRtcController.videoPlayer.getVideoElement());
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (this.webRtcController.config.isFlagEnabled(Flags.XRControllerInput)) {
|
|
195
|
+
this.xrSession.inputSources.forEach(
|
|
196
|
+
(source: XRInputSource, index: number, array: XRInputSource[]) => {
|
|
197
|
+
this.xrGamepadController.updateStatus(
|
|
198
|
+
source,
|
|
199
|
+
frame,
|
|
200
|
+
this.xrRefSpace
|
|
201
|
+
);
|
|
202
|
+
},
|
|
203
|
+
this
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
this.xrSession.requestAnimationFrame(
|
|
208
|
+
(time: DOMHighResTimeStamp, frame: XRFrame) =>
|
|
209
|
+
this.onXrFrame(time, frame)
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
this.onFrame.dispatchEvent(new XrFrameEvent({
|
|
213
|
+
time,
|
|
214
|
+
frame
|
|
215
|
+
}));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private render(videoElement: HTMLVideoElement) {
|
|
219
|
+
if (!this.gl) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const glLayer = this.xrSession.renderState.baseLayer;
|
|
224
|
+
this.gl.viewport(
|
|
225
|
+
0,
|
|
226
|
+
0,
|
|
227
|
+
glLayer.framebufferWidth,
|
|
228
|
+
glLayer.framebufferHeight
|
|
229
|
+
);
|
|
230
|
+
this.gl.uniform4f(this.offsetLocation, 1.0, 1.0, 0.0, 0.0);
|
|
231
|
+
|
|
232
|
+
// Set rectangle
|
|
233
|
+
// prettier-ignore
|
|
234
|
+
this.gl.bufferData(
|
|
235
|
+
this.gl.ARRAY_BUFFER,
|
|
236
|
+
new Float32Array([
|
|
237
|
+
0, 0,
|
|
238
|
+
videoElement.videoWidth, 0,
|
|
239
|
+
0, videoElement.videoHeight,
|
|
240
|
+
0, videoElement.videoHeight,
|
|
241
|
+
videoElement.videoWidth, 0,
|
|
242
|
+
videoElement.videoWidth, videoElement.videoHeight
|
|
243
|
+
]),
|
|
244
|
+
this.gl.STATIC_DRAW
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
// Provide texture coordinates for the rectangle
|
|
248
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.texcoordBuffer);
|
|
249
|
+
this.gl.bufferData(
|
|
250
|
+
this.gl.ARRAY_BUFFER,
|
|
251
|
+
new Float32Array([
|
|
252
|
+
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0
|
|
253
|
+
]),
|
|
254
|
+
this.gl.STATIC_DRAW
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
let size; // components per iteration
|
|
258
|
+
let type; // the data type
|
|
259
|
+
let normalize; // normalize the data
|
|
260
|
+
let stride; // 0 = move forward size * sizeof(type) each iteration to get the next position
|
|
261
|
+
let offset; // start position of the buffer
|
|
262
|
+
|
|
263
|
+
// Bind the position buffer.
|
|
264
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
|
|
265
|
+
// Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)
|
|
266
|
+
size = 2; // 2 components per iteration
|
|
267
|
+
type = this.gl.FLOAT; // the data is 32bit floats
|
|
268
|
+
normalize = false; // don't normalize the data
|
|
269
|
+
stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
|
|
270
|
+
offset = 0; // start at the beginning of the buffer
|
|
271
|
+
this.gl.vertexAttribPointer(
|
|
272
|
+
this.positionLocation,
|
|
273
|
+
size,
|
|
274
|
+
type,
|
|
275
|
+
normalize,
|
|
276
|
+
stride,
|
|
277
|
+
offset
|
|
278
|
+
);
|
|
279
|
+
// Turn on the texcoord attribute
|
|
280
|
+
this.gl.enableVertexAttribArray(this.texcoordLocation);
|
|
281
|
+
// bind the texcoord buffer.
|
|
282
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.texcoordBuffer);
|
|
283
|
+
// Tell the texcoord attribute how to get data out of texcoordBuffer (ARRAY_BUFFER)
|
|
284
|
+
size = 2; // 2 components per iteration
|
|
285
|
+
type = this.gl.FLOAT; // the data is 32bit floats
|
|
286
|
+
normalize = false; // don't normalize the data
|
|
287
|
+
stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
|
|
288
|
+
offset = 0; // start at the beginning of the buffer
|
|
289
|
+
this.gl.vertexAttribPointer(
|
|
290
|
+
this.texcoordLocation,
|
|
291
|
+
size,
|
|
292
|
+
type,
|
|
293
|
+
normalize,
|
|
294
|
+
stride,
|
|
295
|
+
offset
|
|
296
|
+
);
|
|
297
|
+
// set the resolution
|
|
298
|
+
this.gl.uniform2f(
|
|
299
|
+
this.resolutionLocation,
|
|
300
|
+
videoElement.videoWidth,
|
|
301
|
+
videoElement.videoHeight
|
|
302
|
+
);
|
|
303
|
+
// draw the rectangle.
|
|
304
|
+
const primitiveType = this.gl.TRIANGLES;
|
|
305
|
+
const count = 6;
|
|
306
|
+
offset = 0;
|
|
307
|
+
this.gl.drawArrays(primitiveType, offset, count);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
static isSessionSupported(mode: XRSessionMode): Promise<boolean> {
|
|
311
|
+
if (navigator.xr) {
|
|
312
|
+
return navigator.xr.isSessionSupported(mode);
|
|
313
|
+
} else {
|
|
314
|
+
return new Promise<boolean>(() => {
|
|
315
|
+
return false;
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|