@3dsource/angular-unreal-module 0.0.157 → 0.0.159-dev.0
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/LICENSE +14 -14
- package/README.md +212 -422
- package/fesm2022/3dsource-angular-unreal-module.mjs +260 -535
- package/fesm2022/3dsource-angular-unreal-module.mjs.map +1 -1
- package/package.json +3 -4
- package/types/3dsource-angular-unreal-module.d.ts +217 -359
package/README.md
CHANGED
|
@@ -1,422 +1,212 @@
|
|
|
1
|
-
# @3dsource/angular-unreal-module
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
`
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
import {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
`
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### 5) Store integration (actions & selectors)
|
|
216
|
-
|
|
217
|
-
`provideUnrealState()` registers the NgRx feature state `unrealFeature`. You
|
|
218
|
-
can dispatch actions and select state in your components:
|
|
219
|
-
|
|
220
|
-
```ts
|
|
221
|
-
import { inject } from '@angular/core';
|
|
222
|
-
import { Store } from '@ngrx/store';
|
|
223
|
-
import { disconnectStream, selectShowLoader, selectTotalProgress, setConfig, setOrchestrationContext, startStream, unrealFeature } from '@3dsource/angular-unreal-module';
|
|
224
|
-
|
|
225
|
-
// Dispatch actions
|
|
226
|
-
const store = inject(Store);
|
|
227
|
-
store.dispatch(startStream({ config: { autoStart: true, warnTimeout: 120 } }));
|
|
228
|
-
|
|
229
|
-
// Select state
|
|
230
|
-
const progress = store.selectSignal(selectTotalProgress);
|
|
231
|
-
const isVideoPlaying = store.selectSignal(unrealFeature.selectIsVideoPlaying);
|
|
232
|
-
const dataChannelConnected = store.selectSignal(unrealFeature.selectDataChannelConnected);
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
**Key selectors:**
|
|
236
|
-
|
|
237
|
-
- `selectTotalProgress` — Scene load progress (0–1 float)
|
|
238
|
-
- `selectShowLoader` — Whether loader screen should be visible
|
|
239
|
-
- `selectShowReconnectPopup` — Whether reconnect popup should be shown
|
|
240
|
-
- `selectIsVideoPlayingAndDataChannelConnected` — Combined readiness check
|
|
241
|
-
- `selectStreamConfig` — Current stream configuration
|
|
242
|
-
- `unrealFeature.selectCirrusConnected` — Signalling server connection status
|
|
243
|
-
- `unrealFeature.selectDataChannelConnected` — Data channel status
|
|
244
|
-
- `unrealFeature.selectViewportReady` — Viewport readiness
|
|
245
|
-
|
|
246
|
-
**Key actions:**
|
|
247
|
-
|
|
248
|
-
- `startStream` — Start streaming with config
|
|
249
|
-
- `setConfig` — Update stream configuration
|
|
250
|
-
- `setOrchestrationContext` — Set orchestration URLs and environment
|
|
251
|
-
- `disconnectStream` — Disconnect with reason
|
|
252
|
-
- `destroyUnrealScene` — Full teardown
|
|
253
|
-
- `reconnectPeer` — Trigger peer reconnection
|
|
254
|
-
|
|
255
|
-
### 6) Listen for Unreal callbacks
|
|
256
|
-
|
|
257
|
-
Inject `UnrealCallbackService` to listen for callback events from Unreal Engine and to observe command responses.
|
|
258
|
-
|
|
259
|
-
There are two methods:
|
|
260
|
-
|
|
261
|
-
| Method | Description |
|
|
262
|
-
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
263
|
-
| `fromUnrealCallback` | Listens for callbacks matching a command or event key. Supports MetaBox commands and custom Unreal callback events. Returns `Observable<UnrealCallbackDescriptor[K]>`. |
|
|
264
|
-
| `observeCommandResponse` | Sends a command and waits for its matching response by `correlationId`. Returns `Observable<MetaBoxCommandList[K]>`. Includes timeout and error handling. |
|
|
265
|
-
|
|
266
|
-
**Custom Unreal callback events** (defined in `UnrealCallbackEventMap`):
|
|
267
|
-
|
|
268
|
-
| Event | Payload Type |
|
|
269
|
-
| -------------------------- | --------------------------------------------------- |
|
|
270
|
-
| `onSceneState` | `FSceneState` |
|
|
271
|
-
| `onFocusObject` | `FProductPayload` |
|
|
272
|
-
| `cameraChanged` | `FCameraChangedPayload` |
|
|
273
|
-
| `onObjectTransformChanged` | `{ objectName: string; transform: FTransformJson }` |
|
|
274
|
-
| `onChangeSequence` | `unknown` |
|
|
275
|
-
| `onFinishedSequence` | `unknown` |
|
|
276
|
-
|
|
277
|
-
```ts
|
|
278
|
-
import { Component, inject } from '@angular/core';
|
|
279
|
-
import { UnrealCallbackService } from '@3dsource/angular-unreal-module';
|
|
280
|
-
import { UnrealCommunicatorService } from '@3dsource/angular-unreal-module';
|
|
281
|
-
import { MetaBoxCommand } from '@3dsource/types-unreal';
|
|
282
|
-
|
|
283
|
-
@Component({ standalone: true, template: '' })
|
|
284
|
-
export class MyComponent {
|
|
285
|
-
private callbackService = inject(UnrealCallbackService);
|
|
286
|
-
private communicator = inject(UnrealCommunicatorService);
|
|
287
|
-
|
|
288
|
-
listenForCallbacks() {
|
|
289
|
-
// Listen for a MetaBox command callback
|
|
290
|
-
this.callbackService.fromUnrealCallback(MetaBoxCommand.FLoadProductCommand).subscribe((data) => console.log('Product loaded:', data));
|
|
291
|
-
|
|
292
|
-
// Listen for a custom Unreal event
|
|
293
|
-
this.callbackService.fromUnrealCallback('cameraChanged').subscribe((data) => console.log('Camera changed:', data));
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
sendAndObserve() {
|
|
297
|
-
// Send a command and observe its response (with correlationId matching)
|
|
298
|
-
this.callbackService
|
|
299
|
-
.observeCommandResponse(
|
|
300
|
-
{ command: MetaBoxCommand.FLoopBackCommand },
|
|
301
|
-
(data) => this.communicator.sendCommandToUnreal(data),
|
|
302
|
-
60000, // timeout in ms (default: 60000)
|
|
303
|
-
true, // emit on timeout (default: true)
|
|
304
|
-
)
|
|
305
|
-
.subscribe((response) => console.log('Response:', response));
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
## Exported API
|
|
311
|
-
|
|
312
|
-
### Components
|
|
313
|
-
|
|
314
|
-
| Component | Selector | Description |
|
|
315
|
-
| ------------------------------- | ------------------ | -------------------------------------- |
|
|
316
|
-
| `UnrealSceneComponent` | `app-unreal-scene` | Main scene container with video stream |
|
|
317
|
-
| `AfkTimeoutModalComponent` | — | AFK timeout warning modal |
|
|
318
|
-
| `FreezeFrameComponent` | — | Freeze frame overlay |
|
|
319
|
-
| `LowBandwidthModalComponent` | — | Low bandwidth warning modal |
|
|
320
|
-
| `LowBandwidthDetectorComponent` | — | Low bandwidth detector |
|
|
321
|
-
| `ImageLoadingSrcComponent` | — | Loading image overlay |
|
|
322
|
-
| `IntroSrcComponent` | — | Intro image/video overlay |
|
|
323
|
-
| `VideoStatsComponent` | — | Video statistics display |
|
|
324
|
-
| `StatGraphComponent` | — | Statistics graph |
|
|
325
|
-
| `WebrtcErrorModalComponent` | — | WebRTC error modal |
|
|
326
|
-
|
|
327
|
-
### Services
|
|
328
|
-
|
|
329
|
-
| Service | Description |
|
|
330
|
-
| ------------------------------ | --------------------------------------------------------------- |
|
|
331
|
-
| `UnrealCommunicatorService` | Send commands and UI interactions to Unreal |
|
|
332
|
-
| `UnrealCallbackService` | Listen for Unreal callback events and observe command responses |
|
|
333
|
-
| `AggregatorService` | Aggregates data channel messages from Unreal |
|
|
334
|
-
| `SignallingService` | Manages WebSocket signalling connection |
|
|
335
|
-
| `VideoService` | Manages video element and stats |
|
|
336
|
-
| `WebRtcPlayerService` | Manages WebRTC peer connection |
|
|
337
|
-
| `FreezeFrameService` | Handles freeze frame images |
|
|
338
|
-
| `AFKService` | AFK (away from keyboard) detection and timeout |
|
|
339
|
-
| `DevModeService` | Toggle dev mode for debugging |
|
|
340
|
-
| `FileReceiverService` | Receives files from Unreal via data channel |
|
|
341
|
-
| `FileHandlerService` | Processes received files |
|
|
342
|
-
| `RegionsPingService` | Pings regions to determine latency |
|
|
343
|
-
| `CommandTelemetryService` | Records command telemetry |
|
|
344
|
-
| `StreamStatusTelemetryService` | Reports stream status telemetry |
|
|
345
|
-
| `AnalyticsService` | Analytics event tracking |
|
|
346
|
-
| `FpsMonitorService` | FPS monitoring |
|
|
347
|
-
|
|
348
|
-
### Pipes
|
|
349
|
-
|
|
350
|
-
| Pipe | Description |
|
|
351
|
-
| ---------- | ------------------------------------------------------------ |
|
|
352
|
-
| `SafePipe` | Sanitizes a value for the requested Angular security context |
|
|
353
|
-
|
|
354
|
-
### Interfaces
|
|
355
|
-
|
|
356
|
-
| Interface | Description |
|
|
357
|
-
| -------------------------- | ---------------------------------------------------------------------------- |
|
|
358
|
-
| `UnrealInitialConfig` | Shape for `UNREAL_CONFIG` injection token |
|
|
359
|
-
| `StreamConfig` | Stream configuration (autoStart, warnTimeout) |
|
|
360
|
-
| `StreamResolutionProps` | Stream resolution width/height |
|
|
361
|
-
| `UnrealCallbackEventMap` | Custom Unreal callback events pushed from Unreal via data channel |
|
|
362
|
-
| `UnrealCallbackDescriptor` | Combined map of MetaBoxCommandList and UnrealCallbackEventMap callback types |
|
|
363
|
-
|
|
364
|
-
## Features
|
|
365
|
-
|
|
366
|
-
- Standalone Unreal Scene Component
|
|
367
|
-
- Command and UI Interaction API via `UnrealCommunicatorService`
|
|
368
|
-
- Callback listener and command response observer via `UnrealCallbackService`
|
|
369
|
-
- Event-driven status UI (freeze frame, video stats, play overlay, AFK, low bandwidth)
|
|
370
|
-
- NgRx-powered state management and effects
|
|
371
|
-
- **Required** initial configuration via `UNREAL_CONFIG` injection token
|
|
372
|
-
- Auto-reconnection on WebRTC/DataChannel failures (configurable)
|
|
373
|
-
- File receiving from Unreal Engine via data channel
|
|
374
|
-
- Analytics and FPS monitoring
|
|
375
|
-
- Playwright testing mode with mock service substitution
|
|
376
|
-
|
|
377
|
-
## Examples
|
|
378
|
-
|
|
379
|
-
Check the demo application for complete usage examples:
|
|
380
|
-
|
|
381
|
-
```shell
|
|
382
|
-
pnpm demo:start
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
See also: `projects/demo/src/app/demo-layout/info-pages/unreal-scene-demo/constants/unreal.routes.ts` for a real-world provider configuration example.
|
|
386
|
-
|
|
387
|
-
## Repository development
|
|
388
|
-
|
|
389
|
-
Run package commands from the repository root:
|
|
390
|
-
|
|
391
|
-
```shell
|
|
392
|
-
pnpm unreal:build
|
|
393
|
-
pnpm unreal:build:watch
|
|
394
|
-
pnpm unreal:lint
|
|
395
|
-
pnpm unreal:test
|
|
396
|
-
pnpm unreal:test:watch
|
|
397
|
-
pnpm unreal:test:signalling
|
|
398
|
-
pnpm unreal:test:signalling:leaks
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
`unreal:build` builds `source-ui-native`, `types-unreal` and `utils` before this
|
|
402
|
-
package. `unreal:build:watch` performs that initial build automatically and then
|
|
403
|
-
watches `angular-unreal-module`.
|
|
404
|
-
|
|
405
|
-
To version and publish:
|
|
406
|
-
|
|
407
|
-
```shell
|
|
408
|
-
pnpm unreal:release:patch
|
|
409
|
-
pnpm unreal:release:dev
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
The release command publishes to npm. After verifying the npm release, purge
|
|
413
|
-
the matching jsDelivr tag explicitly:
|
|
414
|
-
|
|
415
|
-
```shell
|
|
416
|
-
pnpm unreal:purge-cdn -- latest
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
## Engine requirements
|
|
420
|
-
|
|
421
|
-
- Node.js: >=24.16.0
|
|
422
|
-
- pnpm: 11.17.0 (activated from the root `packageManager` field via Corepack)
|
|
1
|
+
# @3dsource/angular-unreal-module
|
|
2
|
+
|
|
3
|
+
Standalone Angular integration for Unreal Engine Pixel Streaming. The package
|
|
4
|
+
provides the scene component, WebRTC and signalling lifecycle, NgRx state,
|
|
5
|
+
command/callback APIs, reconnection, file transfer and telemetry.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Angular, Angular CDK and Angular Forms `>=19.0.0 <23.0.0`
|
|
10
|
+
- NgRx Store and Effects `>=19.0.0 <23.0.0`
|
|
11
|
+
- RxJS `>=7.8.0 <8.0.0`
|
|
12
|
+
- `@3dsource/source-ui-native >=1.0.9`
|
|
13
|
+
- `@3dsource/types-unreal >=0.0.7`
|
|
14
|
+
- `@3dsource/utils >=1.0.21`
|
|
15
|
+
- `provideHttpClient()` in the host application
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```shell
|
|
20
|
+
pnpm add @3dsource/angular-unreal-module @3dsource/source-ui-native @3dsource/types-unreal @3dsource/utils
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The package is standalone and does not expose an NgModule.
|
|
24
|
+
|
|
25
|
+
## Setup
|
|
26
|
+
|
|
27
|
+
### 1. Register state and configuration once
|
|
28
|
+
|
|
29
|
+
Add the Unreal feature state, HTTP client and configuration at the application
|
|
30
|
+
root. `UNREAL_CONFIG` is required, although all its fields are optional.
|
|
31
|
+
|
|
32
|
+
<!-- prettier-ignore -->
|
|
33
|
+
```typescript
|
|
34
|
+
import { provideHttpClient } from '@angular/common/http';
|
|
35
|
+
import type { ApplicationConfig } from '@angular/core';
|
|
36
|
+
import { provideStore } from '@ngrx/store';
|
|
37
|
+
import {
|
|
38
|
+
provideUnrealState,
|
|
39
|
+
UNREAL_CONFIG,
|
|
40
|
+
type UnrealInitialConfig,
|
|
41
|
+
} from '@3dsource/angular-unreal-module';
|
|
42
|
+
|
|
43
|
+
const unrealConfig = {
|
|
44
|
+
regionsPingUrl: 'https://datacenter.3dsource.com/regions/',
|
|
45
|
+
dataChannelConnectionTimeout: 8000,
|
|
46
|
+
fpsMonitor: false,
|
|
47
|
+
autoHighResolution: false,
|
|
48
|
+
} satisfies UnrealInitialConfig;
|
|
49
|
+
|
|
50
|
+
export const appConfig: ApplicationConfig = {
|
|
51
|
+
providers: [
|
|
52
|
+
provideHttpClient(),
|
|
53
|
+
provideStore(),
|
|
54
|
+
provideUnrealState(),
|
|
55
|
+
{ provide: UNREAL_CONFIG, useValue: unrealConfig },
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Omit `provideStore()` when the root NgRx store is already configured.
|
|
61
|
+
|
|
62
|
+
Available configuration fields:
|
|
63
|
+
|
|
64
|
+
| Field | Purpose |
|
|
65
|
+
| ------------------------------ | ---------------------------------------------- |
|
|
66
|
+
| `regionsPingUrl` | Region latency endpoint |
|
|
67
|
+
| `dataChannelConnectionTimeout` | DataChannel connection timeout in ms |
|
|
68
|
+
| `customErrorsEndpoint` | Custom error reporting endpoint |
|
|
69
|
+
| `commandTelemetryReceiver` | Command telemetry endpoint |
|
|
70
|
+
| `streamTelemetryV2Url` | Stream lifecycle telemetry endpoint |
|
|
71
|
+
| `screenLockerContainerId` | Container used by the screen-locker overlay |
|
|
72
|
+
| `fpsMonitor` | Enables FPS monitoring |
|
|
73
|
+
| `autoHighResolution` | Raises resolution after the scene becomes idle |
|
|
74
|
+
| `playwright` | Enables the test-specific service behaviour |
|
|
75
|
+
|
|
76
|
+
Use `{ provide: UNREAL_CONFIG, useValue: {} }` for the minimal configuration.
|
|
77
|
+
|
|
78
|
+
### 2. Boot the engine on a lazy route
|
|
79
|
+
|
|
80
|
+
Lazy-load the route file from the application router:
|
|
81
|
+
|
|
82
|
+
<!-- prettier-ignore -->
|
|
83
|
+
```typescript
|
|
84
|
+
import type { Routes } from '@angular/router';
|
|
85
|
+
|
|
86
|
+
export const APP_ROUTES: Routes = [
|
|
87
|
+
{
|
|
88
|
+
path: 'stream',
|
|
89
|
+
loadChildren: () =>
|
|
90
|
+
import('./stream/stream.routes').then((module) => module.STREAM_ROUTES),
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Register `provideUnrealModule()` inside that lazy route file:
|
|
96
|
+
|
|
97
|
+
<!-- prettier-ignore -->
|
|
98
|
+
```typescript
|
|
99
|
+
import type { Routes } from '@angular/router';
|
|
100
|
+
import { provideUnrealModule } from '@3dsource/angular-unreal-module';
|
|
101
|
+
import { StreamComponent } from './stream.component';
|
|
102
|
+
|
|
103
|
+
export const STREAM_ROUTES: Routes = [
|
|
104
|
+
{
|
|
105
|
+
path: '',
|
|
106
|
+
component: StreamComponent,
|
|
107
|
+
providers: [provideUnrealModule()],
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Keep `provideUnrealState()` and `UNREAL_CONFIG` at the application root.
|
|
113
|
+
The `loadChildren()` boundary keeps the streaming engine out of the initial
|
|
114
|
+
bundle. Route-scoping `provideUnrealModule()` tears down its effects when the
|
|
115
|
+
route is left.
|
|
116
|
+
|
|
117
|
+
### 3. Render the scene
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
121
|
+
import { UnrealSceneComponent } from '@3dsource/angular-unreal-module';
|
|
122
|
+
|
|
123
|
+
@Component({
|
|
124
|
+
selector: 'app-stream',
|
|
125
|
+
imports: [UnrealSceneComponent],
|
|
126
|
+
template: `<app-unreal-scene />`,
|
|
127
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
128
|
+
})
|
|
129
|
+
export class StreamComponent {}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`UnrealSceneComponent` also accepts `isStudio`,
|
|
133
|
+
`useContainerAsSizeProvider` and `resolutionSize` inputs, and emits
|
|
134
|
+
`changeMouseOverScene`.
|
|
135
|
+
|
|
136
|
+
## Main API
|
|
137
|
+
|
|
138
|
+
- `provideUnrealState()` — registers the `unrealFeature` NgRx state.
|
|
139
|
+
- `provideUnrealModule()` — registers effects and boots streaming services.
|
|
140
|
+
- `UnrealSceneComponent` — renders and manages the Pixel Streaming scene.
|
|
141
|
+
- `UnrealCommunicatorService` — sends commands and UI interactions.
|
|
142
|
+
- `UnrealCallbackService` — observes Unreal callbacks and command responses.
|
|
143
|
+
- `unrealFeature`, exported selectors and actions — expose connection and scene
|
|
144
|
+
lifecycle state.
|
|
145
|
+
- `FileReceiverService` and `FileHandlerService` — receive files over the
|
|
146
|
+
DataChannel.
|
|
147
|
+
|
|
148
|
+
Command packet types are provided by `@3dsource/types-unreal`.
|
|
149
|
+
|
|
150
|
+
Run `pnpm demo:start` from the repository root to see the scene component in
|
|
151
|
+
the demo application.
|
|
152
|
+
|
|
153
|
+
## Optional prefetch scripts
|
|
154
|
+
|
|
155
|
+
The package publishes two dependency-free scripts for use in the document
|
|
156
|
+
`<head>` before Angular starts:
|
|
157
|
+
|
|
158
|
+
- `region-ping-prefetch.js` measures regions early and caches the closest one.
|
|
159
|
+
- `stream-prefetch.js` opens and parks an eligible WebRTC connection so Angular
|
|
160
|
+
can adopt it after bootstrap.
|
|
161
|
+
|
|
162
|
+
<!-- prettier-ignore -->
|
|
163
|
+
```html
|
|
164
|
+
<script
|
|
165
|
+
src="https://cdn.jsdelivr.net/npm/@3dsource/angular-unreal-module/js/region-ping-prefetch.js"
|
|
166
|
+
async
|
|
167
|
+
></script>
|
|
168
|
+
<script
|
|
169
|
+
src="https://cdn.jsdelivr.net/npm/@3dsource/angular-unreal-module/js/stream-prefetch.js"
|
|
170
|
+
async
|
|
171
|
+
></script>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`stream-prefetch.js` runs by default only on
|
|
175
|
+
`metabox-configurator/{modular|basic}/...` routes. It reads the same-origin
|
|
176
|
+
`assets/config.json`; override that path with `data-config-url` when needed.
|
|
177
|
+
Pin an exact package version in production when deterministic CDN assets are
|
|
178
|
+
required.
|
|
179
|
+
|
|
180
|
+
## Repository development
|
|
181
|
+
|
|
182
|
+
Run commands from the repository root:
|
|
183
|
+
|
|
184
|
+
```shell
|
|
185
|
+
pnpm unreal:build
|
|
186
|
+
pnpm unreal:build:watch
|
|
187
|
+
pnpm unreal:lint
|
|
188
|
+
pnpm unreal:test
|
|
189
|
+
pnpm unreal:test:watch
|
|
190
|
+
pnpm unreal:test:signalling
|
|
191
|
+
pnpm unreal:test:signalling:leaks
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`unreal:build` builds the local `source-ui-native`, `types-unreal` and `utils`
|
|
195
|
+
dependencies before this package.
|
|
196
|
+
|
|
197
|
+
Release commands publish only this package:
|
|
198
|
+
|
|
199
|
+
```shell
|
|
200
|
+
pnpm unreal:release:patch
|
|
201
|
+
pnpm unreal:release:dev
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
After a successful publish, the release automatically purges the matching
|
|
205
|
+
jsDelivr tag. Retry a failed purge without rerunning the release:
|
|
206
|
+
|
|
207
|
+
```shell
|
|
208
|
+
pnpm unreal:purge-cdn -- latest
|
|
209
|
+
pnpm unreal:purge-cdn -- dev
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Repository tooling requires Node.js 24.16.0 or newer and pnpm 11.17.0.
|