@100mslive/react-native-hms 1.12.2 → 2.0.0-alpha.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/android/build.gradle +70 -12
- package/android/src/main/java/com/reactnativehmssdk/HMSAudioshareActivity.kt +8 -8
- package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayer.kt +38 -12
- package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManagerImpl.kt +185 -0
- package/android/src/main/java/com/reactnativehmssdk/HMSHelper.kt +20 -10
- package/android/src/main/java/com/reactnativehmssdk/{HMSManager.kt → HMSManagerImpl.kt} +28 -111
- package/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt +3 -3
- package/android/src/main/java/com/reactnativehmssdk/HMSReactNativeEvent.kt +29 -0
- package/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManagerImpl.kt +119 -0
- package/android/src/main/java/com/reactnativehmssdk/HMSView.kt +33 -5
- package/android/src/main/java/com/reactnativehmssdk/HmsScreenshareActivity.kt +9 -9
- package/android/src/main/java/com/reactnativehmssdk/HmssdkPackage.kt +42 -3
- package/android/src/newarch/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +128 -0
- package/android/src/newarch/java/com/reactnativehmssdk/HMSManager.kt +332 -0
- package/android/src/newarch/java/com/reactnativehmssdk/HMSSDKViewManager.kt +102 -0
- package/android/src/oldarch/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +61 -0
- package/android/src/oldarch/java/com/reactnativehmssdk/HMSManager.kt +351 -0
- package/android/src/oldarch/java/com/reactnativehmssdk/HMSSDKViewManager.kt +87 -0
- package/ios/HMSHLSPlayerComponentView.mm +325 -0
- package/ios/HMSHLSPlayerManager.m +10 -0
- package/ios/HMSHLSPlayerManager.swift +91 -79
- package/ios/HMSManager.m +13 -0
- package/ios/HMSManager.mm +365 -0
- package/ios/HMSManager.swift +109 -103
- package/ios/HMSView.m +9 -0
- package/ios/HMSView.swift +44 -14
- package/ios/HMSViewComponentView.mm +229 -0
- package/lib/commonjs/classes/HmsView.js +45 -48
- package/lib/commonjs/classes/HmsView.js.map +1 -1
- package/lib/commonjs/components/HMSHLSPlayer/HMSHLSPlayer.js +46 -26
- package/lib/commonjs/components/HMSHLSPlayer/HMSHLSPlayer.js.map +1 -1
- package/lib/commonjs/components/HMSHLSPlayer/RCTHMSHLSPlayer.js +5 -4
- package/lib/commonjs/components/HMSHLSPlayer/RCTHMSHLSPlayer.js.map +1 -1
- package/lib/commonjs/modules/HMSManagerModule.js +3 -10
- package/lib/commonjs/modules/HMSManagerModule.js.map +1 -1
- package/lib/commonjs/specs/HMSHLSPlayerNativeComponent.js +75 -0
- package/lib/commonjs/specs/HMSHLSPlayerNativeComponent.js.map +1 -0
- package/lib/commonjs/specs/HMSViewNativeComponent.js +55 -0
- package/lib/commonjs/specs/HMSViewNativeComponent.js.map +1 -0
- package/lib/commonjs/specs/NativeHMSManager.js +38 -0
- package/lib/commonjs/specs/NativeHMSManager.js.map +1 -0
- package/lib/module/classes/HmsView.js +46 -49
- package/lib/module/classes/HmsView.js.map +1 -1
- package/lib/module/components/HMSHLSPlayer/HMSHLSPlayer.js +48 -28
- package/lib/module/components/HMSHLSPlayer/HMSHLSPlayer.js.map +1 -1
- package/lib/module/components/HMSHLSPlayer/RCTHMSHLSPlayer.js +3 -3
- package/lib/module/components/HMSHLSPlayer/RCTHMSHLSPlayer.js.map +1 -1
- package/lib/module/modules/HMSManagerModule.js +1 -9
- package/lib/module/modules/HMSManagerModule.js.map +1 -1
- package/lib/module/specs/HMSHLSPlayerNativeComponent.js +69 -0
- package/lib/module/specs/HMSHLSPlayerNativeComponent.js.map +1 -0
- package/lib/module/specs/HMSViewNativeComponent.js +49 -0
- package/lib/module/specs/HMSViewNativeComponent.js.map +1 -0
- package/lib/module/specs/NativeHMSManager.js +33 -0
- package/lib/module/specs/NativeHMSManager.js.map +1 -0
- package/lib/typescript/components/HMSHLSPlayer/RCTHMSHLSPlayer.d.ts +6 -9
- package/lib/typescript/specs/HMSHLSPlayerNativeComponent.d.ts +115 -0
- package/lib/typescript/specs/HMSViewNativeComponent.d.ts +97 -0
- package/lib/typescript/specs/NativeHMSManager.d.ts +147 -0
- package/package.json +16 -1
- package/react-native-hms.podspec +43 -0
- package/src/classes/HmsView.tsx +60 -78
- package/src/components/HMSHLSPlayer/HMSHLSPlayer.tsx +62 -128
- package/src/components/HMSHLSPlayer/RCTHMSHLSPlayer.ts +8 -13
- package/src/modules/HMSManagerModule.ts +1 -14
- package/src/specs/HMSHLSPlayerNativeComponent.ts +203 -0
- package/src/specs/HMSViewNativeComponent.ts +119 -0
- package/src/specs/NativeHMSManager.ts +307 -0
- package/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt +0 -144
- package/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt +0 -111
package/src/classes/HmsView.tsx
CHANGED
|
@@ -1,57 +1,21 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from 'react-native';
|
|
1
|
+
import React, {
|
|
2
|
+
useEffect,
|
|
3
|
+
useImperativeHandle,
|
|
4
|
+
useMemo,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
8
|
+
import { StyleSheet, Platform } from 'react-native';
|
|
9
9
|
import type { NativeSyntheticEvent, ViewStyle } from 'react-native';
|
|
10
|
+
import HmsView, { Commands } from '../specs/HMSViewNativeComponent';
|
|
10
11
|
import { HMSConstants } from './HMSConstants';
|
|
11
12
|
import { HMSVideoViewMode } from './HMSVideoViewMode';
|
|
12
13
|
import { setHmsViewsResolutionsState } from '../hooks/hmsviews';
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
* properties for configuring the video track display, such as the track ID, mirroring options,
|
|
19
|
-
* and scale type. It also includes properties for handling events and customizing the component's style.
|
|
20
|
-
*
|
|
21
|
-
* @interface HmsViewProps
|
|
22
|
-
* @property {Object} data - An object containing the track ID, instance ID, mirroring option, and scale type for the video or audio track.
|
|
23
|
-
* @property {string} data.trackId - The unique identifier for the track to be displayed.
|
|
24
|
-
* @property {string} data.id - The identifier for the `HmsViewComponent` instance.
|
|
25
|
-
* @property {boolean} data.mirror - Indicates whether the video should be mirrored. This is commonly used for local video tracks.
|
|
26
|
-
* @property {HMSVideoViewMode} data.scaleType - Determines how the video fits within the bounds of the view (e.g., aspect fill, aspect fit).
|
|
27
|
-
* @property {boolean} autoSimulcast - Enables automatic simulcast layer switching based on network conditions, if supported.
|
|
28
|
-
* @property {boolean} setZOrderMediaOverlay - When true, the video view will be rendered above the regular view hierarchy.
|
|
29
|
-
* @property {ViewStyle} style - Custom styles to apply to the view.
|
|
30
|
-
* @property {Function} onChange - A callback function that is invoked when the `HmsView` component emits a change event.
|
|
31
|
-
* @property {Function} onDataReturned - A callback function that is invoked when the `HmsView` component returns data in response to a capture frame event.
|
|
32
|
-
*
|
|
33
|
-
* @see {https://www.100ms.live/docs/react-native/v2/how-to-guides/set-up-video-conferencing/render-video/overview}
|
|
34
|
-
*/
|
|
35
|
-
interface HmsViewProps {
|
|
36
|
-
data: {
|
|
37
|
-
trackId: string;
|
|
38
|
-
id: string;
|
|
39
|
-
mirror: boolean;
|
|
40
|
-
scaleType: HMSVideoViewMode;
|
|
41
|
-
};
|
|
42
|
-
autoSimulcast: boolean;
|
|
43
|
-
setZOrderMediaOverlay: boolean;
|
|
44
|
-
scaleType: HMSVideoViewMode;
|
|
45
|
-
style: ViewStyle;
|
|
46
|
-
onChange: Function;
|
|
47
|
-
onDataReturned: Function;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Imports the `HmsView` component from the native side using the `requireNativeComponent` function.
|
|
51
|
-
// This component is used to render video tracks in the application.
|
|
52
|
-
const HmsView = requireNativeComponent<HmsViewProps>('HMSView');
|
|
53
|
-
let _nextRequestId = 1;
|
|
54
|
-
let _requestMap = new Map();
|
|
15
|
+
type CapturePromiseMethods = {
|
|
16
|
+
resolve: (value: unknown) => void;
|
|
17
|
+
reject: (reason?: unknown) => void;
|
|
18
|
+
};
|
|
55
19
|
|
|
56
20
|
/**
|
|
57
21
|
* Defines the properties for the `HmsViewComponent`.
|
|
@@ -93,12 +57,25 @@ export const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(
|
|
|
93
57
|
|
|
94
58
|
const hmsViewRef: any = useRef();
|
|
95
59
|
const [applyStyles_ANDROID, setApplyStyles_ANDROID] = useState(false);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
60
|
+
// Memoized so the object reference is stable across renders unless one
|
|
61
|
+
// of the inputs actually changes. Fabric diffs view props by reference
|
|
62
|
+
// before doing a deep compare — a fresh `{...}` on every render would
|
|
63
|
+
// trigger redundant native prop updates.
|
|
64
|
+
const data = useMemo(
|
|
65
|
+
() => ({ trackId, id, mirror, scaleType }),
|
|
66
|
+
[trackId, id, mirror, scaleType]
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// Per-instance request/response state for the `capture` imperative.
|
|
70
|
+
// Each `<HmsView />` gets its own counter + pending-promise map so:
|
|
71
|
+
// - requestIds can't collide across multiple HmsView instances
|
|
72
|
+
// - pending promises are scoped to this view and cleaned up when
|
|
73
|
+
// it unmounts (see the useEffect below)
|
|
74
|
+
const nextRequestId = useRef(1);
|
|
75
|
+
const requestMap = useMemo(
|
|
76
|
+
() => new Map<number, CapturePromiseMethods>(),
|
|
77
|
+
[]
|
|
78
|
+
);
|
|
102
79
|
|
|
103
80
|
/**
|
|
104
81
|
* This method is passed to `onChange` prop of `HmsView` Native Component.
|
|
@@ -126,38 +103,30 @@ export const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(
|
|
|
126
103
|
const _onDataReturned = (event: {
|
|
127
104
|
nativeEvent: { requestId: any; result: any; error: any };
|
|
128
105
|
}) => {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
106
|
+
const { requestId, result, error } = event.nativeEvent;
|
|
107
|
+
const promise = requestMap.get(requestId);
|
|
108
|
+
if (!promise) {
|
|
109
|
+
// No pending request — typically a late event after unmount/cleanup
|
|
110
|
+
// rejected it, or a stale requestId from a previous mount.
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
133
113
|
if (result) {
|
|
134
|
-
// If it was successful, we resolve the promise.
|
|
135
114
|
promise.resolve(result);
|
|
136
115
|
} else {
|
|
137
|
-
// Otherwise, we reject it.
|
|
138
116
|
promise.reject(error);
|
|
139
117
|
}
|
|
140
|
-
|
|
141
|
-
_requestMap.delete(requestId);
|
|
118
|
+
requestMap.delete(requestId);
|
|
142
119
|
};
|
|
143
120
|
|
|
144
121
|
const capture = async () => {
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
let requestId = _nextRequestId++;
|
|
148
|
-
let requestMap = _requestMap;
|
|
149
|
-
|
|
150
|
-
// We create a promise here that will be resolved once `_onRequestDone` is
|
|
151
|
-
// called.
|
|
152
|
-
let promise = new Promise(function (resolve, reject) {
|
|
122
|
+
const requestId = nextRequestId.current++;
|
|
123
|
+
const promise = new Promise((resolve, reject) => {
|
|
153
124
|
requestMap.set(requestId, { resolve, reject });
|
|
154
125
|
});
|
|
155
126
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
[requestId]
|
|
160
|
-
);
|
|
127
|
+
if (hmsViewRef.current) {
|
|
128
|
+
Commands.capture(hmsViewRef.current, requestId);
|
|
129
|
+
}
|
|
161
130
|
return promise;
|
|
162
131
|
};
|
|
163
132
|
|
|
@@ -167,10 +136,23 @@ export const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(
|
|
|
167
136
|
};
|
|
168
137
|
});
|
|
169
138
|
|
|
139
|
+
// Reject any in-flight capture promises on unmount. Under bridgeless
|
|
140
|
+
// mode the native side may not be able to deliver the captureFrame
|
|
141
|
+
// event back (event dispatcher returns null when the React tag is
|
|
142
|
+
// gone), which would leave promises hanging in the map forever.
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
return () => {
|
|
145
|
+
requestMap.forEach(({ reject }) => {
|
|
146
|
+
reject(new Error('HmsView unmounted before capture completed'));
|
|
147
|
+
});
|
|
148
|
+
requestMap.clear();
|
|
149
|
+
};
|
|
150
|
+
}, [requestMap]);
|
|
151
|
+
|
|
170
152
|
return (
|
|
171
153
|
<HmsView
|
|
172
154
|
ref={hmsViewRef}
|
|
173
|
-
|
|
155
|
+
onResolutionChange={onChange as any}
|
|
174
156
|
data={data}
|
|
175
157
|
style={
|
|
176
158
|
Platform.OS === 'android' ? (applyStyles_ANDROID ? style : {}) : style
|
|
@@ -178,7 +160,7 @@ export const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(
|
|
|
178
160
|
autoSimulcast={autoSimulcast}
|
|
179
161
|
scaleType={scaleType}
|
|
180
162
|
setZOrderMediaOverlay={setZOrderMediaOverlay}
|
|
181
|
-
onDataReturned={_onDataReturned}
|
|
163
|
+
onDataReturned={_onDataReturned as any}
|
|
182
164
|
/>
|
|
183
165
|
);
|
|
184
166
|
}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useImperativeHandle, useMemo, useRef } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
StyleSheet,
|
|
5
|
-
UIManager,
|
|
6
|
-
findNodeHandle,
|
|
7
|
-
Platform,
|
|
8
|
-
} from 'react-native';
|
|
2
|
+
import { View, StyleSheet, Platform } from 'react-native';
|
|
9
3
|
import type { StyleProp, ViewStyle } from 'react-native';
|
|
10
4
|
|
|
11
5
|
import {
|
|
@@ -17,10 +11,7 @@ import {
|
|
|
17
11
|
setHMSHLSPlayerStatsError,
|
|
18
12
|
setHMSHLSPlayerSubtitles,
|
|
19
13
|
} from './hooks';
|
|
20
|
-
import {
|
|
21
|
-
RCTHMSHLSPlayer,
|
|
22
|
-
RCTHMSHLSPlayerViewManagerConfig,
|
|
23
|
-
} from './RCTHMSHLSPlayer';
|
|
14
|
+
import { RCTHMSHLSPlayer, RCTHMSHLSPlayerCommands } from './RCTHMSHLSPlayer';
|
|
24
15
|
import type {
|
|
25
16
|
HlsSPlayerCuesEventHandler,
|
|
26
17
|
HmsHlsPlaybackEventHandler,
|
|
@@ -87,52 +78,30 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction<
|
|
|
87
78
|
useImperativeHandle(
|
|
88
79
|
ref,
|
|
89
80
|
() => ({
|
|
81
|
+
// `url` is optional at the JS API level: omit it (or pass undefined)
|
|
82
|
+
// to play the URL currently configured on the player; pass a string
|
|
83
|
+
// to switch to a new stream. The Codegen `play` command signature is
|
|
84
|
+
// `(viewRef, url: string)` (non-optional), so we pass `''` to mean
|
|
85
|
+
// "no override" — the native side treats empty-string as the
|
|
86
|
+
// "use existing url" sentinel.
|
|
90
87
|
play: (url?: string) => {
|
|
91
|
-
if (
|
|
92
|
-
hmsHlsPlayerRef.current
|
|
93
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.play
|
|
94
|
-
) {
|
|
95
|
-
UIManager.dispatchViewManagerCommand(
|
|
96
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
97
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.play,
|
|
98
|
-
url ? [url] : ['']
|
|
99
|
-
);
|
|
88
|
+
if (hmsHlsPlayerRef.current) {
|
|
89
|
+
RCTHMSHLSPlayerCommands.play(hmsHlsPlayerRef.current, url ?? '');
|
|
100
90
|
}
|
|
101
91
|
},
|
|
102
92
|
stop: () => {
|
|
103
|
-
if (
|
|
104
|
-
hmsHlsPlayerRef.current
|
|
105
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.stop
|
|
106
|
-
) {
|
|
107
|
-
UIManager.dispatchViewManagerCommand(
|
|
108
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
109
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.stop,
|
|
110
|
-
undefined
|
|
111
|
-
);
|
|
93
|
+
if (hmsHlsPlayerRef.current) {
|
|
94
|
+
RCTHMSHLSPlayerCommands.stop(hmsHlsPlayerRef.current);
|
|
112
95
|
}
|
|
113
96
|
},
|
|
114
97
|
pause: () => {
|
|
115
|
-
if (
|
|
116
|
-
hmsHlsPlayerRef.current
|
|
117
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.pause
|
|
118
|
-
) {
|
|
119
|
-
UIManager.dispatchViewManagerCommand(
|
|
120
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
121
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.pause,
|
|
122
|
-
undefined
|
|
123
|
-
);
|
|
98
|
+
if (hmsHlsPlayerRef.current) {
|
|
99
|
+
RCTHMSHLSPlayerCommands.pause(hmsHlsPlayerRef.current);
|
|
124
100
|
}
|
|
125
101
|
},
|
|
126
102
|
resume: () => {
|
|
127
|
-
if (
|
|
128
|
-
hmsHlsPlayerRef.current
|
|
129
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.resume
|
|
130
|
-
) {
|
|
131
|
-
UIManager.dispatchViewManagerCommand(
|
|
132
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
133
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.resume,
|
|
134
|
-
undefined
|
|
135
|
-
);
|
|
103
|
+
if (hmsHlsPlayerRef.current) {
|
|
104
|
+
RCTHMSHLSPlayerCommands.resume(hmsHlsPlayerRef.current);
|
|
136
105
|
}
|
|
137
106
|
},
|
|
138
107
|
seekForward: (seconds: number) => {
|
|
@@ -144,15 +113,8 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction<
|
|
|
144
113
|
);
|
|
145
114
|
}
|
|
146
115
|
|
|
147
|
-
if (
|
|
148
|
-
hmsHlsPlayerRef.current
|
|
149
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.seekForward
|
|
150
|
-
) {
|
|
151
|
-
UIManager.dispatchViewManagerCommand(
|
|
152
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
153
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.seekForward,
|
|
154
|
-
[seconds]
|
|
155
|
-
);
|
|
116
|
+
if (hmsHlsPlayerRef.current) {
|
|
117
|
+
RCTHMSHLSPlayerCommands.seekForward(hmsHlsPlayerRef.current, seconds);
|
|
156
118
|
}
|
|
157
119
|
},
|
|
158
120
|
seekBackward: (seconds: number) => {
|
|
@@ -164,27 +126,16 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction<
|
|
|
164
126
|
);
|
|
165
127
|
}
|
|
166
128
|
|
|
167
|
-
if (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
UIManager.dispatchViewManagerCommand(
|
|
172
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
173
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.seekBackward,
|
|
174
|
-
[seconds]
|
|
129
|
+
if (hmsHlsPlayerRef.current) {
|
|
130
|
+
RCTHMSHLSPlayerCommands.seekBackward(
|
|
131
|
+
hmsHlsPlayerRef.current,
|
|
132
|
+
seconds
|
|
175
133
|
);
|
|
176
134
|
}
|
|
177
135
|
},
|
|
178
136
|
seekToLivePosition: () => {
|
|
179
|
-
if (
|
|
180
|
-
hmsHlsPlayerRef.current
|
|
181
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.seekToLivePosition
|
|
182
|
-
) {
|
|
183
|
-
UIManager.dispatchViewManagerCommand(
|
|
184
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
185
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.seekToLivePosition,
|
|
186
|
-
undefined
|
|
187
|
-
);
|
|
137
|
+
if (hmsHlsPlayerRef.current) {
|
|
138
|
+
RCTHMSHLSPlayerCommands.seekToLivePosition(hmsHlsPlayerRef.current);
|
|
188
139
|
}
|
|
189
140
|
},
|
|
190
141
|
setVolume: (level: number) => {
|
|
@@ -194,84 +145,52 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction<
|
|
|
194
145
|
);
|
|
195
146
|
}
|
|
196
147
|
|
|
197
|
-
if (
|
|
198
|
-
hmsHlsPlayerRef.current
|
|
199
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.setVolume
|
|
200
|
-
) {
|
|
201
|
-
UIManager.dispatchViewManagerCommand(
|
|
202
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
203
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.setVolume,
|
|
204
|
-
[level]
|
|
205
|
-
);
|
|
148
|
+
if (hmsHlsPlayerRef.current) {
|
|
149
|
+
RCTHMSHLSPlayerCommands.setVolume(hmsHlsPlayerRef.current, level);
|
|
206
150
|
}
|
|
207
151
|
},
|
|
208
152
|
isClosedCaptionSupported: () => {
|
|
209
|
-
if (
|
|
210
|
-
hmsHlsPlayerRef.current &&
|
|
211
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.areClosedCaptionSupported
|
|
212
|
-
) {
|
|
153
|
+
if (hmsHlsPlayerRef.current) {
|
|
213
154
|
const requestId = currentRequestId.current++;
|
|
214
155
|
const promise = new Promise<boolean>((resolve, reject) => {
|
|
215
156
|
promiseAndIdsMap.set(requestId, { resolve, reject });
|
|
216
157
|
});
|
|
217
158
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
[requestId]
|
|
159
|
+
RCTHMSHLSPlayerCommands.areClosedCaptionSupported(
|
|
160
|
+
hmsHlsPlayerRef.current,
|
|
161
|
+
requestId
|
|
222
162
|
);
|
|
223
163
|
return promise;
|
|
224
164
|
}
|
|
225
165
|
return Promise.resolve(false);
|
|
226
166
|
},
|
|
227
167
|
isClosedCaptionEnabled: () => {
|
|
228
|
-
if (
|
|
229
|
-
hmsHlsPlayerRef.current &&
|
|
230
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.isClosedCaptionEnabled
|
|
231
|
-
) {
|
|
168
|
+
if (hmsHlsPlayerRef.current) {
|
|
232
169
|
const requestId = currentRequestId.current++;
|
|
233
170
|
const promise = new Promise<boolean>((resolve, reject) => {
|
|
234
171
|
promiseAndIdsMap.set(requestId, { resolve, reject });
|
|
235
172
|
});
|
|
236
173
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
[requestId]
|
|
174
|
+
RCTHMSHLSPlayerCommands.isClosedCaptionEnabled(
|
|
175
|
+
hmsHlsPlayerRef.current,
|
|
176
|
+
requestId
|
|
241
177
|
);
|
|
242
178
|
return promise;
|
|
243
179
|
}
|
|
244
180
|
return Promise.resolve(false);
|
|
245
181
|
},
|
|
246
182
|
enableClosedCaption: () => {
|
|
247
|
-
if (
|
|
248
|
-
hmsHlsPlayerRef.current
|
|
249
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.enableClosedCaption
|
|
250
|
-
) {
|
|
251
|
-
UIManager.dispatchViewManagerCommand(
|
|
252
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
253
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.enableClosedCaption,
|
|
254
|
-
undefined
|
|
255
|
-
);
|
|
183
|
+
if (hmsHlsPlayerRef.current) {
|
|
184
|
+
RCTHMSHLSPlayerCommands.enableClosedCaption(hmsHlsPlayerRef.current);
|
|
256
185
|
}
|
|
257
186
|
},
|
|
258
187
|
disableClosedCaption: () => {
|
|
259
|
-
if (
|
|
260
|
-
hmsHlsPlayerRef.current
|
|
261
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.disableClosedCaption
|
|
262
|
-
) {
|
|
263
|
-
UIManager.dispatchViewManagerCommand(
|
|
264
|
-
findNodeHandle(hmsHlsPlayerRef.current),
|
|
265
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.disableClosedCaption,
|
|
266
|
-
undefined
|
|
267
|
-
);
|
|
188
|
+
if (hmsHlsPlayerRef.current) {
|
|
189
|
+
RCTHMSHLSPlayerCommands.disableClosedCaption(hmsHlsPlayerRef.current);
|
|
268
190
|
}
|
|
269
191
|
},
|
|
270
192
|
getPlayerDurationDetails: () => {
|
|
271
|
-
if (
|
|
272
|
-
hmsHlsPlayerRef.current &&
|
|
273
|
-
RCTHMSHLSPlayerViewManagerConfig.Commands.getPlayerDurationDetails
|
|
274
|
-
) {
|
|
193
|
+
if (hmsHlsPlayerRef.current) {
|
|
275
194
|
const requestId = currentRequestId.current++;
|
|
276
195
|
const promise = new Promise<HLSPlayerDurationDetails>(
|
|
277
196
|
(resolve, reject) => {
|
|
@@ -279,10 +198,9 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction<
|
|
|
279
198
|
}
|
|
280
199
|
);
|
|
281
200
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
[requestId]
|
|
201
|
+
RCTHMSHLSPlayerCommands.getPlayerDurationDetails(
|
|
202
|
+
hmsHlsPlayerRef.current,
|
|
203
|
+
requestId
|
|
286
204
|
);
|
|
287
205
|
return promise;
|
|
288
206
|
}
|
|
@@ -359,13 +277,27 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction<
|
|
|
359
277
|
return;
|
|
360
278
|
}
|
|
361
279
|
promiseMethods.resolve(data);
|
|
280
|
+
// Remove the entry so the map doesn't grow unboundedly across the
|
|
281
|
+
// lifetime of the player view.
|
|
282
|
+
promiseAndIdsMap.delete(requestId);
|
|
362
283
|
};
|
|
363
284
|
|
|
364
285
|
useEffect(() => {
|
|
365
286
|
return () => {
|
|
366
287
|
useHMSStore.getState().resetPlaybackSlice();
|
|
367
288
|
useHMSHLSPlayerStatsStore.getState().reset();
|
|
289
|
+
// Reject any in-flight command promises that didn't get a response
|
|
290
|
+
// before unmount. Under bridgeless mode the native side may not be
|
|
291
|
+
// able to deliver `onDataReturned` events back if the React tag is
|
|
292
|
+
// gone — left unrejected, those promises would hang forever.
|
|
293
|
+
promiseAndIdsMap.forEach(({ reject }) => {
|
|
294
|
+
reject(
|
|
295
|
+
new Error('HMSHLSPlayer unmounted before command response arrived')
|
|
296
|
+
);
|
|
297
|
+
});
|
|
298
|
+
promiseAndIdsMap.clear();
|
|
368
299
|
};
|
|
300
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
369
301
|
}, []);
|
|
370
302
|
|
|
371
303
|
return (
|
|
@@ -377,12 +309,14 @@ const _HMSHLSPlayer: React.ForwardRefRenderFunction<
|
|
|
377
309
|
style={styles.player}
|
|
378
310
|
enableStats={enableStats}
|
|
379
311
|
enableControls={enableControls}
|
|
380
|
-
onHmsHlsPlaybackEvent={handleHLSPlaybackEvent}
|
|
381
|
-
onHmsHlsStatsEvent={handleHLSStatsEvent}
|
|
312
|
+
onHmsHlsPlaybackEvent={handleHLSPlaybackEvent as any}
|
|
313
|
+
onHmsHlsStatsEvent={handleHLSStatsEvent as any}
|
|
382
314
|
onHlsPlayerCuesEvent={
|
|
383
|
-
Platform.OS === 'android'
|
|
315
|
+
Platform.OS === 'android'
|
|
316
|
+
? (handleHLSPlayerCuesEvent as any)
|
|
317
|
+
: undefined
|
|
384
318
|
}
|
|
385
|
-
onDataReturned={handleRequestedDataReturned}
|
|
319
|
+
onDataReturned={handleRequestedDataReturned as any}
|
|
386
320
|
/>
|
|
387
321
|
</View>
|
|
388
322
|
</View>
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
NativeMethods,
|
|
7
|
-
} from 'react-native';
|
|
1
|
+
import type { ElementRef } from 'react';
|
|
2
|
+
import type { StyleProp, NativeSyntheticEvent, ViewStyle } from 'react-native';
|
|
3
|
+
import HMSHLSPlayerNativeComponent, {
|
|
4
|
+
Commands,
|
|
5
|
+
} from '../../specs/HMSHLSPlayerNativeComponent';
|
|
8
6
|
import type {
|
|
9
7
|
HMSHLSPlayerCuesEvent,
|
|
10
8
|
HMSHLSPlayerPlaybackEvent,
|
|
@@ -39,11 +37,8 @@ export type RCTHMSHLSPlayerProps = {
|
|
|
39
37
|
onHlsPlayerCuesEvent?: HlsSPlayerCuesEventHandler;
|
|
40
38
|
};
|
|
41
39
|
|
|
42
|
-
export const RCTHMSHLSPlayer =
|
|
43
|
-
requireNativeComponent<RCTHMSHLSPlayerProps>('HMSHLSPlayer');
|
|
40
|
+
export const RCTHMSHLSPlayer = HMSHLSPlayerNativeComponent;
|
|
44
41
|
|
|
45
|
-
export
|
|
46
|
-
Readonly<NativeMethods>;
|
|
42
|
+
export const RCTHMSHLSPlayerCommands = Commands;
|
|
47
43
|
|
|
48
|
-
export
|
|
49
|
-
UIManager.getViewManagerConfig('HMSHLSPlayer');
|
|
44
|
+
export type RCTHMSHLSPlayerRef = ElementRef<typeof RCTHMSHLSPlayer>;
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
const { HMSManager } = NativeModules;
|
|
4
|
-
|
|
5
|
-
if (HMSManager == null) {
|
|
6
|
-
console.error(
|
|
7
|
-
`[@100mslive/react-native-hms] react-native-hms module was not found. Make sure you're running your app on the native platform and your code is linked properly (cd ios && pod install && cd ..).
|
|
8
|
-
|
|
9
|
-
For installation instructions, please refer to https://www.100ms.live/docs/react-native/v2/how-to-guides/install-the-sdk/integration`
|
|
10
|
-
.split('\n')
|
|
11
|
-
.map((line) => line.trim())
|
|
12
|
-
.join('\n')
|
|
13
|
-
);
|
|
14
|
-
}
|
|
1
|
+
import HMSManager from '../specs/NativeHMSManager';
|
|
15
2
|
|
|
16
3
|
export type HMSManagerProps = any;
|
|
17
4
|
|