@uniai-fe/uds-templates 0.6.13 → 0.6.15
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/package.json
CHANGED
|
@@ -49,6 +49,15 @@ const attachVideo = (video: HTMLVideoElement, stream: MediaStream | null) => {
|
|
|
49
49
|
video.srcObject = stream;
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
const clearVideoIfAttachedStream = (
|
|
53
|
+
video: HTMLVideoElement,
|
|
54
|
+
stream: MediaStream | null,
|
|
55
|
+
) => {
|
|
56
|
+
if (stream && video.srcObject === stream) {
|
|
57
|
+
video.srcObject = null;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
52
61
|
const notifyEntry = (entry: CctvRtcStreamEntry) => {
|
|
53
62
|
const snapshot = getEntrySnapshot(entry);
|
|
54
63
|
entry.listeners.forEach(listener => listener(snapshot));
|
|
@@ -125,9 +134,7 @@ const closeEntry = (entry: CctvRtcStreamEntry) => {
|
|
|
125
134
|
entry.isStreaming = false;
|
|
126
135
|
|
|
127
136
|
entry.attachedVideos.forEach(video => {
|
|
128
|
-
|
|
129
|
-
video.srcObject = null;
|
|
130
|
-
}
|
|
137
|
+
clearVideoIfAttachedStream(video, entry.stream);
|
|
131
138
|
});
|
|
132
139
|
|
|
133
140
|
notifyEntry(entry);
|
|
@@ -166,13 +173,13 @@ export function createCctvRtcStreamRegistry(): CctvRtcStreamRegistry {
|
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
entry.attachedVideos.add(video);
|
|
169
|
-
|
|
176
|
+
if (entry.stream || !video.srcObject) {
|
|
177
|
+
attachVideo(video, entry.stream);
|
|
178
|
+
}
|
|
170
179
|
|
|
171
180
|
return () => {
|
|
172
181
|
entry.attachedVideos.delete(video);
|
|
173
|
-
|
|
174
|
-
video.srcObject = null;
|
|
175
|
-
}
|
|
182
|
+
clearVideoIfAttachedStream(video, entry.stream);
|
|
176
183
|
};
|
|
177
184
|
},
|
|
178
185
|
closeAll() {
|
|
@@ -233,7 +240,12 @@ export function createCctvRtcStreamRegistry(): CctvRtcStreamRegistry {
|
|
|
233
240
|
};
|
|
234
241
|
|
|
235
242
|
entries.set(streamKey, entry);
|
|
236
|
-
|
|
243
|
+
if (!video.srcObject) {
|
|
244
|
+
attachVideo(video, null);
|
|
245
|
+
} else {
|
|
246
|
+
video.playsInline = true;
|
|
247
|
+
video.autoplay = true;
|
|
248
|
+
}
|
|
237
249
|
logCctvDebugEvent({
|
|
238
250
|
event: "start:create-entry",
|
|
239
251
|
payload: {
|
|
@@ -328,7 +340,7 @@ export function createCctvRtcStreamRegistry(): CctvRtcStreamRegistry {
|
|
|
328
340
|
source: "streamRegistry",
|
|
329
341
|
});
|
|
330
342
|
entry.attachedVideos.forEach(attachedVideo =>
|
|
331
|
-
|
|
343
|
+
clearVideoIfAttachedStream(attachedVideo, entry.stream),
|
|
332
344
|
);
|
|
333
345
|
notifyEntry(entry);
|
|
334
346
|
});
|
|
@@ -138,10 +138,10 @@ const canUseTokenForNewConnection = ({
|
|
|
138
138
|
* @desc
|
|
139
139
|
* return {
|
|
140
140
|
* videoRef, // WebRTC MediaStream을 연결할 video 요소 ref
|
|
141
|
-
* connectionState, // RTCPeerConnectionState 상태값
|
|
141
|
+
* connectionState, // UI 표시 기준 RTCPeerConnectionState 상태값
|
|
142
142
|
* streamError, // 스트림 시도 중 발생한 오류 메시지
|
|
143
|
-
* isStreaming, //
|
|
144
|
-
* isTokenLoading, // 토큰 발급
|
|
143
|
+
* isStreaming, // UI 표시 기준 스트림 연결 절차 진행 여부
|
|
144
|
+
* isTokenLoading, // UI 표시 기준 토큰 발급 요청 진행 여부
|
|
145
145
|
* isTokenError, // 토큰 발급 요청이 실패했는지 여부
|
|
146
146
|
* canReconnect, // UDS 내부 grace/stagger 이후 재연결 호출이 가능한지 여부
|
|
147
147
|
* refetchToken, // 토큰 발급을 재시도하는 함수
|
|
@@ -328,16 +328,34 @@ export function useCctvRtcStream({
|
|
|
328
328
|
streamIdentityKey,
|
|
329
329
|
]);
|
|
330
330
|
|
|
331
|
-
const
|
|
331
|
+
const isPostConnectedRecoverableState =
|
|
332
332
|
hasConnected &&
|
|
333
|
-
|
|
333
|
+
Boolean(streamIdentityKey) &&
|
|
334
|
+
!isTokenError &&
|
|
335
|
+
!streamError &&
|
|
334
336
|
DISPLAY_CONNECTED_DURING_RECOVERY_STATES.has(connectionState);
|
|
335
337
|
|
|
338
|
+
const isPostConnectedReplacementLoading =
|
|
339
|
+
hasConnected &&
|
|
340
|
+
Boolean(streamIdentityKey) &&
|
|
341
|
+
!isTokenError &&
|
|
342
|
+
!streamError &&
|
|
343
|
+
(isTokenLoading || isStreaming);
|
|
344
|
+
|
|
345
|
+
const shouldPreserveConnectedDisplay =
|
|
346
|
+
isPostConnectedReplacementLoading || isPostConnectedRecoverableState;
|
|
347
|
+
|
|
336
348
|
// 반환 state는 CamList/Viewer/overlay의 live/error/message 계산에 직접 쓰인다.
|
|
337
|
-
// post-connected
|
|
349
|
+
// post-connected recovery/replacement 중에는 canReconnect만 열고, 기존 화면은 유지해 UI reset 파동을 막는다.
|
|
338
350
|
const displayConnectionState = shouldPreserveConnectedDisplay
|
|
339
351
|
? "connected"
|
|
340
352
|
: connectionState;
|
|
353
|
+
const displayIsStreaming = shouldPreserveConnectedDisplay
|
|
354
|
+
? false
|
|
355
|
+
: isStreaming;
|
|
356
|
+
const displayIsTokenLoading = shouldPreserveConnectedDisplay
|
|
357
|
+
? false
|
|
358
|
+
: isTokenLoading;
|
|
341
359
|
|
|
342
360
|
const skippedDisconnectedDebugKeyRef = useRef<string | null>(null);
|
|
343
361
|
|
|
@@ -468,20 +486,39 @@ export function useCctvRtcStream({
|
|
|
468
486
|
if (!streamKey || !tokenQuery.data?.token || !endpoint || !currentVideo)
|
|
469
487
|
return;
|
|
470
488
|
|
|
471
|
-
|
|
489
|
+
const previousStreamKey =
|
|
472
490
|
activeStreamIdentityKeyRef.current === streamIdentityKey &&
|
|
473
491
|
activeStreamKeyRef.current !== streamKey
|
|
474
|
-
|
|
492
|
+
? activeStreamKeyRef.current
|
|
493
|
+
: null;
|
|
494
|
+
let didClosePreviousStream = false;
|
|
495
|
+
|
|
496
|
+
const closePreviousStreamAfterTrack = () => {
|
|
497
|
+
if (!previousStreamKey || didClosePreviousStream) return;
|
|
498
|
+
|
|
499
|
+
didClosePreviousStream = true;
|
|
475
500
|
logCctvDebugEvent({
|
|
476
|
-
event: "stream-effect:close-previous-
|
|
501
|
+
event: "stream-effect:close-previous-after-track",
|
|
477
502
|
payload: {
|
|
478
503
|
...debugBasePayload,
|
|
479
|
-
|
|
480
|
-
|
|
504
|
+
previousStreamKey: getCctvDebugKeyLabel(previousStreamKey),
|
|
505
|
+
streamKey: getCctvDebugKeyLabel(streamKey),
|
|
481
506
|
},
|
|
482
507
|
source: "useRtcStream",
|
|
483
508
|
});
|
|
484
509
|
streamRegistry.closeByIdentity(streamIdentityKey, streamKey);
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
if (previousStreamKey) {
|
|
513
|
+
logCctvDebugEvent({
|
|
514
|
+
event: "stream-effect:prepare-replacement",
|
|
515
|
+
payload: {
|
|
516
|
+
...debugBasePayload,
|
|
517
|
+
previousStreamKey: getCctvDebugKeyLabel(previousStreamKey),
|
|
518
|
+
streamKey: getCctvDebugKeyLabel(streamKey),
|
|
519
|
+
},
|
|
520
|
+
source: "useRtcStream",
|
|
521
|
+
});
|
|
485
522
|
}
|
|
486
523
|
|
|
487
524
|
activeStreamKeyRef.current = streamKey;
|
|
@@ -520,8 +557,11 @@ export function useCctvRtcStream({
|
|
|
520
557
|
});
|
|
521
558
|
setHasConnected(true);
|
|
522
559
|
}
|
|
523
|
-
if (snapshot.stream
|
|
524
|
-
currentVideo.srcObject
|
|
560
|
+
if (snapshot.stream) {
|
|
561
|
+
if (currentVideo.srcObject !== snapshot.stream) {
|
|
562
|
+
currentVideo.srcObject = snapshot.stream;
|
|
563
|
+
}
|
|
564
|
+
closePreviousStreamAfterTrack();
|
|
525
565
|
}
|
|
526
566
|
});
|
|
527
567
|
const snapshot = streamRegistry.getSnapshot(streamKey);
|
|
@@ -530,8 +570,11 @@ export function useCctvRtcStream({
|
|
|
530
570
|
setStreaming(snapshot.isStreaming);
|
|
531
571
|
if (snapshot.connectionState === "connected") setHasConnected(true);
|
|
532
572
|
|
|
533
|
-
if (snapshot.stream
|
|
534
|
-
currentVideo.srcObject
|
|
573
|
+
if (snapshot.stream) {
|
|
574
|
+
if (currentVideo.srcObject !== snapshot.stream) {
|
|
575
|
+
currentVideo.srcObject = snapshot.stream;
|
|
576
|
+
}
|
|
577
|
+
closePreviousStreamAfterTrack();
|
|
535
578
|
}
|
|
536
579
|
|
|
537
580
|
// effect cleanup: current video attach만 해제하고 registry stream은 유지한다.
|
|
@@ -602,17 +645,9 @@ export function useCctvRtcStream({
|
|
|
602
645
|
},
|
|
603
646
|
source: "useRtcStream",
|
|
604
647
|
});
|
|
605
|
-
if (result.isSuccess && streamIdentityKey) {
|
|
606
|
-
logCctvDebugEvent({
|
|
607
|
-
event: "reconnect-stream:close-identity",
|
|
608
|
-
payload: resultDebugState.debugBasePayload,
|
|
609
|
-
source: "useRtcStream",
|
|
610
|
-
});
|
|
611
|
-
streamRegistry.closeByIdentity(streamIdentityKey);
|
|
612
|
-
}
|
|
613
648
|
return result;
|
|
614
649
|
},
|
|
615
|
-
[refetchRtcToken
|
|
650
|
+
[refetchRtcToken],
|
|
616
651
|
);
|
|
617
652
|
|
|
618
653
|
const canReconnect = useMemo(() => {
|
|
@@ -681,18 +716,18 @@ export function useCctvRtcStream({
|
|
|
681
716
|
? getIsLive({
|
|
682
717
|
cam,
|
|
683
718
|
connectionState: displayConnectionState,
|
|
684
|
-
isTokenLoading,
|
|
719
|
+
isTokenLoading: displayIsTokenLoading,
|
|
685
720
|
isTokenError,
|
|
686
|
-
isStreaming,
|
|
721
|
+
isStreaming: displayIsStreaming,
|
|
687
722
|
streamError,
|
|
688
723
|
})
|
|
689
724
|
: false,
|
|
690
725
|
[
|
|
691
726
|
cam,
|
|
692
727
|
displayConnectionState,
|
|
693
|
-
|
|
728
|
+
displayIsTokenLoading,
|
|
694
729
|
isTokenError,
|
|
695
|
-
|
|
730
|
+
displayIsStreaming,
|
|
696
731
|
streamError,
|
|
697
732
|
],
|
|
698
733
|
);
|
|
@@ -706,7 +741,11 @@ export function useCctvRtcStream({
|
|
|
706
741
|
connectionState,
|
|
707
742
|
displayConnectionState,
|
|
708
743
|
hasConnected,
|
|
744
|
+
isPostConnectedReplacementLoading,
|
|
745
|
+
isPostConnectedRecoverableState,
|
|
709
746
|
isPostConnectedReconnectReady,
|
|
747
|
+
displayIsStreaming,
|
|
748
|
+
displayIsTokenLoading,
|
|
710
749
|
isStreaming,
|
|
711
750
|
isTokenError,
|
|
712
751
|
isTokenLoading,
|
|
@@ -721,7 +760,11 @@ export function useCctvRtcStream({
|
|
|
721
760
|
connectionState,
|
|
722
761
|
debugBasePayload,
|
|
723
762
|
displayConnectionState,
|
|
763
|
+
displayIsStreaming,
|
|
764
|
+
displayIsTokenLoading,
|
|
724
765
|
hasConnected,
|
|
766
|
+
isPostConnectedReplacementLoading,
|
|
767
|
+
isPostConnectedRecoverableState,
|
|
725
768
|
isPostConnectedReconnectReady,
|
|
726
769
|
isStreaming,
|
|
727
770
|
isTokenError,
|
|
@@ -770,8 +813,8 @@ export function useCctvRtcStream({
|
|
|
770
813
|
videoRef,
|
|
771
814
|
connectionState: displayConnectionState,
|
|
772
815
|
streamError,
|
|
773
|
-
isStreaming,
|
|
774
|
-
isTokenLoading,
|
|
816
|
+
isStreaming: displayIsStreaming,
|
|
817
|
+
isTokenLoading: displayIsTokenLoading,
|
|
775
818
|
isTokenError,
|
|
776
819
|
canReconnect,
|
|
777
820
|
refetchToken,
|
package/src/cctv/types/hook.ts
CHANGED
|
@@ -59,23 +59,33 @@ export interface UseCctvRtcStreamError {
|
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* CCTV; useCctvRtcStream 연결 상태
|
|
62
|
-
* @property {RTCPeerConnectionState} connectionState WebRTC 연결 상태
|
|
63
|
-
* @property {boolean} isStreaming startWhepStream 진행 여부
|
|
64
|
-
* @property {boolean} isTokenLoading 토큰 발급 요청 진행 여부
|
|
62
|
+
* @property {RTCPeerConnectionState} connectionState UI 표시 기준 WebRTC 연결 상태
|
|
63
|
+
* @property {boolean} isStreaming UI 표시 기준 startWhepStream 진행 여부
|
|
64
|
+
* @property {boolean} isTokenLoading UI 표시 기준 토큰 발급 요청 진행 여부
|
|
65
65
|
* @property {boolean} isTokenError 토큰 발급 실패 여부
|
|
66
66
|
* @property {string | null} streamError 스트림 오류 메시지
|
|
67
67
|
*/
|
|
68
68
|
export interface UseCctvRtcStreamState extends UseCctvRtcStreamError {
|
|
69
69
|
/**
|
|
70
|
-
* WebRTC 연결 상태
|
|
70
|
+
* UI 표시 기준 WebRTC 연결 상태
|
|
71
|
+
* @desc
|
|
72
|
+
* 최초 연결 전에는 실제 PeerConnection 상태를 나타낸다. 이미 한 번 연결된 stream이
|
|
73
|
+
* recoverable `disconnected`/`failed` 상태에 들어가면 기존 화면과 live count 유지를 위해
|
|
74
|
+
* `connected`로 smoothing될 수 있다.
|
|
71
75
|
*/
|
|
72
76
|
connectionState: RTCPeerConnectionState;
|
|
73
77
|
/**
|
|
74
|
-
* startWhepStream 진행 여부
|
|
78
|
+
* UI 표시 기준 startWhepStream 진행 여부
|
|
79
|
+
* @desc
|
|
80
|
+
* 최초 연결 전에는 실제 진행 상태를 나타낸다. 이미 한 번 연결된 stream을 교체하는 동안에는
|
|
81
|
+
* 기존 화면과 live count를 유지하기 위해 false로 smoothing될 수 있다.
|
|
75
82
|
*/
|
|
76
83
|
isStreaming: boolean;
|
|
77
84
|
/**
|
|
78
|
-
* 토큰 발급 요청 진행 여부
|
|
85
|
+
* UI 표시 기준 토큰 발급 요청 진행 여부
|
|
86
|
+
* @desc
|
|
87
|
+
* 최초 연결 전에는 실제 요청 상태를 나타낸다. 이미 한 번 연결된 stream의 재연결 token
|
|
88
|
+
* 재발급 중에는 기존 화면과 live count를 유지하기 위해 false로 smoothing될 수 있다.
|
|
79
89
|
*/
|
|
80
90
|
isTokenLoading: boolean;
|
|
81
91
|
}
|
|
@@ -83,10 +93,10 @@ export interface UseCctvRtcStreamState extends UseCctvRtcStreamError {
|
|
|
83
93
|
/**
|
|
84
94
|
* CCTV; useCctvRtcStream return
|
|
85
95
|
* @property {React.RefObject<HTMLVideoElement>} videoRef <video /> ref
|
|
86
|
-
* @property {RTCPeerConnectionState} connectionState WebRTC 연결 상태
|
|
96
|
+
* @property {RTCPeerConnectionState} connectionState UI 표시 기준 WebRTC 연결 상태
|
|
87
97
|
* @property {string | null} streamError 스트림 오류 메시지
|
|
88
|
-
* @property {boolean} isStreaming startWhepStream 진행 여부
|
|
89
|
-
* @property {boolean} isTokenLoading 토큰 발급 요청 진행 여부
|
|
98
|
+
* @property {boolean} isStreaming UI 표시 기준 startWhepStream 진행 여부
|
|
99
|
+
* @property {boolean} isTokenLoading UI 표시 기준 토큰 발급 요청 진행 여부
|
|
90
100
|
* @property {boolean} isTokenError 토큰 발급 실패 여부
|
|
91
101
|
* @property {boolean} canReconnect UDS 내부 허용 사유와 grace/stagger를 통과해 재연결 호출이 가능한지 여부
|
|
92
102
|
* @property {() => Promise<void>} refetchToken 토큰 재발급 함수
|
|
@@ -104,6 +114,7 @@ export interface UseCctvRtcStreamReturn extends UseCctvRtcStreamState {
|
|
|
104
114
|
* 서비스 overlay가 reconnectStream()을 호출해도 되는 시점에 true가 된다.
|
|
105
115
|
* post-connected `disconnected`는 자동 재연결 사유가 아니며,
|
|
106
116
|
* token/stream 오류 또는 `failed`처럼 명확한 복구 사유만 true 전환 후보가 된다.
|
|
117
|
+
* recoverable `failed`에서는 화면이 live로 유지되는 동안에도 true가 될 수 있다.
|
|
107
118
|
*/
|
|
108
119
|
canReconnect: boolean;
|
|
109
120
|
/**
|
|
@@ -6,12 +6,13 @@ import type { UseCctvRtcStreamError, UseCctvRtcStreamState } from "./hook";
|
|
|
6
6
|
* @property {CctvCompanyCameraData} [cam] 카메라 데이터
|
|
7
7
|
* @property {boolean} [hasCamProp] 직접 cam prop을 받은 경우 true
|
|
8
8
|
* @property {boolean} [isFetching] 서버에서 cam 리스트를 가져오는 중인지 여부
|
|
9
|
-
* @property {RTCPeerConnectionState} connectionState WebRTC 연결 상태
|
|
10
|
-
* @property {boolean} isStreaming startWhepStream 진행 여부
|
|
11
|
-
* @property {boolean} isTokenLoading 토큰 발급 요청 진행 여부
|
|
9
|
+
* @property {RTCPeerConnectionState} connectionState UI 표시 기준 WebRTC 연결 상태
|
|
10
|
+
* @property {boolean} isStreaming UI 표시 기준 startWhepStream 진행 여부
|
|
11
|
+
* @property {boolean} isTokenLoading UI 표시 기준 토큰 발급 요청 진행 여부
|
|
12
12
|
* @property {boolean} isTokenError 토큰 발급 실패 여부
|
|
13
13
|
* @property {string | null} streamError 스트림 오류 메시지
|
|
14
|
-
* @property {boolean} [canReconnect] UDS 내부 허용 사유와 grace/stagger를 통과해 재연결 호출이 가능한지
|
|
14
|
+
* @property {boolean} [canReconnect] UDS 내부 허용 사유와 grace/stagger를 통과해 재연결 호출이 가능한지 여부.
|
|
15
|
+
* 오류 스타일 판정에는 직접 사용하지 않는다.
|
|
15
16
|
*/
|
|
16
17
|
export interface CctvVideoOverlayMessageParams extends UseCctvRtcStreamState {
|
|
17
18
|
/**
|
|
@@ -28,6 +29,8 @@ export interface CctvVideoOverlayMessageParams extends UseCctvRtcStreamState {
|
|
|
28
29
|
isFetching?: boolean;
|
|
29
30
|
/**
|
|
30
31
|
* UDS 내부 허용 사유와 grace/stagger를 통과해 재연결 호출이 가능한지 여부
|
|
32
|
+
* @desc
|
|
33
|
+
* 재연결 trigger gate이며, 기본 error style 판정에는 직접 사용하지 않는다.
|
|
31
34
|
*/
|
|
32
35
|
canReconnect?: boolean;
|
|
33
36
|
}
|
|
@@ -35,9 +38,9 @@ export interface CctvVideoOverlayMessageParams extends UseCctvRtcStreamState {
|
|
|
35
38
|
/**
|
|
36
39
|
* CCTV; getIsLive() params
|
|
37
40
|
* @property {CctvCompanyCameraData} [cam] 카메라 데이터
|
|
38
|
-
* @property {RTCPeerConnectionState} connectionState WebRTC 연결 상태
|
|
39
|
-
* @property {boolean} isStreaming startWhepStream 진행 여부
|
|
40
|
-
* @property {boolean} isTokenLoading 토큰 발급 요청 진행 여부
|
|
41
|
+
* @property {RTCPeerConnectionState} connectionState UI 표시 기준 WebRTC 연결 상태
|
|
42
|
+
* @property {boolean} isStreaming UI 표시 기준 startWhepStream 진행 여부
|
|
43
|
+
* @property {boolean} isTokenLoading UI 표시 기준 토큰 발급 요청 진행 여부
|
|
41
44
|
* @property {boolean} isTokenError 토큰 발급 실패 여부
|
|
42
45
|
* @property {string | null} streamError 스트림 오류 메시지
|
|
43
46
|
*/
|
|
@@ -53,7 +56,8 @@ export interface CctvVideoLiveParams extends UseCctvRtcStreamState {
|
|
|
53
56
|
* @property {CctvCompanyCameraData} [cam] 카메라 데이터
|
|
54
57
|
* @property {boolean} isTokenError 토큰 발급 실패 여부
|
|
55
58
|
* @property {string | null} streamError 스트림 오류 메시지
|
|
56
|
-
* @property {boolean} [canReconnect] UDS 내부 허용 사유와 grace/stagger를 통과해 재연결 호출이 가능한지
|
|
59
|
+
* @property {boolean} [canReconnect] UDS 내부 허용 사유와 grace/stagger를 통과해 재연결 호출이 가능한지 여부.
|
|
60
|
+
* 오류 스타일 판정에는 직접 사용하지 않는다.
|
|
57
61
|
*/
|
|
58
62
|
export interface CctvVideoErrorParams extends UseCctvRtcStreamError {
|
|
59
63
|
/**
|
|
@@ -62,6 +66,8 @@ export interface CctvVideoErrorParams extends UseCctvRtcStreamError {
|
|
|
62
66
|
cam?: CctvCompanyCameraData;
|
|
63
67
|
/**
|
|
64
68
|
* UDS 내부 허용 사유와 grace/stagger를 통과해 재연결 호출이 가능한지 여부
|
|
69
|
+
* @desc
|
|
70
|
+
* 재연결 trigger gate이며, 기본 error style 판정에는 직접 사용하지 않는다.
|
|
65
71
|
*/
|
|
66
72
|
canReconnect?: boolean;
|
|
67
73
|
}
|
|
@@ -31,9 +31,9 @@ const RTC_SESSION_ENDED_RECONNECT_STATES = new Set<RTCPeerConnectionState>([
|
|
|
31
31
|
* @property {CctvCompanyCameraData} [cam] 카메라 데이터
|
|
32
32
|
* @property {boolean} [hasCamProp] 직접 cam prop을 받은 경우 true
|
|
33
33
|
* @property {boolean} [isFetching] 서버에서 cam 리스트를 가져오는 중인지 여부
|
|
34
|
-
* @property {RTCPeerConnectionState} connectionState WebRTC 연결 상태
|
|
35
|
-
* @property {boolean} isStreaming startWhepStream 진행 여부
|
|
36
|
-
* @property {boolean} isTokenLoading 토큰 발급 요청 진행 여부
|
|
34
|
+
* @property {RTCPeerConnectionState} connectionState UI 표시 기준 WebRTC 연결 상태
|
|
35
|
+
* @property {boolean} isStreaming UI 표시 기준 startWhepStream 진행 여부
|
|
36
|
+
* @property {boolean} isTokenLoading UI 표시 기준 토큰 발급 요청 진행 여부
|
|
37
37
|
* @property {boolean} isTokenError 토큰 발급 실패 여부
|
|
38
38
|
* @property {string | null} streamError 스트림 오류 메시지
|
|
39
39
|
* @returns {string | null} 상태에 따른 메시지 반환 (문제가 없으면 null)
|
|
@@ -72,9 +72,9 @@ export function getOverlayMessage({
|
|
|
72
72
|
* CCTV; 스트리밍 라이브 상태 판단
|
|
73
73
|
* @param {CctvVideoLiveParams} params 상태 파라미터
|
|
74
74
|
* @property {CctvCompanyCameraData} [cam] 카메라 데이터
|
|
75
|
-
* @property {RTCPeerConnectionState} connectionState WebRTC 연결 상태
|
|
76
|
-
* @property {boolean} isStreaming startWhepStream 진행 여부
|
|
77
|
-
* @property {boolean} isTokenLoading 토큰 발급 요청 진행 여부
|
|
75
|
+
* @property {RTCPeerConnectionState} connectionState UI 표시 기준 WebRTC 연결 상태
|
|
76
|
+
* @property {boolean} isStreaming UI 표시 기준 startWhepStream 진행 여부
|
|
77
|
+
* @property {boolean} isTokenLoading UI 표시 기준 토큰 발급 요청 진행 여부
|
|
78
78
|
* @property {boolean} isTokenError 토큰 발급 실패 여부
|
|
79
79
|
* @property {string | null} streamError 스트림 오류 메시지
|
|
80
80
|
* @returns {boolean} 라이브 상태 여부 반환
|
|
@@ -102,17 +102,16 @@ export function getIsLive({
|
|
|
102
102
|
* @property {CctvCompanyCameraData} [cam] 카메라 데이터
|
|
103
103
|
* @property {boolean} isTokenError 토큰 발급 실패 여부
|
|
104
104
|
* @property {string | null} streamError 스트림 오류 메시지
|
|
105
|
+
* @property {boolean} [canReconnect] 재연결 trigger 가능 여부. 오류 표시 여부에는 직접 사용하지 않는다.
|
|
105
106
|
* @returns {boolean} 에러 상태 여부 반환
|
|
106
107
|
*/
|
|
107
108
|
export function getIsError({
|
|
108
109
|
cam,
|
|
109
|
-
canReconnect,
|
|
110
110
|
isTokenError,
|
|
111
111
|
streamError,
|
|
112
112
|
}: CctvVideoErrorParams): boolean {
|
|
113
113
|
if (!cam) return true;
|
|
114
114
|
if (!cam.cam_online) return true;
|
|
115
|
-
if (canReconnect) return true;
|
|
116
115
|
if (isTokenError) return true;
|
|
117
116
|
if (streamError) return true;
|
|
118
117
|
return false;
|