@npaw/forge-react-native-video 9.6.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/LICENSE ADDED
@@ -0,0 +1,10 @@
1
+ Copyright (C) NPAW - All Rights Reserved
2
+
3
+ This software is protected under international copyright law. All rights
4
+ reserved and protected by the copyright holders. This software is confidential
5
+ and only available to authorized individuals with the permission of the
6
+ copyright holders. If you obtained this software and do not have permission,
7
+ please contact the copyright holders and delete it.
8
+
9
+ Use of this software requires an active NPAW commercial agreement. See
10
+ https://npaw.com for licensing and support.
@@ -0,0 +1,48 @@
1
+ # Copyright (C) NPAW - All Rights Reserved
2
+ #
3
+ # This source code is protected under international copyright law. All rights
4
+ # reserved and protected by the copyright holders. This file is confidential and
5
+ # only available to authorized individuals with the permission of the copyright
6
+ # holders. If you encounter this file and do not have permission, please contact
7
+ # the copyright holders and delete this file.
8
+ #
9
+ #
10
+ # @author: Victor Soto <victor.soto@nicepeopleatwork.com>
11
+ # @description: CocoaPods spec for the @npaw/forge-react-native-video glue (Forge AVPlayerAdapter onto react-native-video's plugin API).
12
+
13
+ require "json"
14
+
15
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
16
+
17
+ Pod::Spec.new do |s|
18
+ s.name = "NPAWForgeReactNativeVideo"
19
+ s.version = package["version"]
20
+ s.summary = package["description"]
21
+ s.homepage = "https://npaw.com"
22
+ s.license = { :type => "Commercial", :text => "Copyright (C) NPAW - All Rights Reserved" }
23
+ s.authors = { "Victor Soto" => "victor.soto@nicepeopleatwork.com" }
24
+ s.platforms = { :ios => "13.0" }
25
+ s.source = { :path => "." }
26
+
27
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
28
+ s.swift_version = "5.9"
29
+ s.pod_target_xcconfig = {
30
+ "DEFINES_MODULE" => "YES",
31
+ }
32
+
33
+ s.dependency "NPAWForgeReactNative"
34
+ s.dependency "react-native-video"
35
+
36
+ # FORGE_APPLE_CONSUMPTION BEGIN (staged: ForgeApple ships inside the core pod)
37
+ s.pod_target_xcconfig = {
38
+ "DEFINES_MODULE" => "YES",
39
+ "OTHER_SWIFT_FLAGS" => "$(inherited) -DFORGE_RN_HYDRATED",
40
+ }
41
+ # FORGE_APPLE_CONSUMPTION END
42
+
43
+ if respond_to?(:install_modules_dependencies, true)
44
+ install_modules_dependencies(s)
45
+ else
46
+ s.dependency "React-Core"
47
+ end
48
+ end
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # @npaw/forge-react-native-video
2
+
3
+ `react-native-video` player adapter for NPAW Forge: automatic playback and QoS
4
+ reporting by attaching to the player instance `react-native-video` already
5
+ manages.
6
+
7
+ Use of this package requires an active NPAW commercial agreement. See
8
+ [LICENSE](./LICENSE).
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ npm install @npaw/forge-react-native @npaw/forge-react-native-video
14
+ ```
15
+
16
+ Requires `react-native-video` v6 and React Native 0.75+ with the New
17
+ Architecture enabled.
18
+
19
+ ### iOS
20
+
21
+ ```sh
22
+ cd ios && pod install
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ Register the adapter alongside your `Video` component; the adapter attaches to
28
+ the underlying player and reports playback to the Forge session created with
29
+ [`@npaw/forge-react-native`](https://www.npmjs.com/package/@npaw/forge-react-native).
30
+
31
+ ```js
32
+ import { NPAWForge } from '@npaw/forge-react-native';
33
+ import { attachForgeVideo } from '@npaw/forge-react-native-video';
34
+
35
+ const video = await attachForgeVideo(forge, { identifier: 'main' });
36
+ ```
37
+
38
+ ## Documentation
39
+
40
+ Integration guides and the API reference are published at
41
+ [npaw.com](https://npaw.com).
@@ -0,0 +1,98 @@
1
+ // Copyright (C) NPAW - All Rights Reserved
2
+ //
3
+ // This source code is protected under international copyright law. All rights
4
+ // reserved and protected by the copyright holders. This file is confidential and
5
+ // only available to authorized individuals with the permission of the copyright
6
+ // holders. If you encounter this file and do not have permission, please contact
7
+ // the copyright holders and delete this file.
8
+ //
9
+ //
10
+ // @author: Victor Soto <victor.soto@nicepeopleatwork.com>
11
+ // @description: Android library build for the @npaw/forge-react-native-video glue module (Forge Media3 adapter onto react-native-video's plugin API). Pure-Java module so it builds under any host-app Kotlin version.
12
+
13
+ def isNewArchitectureEnabled() {
14
+ return project.hasProperty('newArchEnabled') && project.newArchEnabled == 'true'
15
+ }
16
+
17
+ apply plugin: 'com.android.library'
18
+ if (isNewArchitectureEnabled()) {
19
+ apply plugin: 'com.facebook.react'
20
+ }
21
+
22
+ def safeExtGet(prop, fallback) {
23
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
24
+ }
25
+
26
+ def forgeCoreVersion = project.hasProperty('NpawForge_forgeCoreVersion')
27
+ ? project.property('NpawForge_forgeCoreVersion')
28
+ : (System.getenv('FORGE_CORE_VERSION') ?: '9.6.1')
29
+
30
+ def forgeAdapterVersion = project.hasProperty('NpawForge_forgeAdapterVersion')
31
+ ? project.property('NpawForge_forgeAdapterVersion')
32
+ : (System.getenv('FORGE_ADAPTER_VERSION') ?: '9.6.1')
33
+
34
+ android {
35
+ namespace 'com.npaw.forge.reactnative.video'
36
+ compileSdkVersion safeExtGet('compileSdkVersion', 35)
37
+
38
+ defaultConfig {
39
+ minSdkVersion safeExtGet('minSdkVersion', 23)
40
+ targetSdkVersion safeExtGet('targetSdkVersion', 34)
41
+ }
42
+
43
+ compileOptions {
44
+ sourceCompatibility JavaVersion.VERSION_17
45
+ targetCompatibility JavaVersion.VERSION_17
46
+ }
47
+
48
+ testOptions {
49
+ unitTests.returnDefaultValues = true
50
+ }
51
+ }
52
+
53
+ repositories {
54
+ mavenCentral()
55
+ google()
56
+ def localMavenRepo = System.getenv('FORGE_LOCAL_MAVEN_REPO')
57
+ if (localMavenRepo != null && !localMavenRepo.isEmpty()) {
58
+ maven { url uri(localMavenRepo) }
59
+ }
60
+ maven { url 'https://artifact.plugin.npaw.com/artifactory/plugins/android' }
61
+ }
62
+
63
+ // The core RN library project name comes from React Native autolinking's
64
+ // package-name sanitization; probe the known spellings so this module works
65
+ // wherever the app's settings.gradle placed it.
66
+ def forgeCoreRnProject = [
67
+ ':npaw_forge-react-native',
68
+ ':forge-react-native',
69
+ ':npaw-forge-react-native',
70
+ ].collect { findProject(it) }.find { it != null }
71
+
72
+ def reactNativeVideoProject = findProject(':react-native-video')
73
+
74
+ // The Forge media3 adapter declares its player SDK compileOnly (runtime
75
+ // player detection), and react-native-video provides media3 at the app level;
76
+ // this module needs the same media3 surface on its own compile classpath.
77
+ def media3Version = safeExtGet('media3Version', '1.8.0')
78
+
79
+ dependencies {
80
+ implementation 'com.facebook.react:react-native:+'
81
+ // compileOnly + runtimeOnly split — see the core module's build.gradle:
82
+ // keeps the Kotlin-2.3 Forge graph off host-app Kotlin compile classpaths.
83
+ compileOnly "com.npaw.forge:forge-android-core:${forgeCoreVersion}"
84
+ runtimeOnly "com.npaw.forge:forge-android-core:${forgeCoreVersion}"
85
+ compileOnly "com.npaw.forge:forge-adapter-media3:${forgeAdapterVersion}"
86
+ runtimeOnly "com.npaw.forge:forge-adapter-media3:${forgeAdapterVersion}"
87
+ compileOnly "androidx.media3:media3-common:${media3Version}"
88
+ compileOnly "androidx.media3:media3-datasource:${media3Version}"
89
+ compileOnly "androidx.media3:media3-exoplayer:${media3Version}"
90
+ if (forgeCoreRnProject != null) {
91
+ implementation forgeCoreRnProject
92
+ }
93
+ if (reactNativeVideoProject != null) {
94
+ compileOnly reactNativeVideoProject
95
+ }
96
+
97
+ testImplementation 'junit:junit:4.13.2'
98
+ }
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!--
3
+ Copyright (C) NPAW - All Rights Reserved
4
+
5
+ This source code is protected under international copyright law. All rights
6
+ reserved and protected by the copyright holders. This file is confidential and
7
+ only available to authorized individuals with the permission of the copyright
8
+ holders. If you encounter this file and do not have permission, please contact
9
+ the copyright holders and delete this file.
10
+
11
+ @author: Victor Soto <victor.soto@nicepeopleatwork.com>
12
+ @description: Manifest stub for the @npaw/forge-react-native-video Android library module.
13
+ -->
14
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" />
@@ -0,0 +1,341 @@
1
+ /**
2
+ * Copyright (C) NPAW - All Rights Reserved
3
+ *
4
+ * This source code is protected under international copyright law. All rights
5
+ * reserved and protected by the copyright holders.
6
+ * This file is confidential and only available to authorized individuals with the
7
+ * permission of the copyright holders. If you encounter this file and do not have
8
+ * permission, please contact the copyright holders and delete this file.
9
+ *
10
+ *
11
+ * @author: Victor Soto <victor.soto@nicepeopleatwork.com>
12
+ * @description: react-native-video glue TurboModule for Android. Implements RNVExoplayerPlugin, smuggles the X-NPAW-Forge header token into the MediaItem tag via overrideMediaItemBuilder, caches player facts on the main thread, and delegates policy to RNVideoAttachCoordinator to bind Forge's Media3PlayerAdapter.
13
+ */
14
+
15
+ package com.npaw.forge.reactnative.video;
16
+
17
+ import androidx.annotation.Nullable;
18
+ import android.os.Handler;
19
+ import android.os.Looper;
20
+ import androidx.media3.common.MediaItem;
21
+ import androidx.media3.datasource.DataSource;
22
+ import androidx.media3.exoplayer.ExoPlayer;
23
+ import androidx.media3.exoplayer.drm.DrmSessionManager;
24
+ import androidx.media3.exoplayer.source.MediaSource;
25
+ import com.brentvatne.common.api.Source;
26
+ import com.brentvatne.exoplayer.DRMManagerSpec;
27
+ import com.brentvatne.exoplayer.RNVExoplayerPlugin;
28
+ import com.brentvatne.react.ReactNativeVideoManager;
29
+ import com.facebook.react.bridge.Arguments;
30
+ import com.facebook.react.bridge.Promise;
31
+ import com.facebook.react.bridge.ReactApplicationContext;
32
+ import com.facebook.react.bridge.ReadableMap;
33
+ import com.facebook.react.bridge.UiThreadUtil;
34
+ import com.facebook.react.bridge.WritableMap;
35
+ import com.npaw.forge.android.NPAWForge;
36
+ import com.npaw.forge.android.adapters.media3.Media3PlayerAdapter;
37
+ import com.npaw.forge.android.video.VideoAdapter;
38
+ import com.npaw.forge.reactnative.ForgeInstanceRegistry;
39
+ import java.util.HashMap;
40
+ import java.util.Locale;
41
+ import java.util.Map;
42
+ import java.util.concurrent.ConcurrentHashMap;
43
+
44
+ public class NPAWForgeVideoModule extends NativeNPAWForgeVideoSpec
45
+ implements RNVExoplayerPlugin {
46
+
47
+ public static final String NAME = "NPAWForgeVideoRN";
48
+ /** Header customers set on source.requestHeaders for multi-player matching. */
49
+ public static final String TOKEN_HEADER = "x-npaw-forge";
50
+ private static final String TAG_PREFIX = "npaw-forge:";
51
+ private static final String E_UNKNOWN_INSTANCE = "E_FORGE_UNKNOWN_INSTANCE";
52
+
53
+ private static final class PlayerFacts {
54
+ @Nullable volatile String token;
55
+ @Nullable volatile String uri;
56
+ }
57
+
58
+ private final ConcurrentHashMap<String, PlayerFacts> facts = new ConcurrentHashMap<>();
59
+ private final ConcurrentHashMap<String, ExoPlayer> playersById = new ConcurrentHashMap<>();
60
+ private final ConcurrentHashMap<String, Media3PlayerAdapter> adaptersByPlayerId =
61
+ new ConcurrentHashMap<>();
62
+ private final Handler mainHandler = new Handler(Looper.getMainLooper());
63
+
64
+ private final RNVideoAttachCoordinator<ExoPlayer> coordinator =
65
+ new RNVideoAttachCoordinator<>(
66
+ new RNVideoAttachCoordinator.PlayerIntrospection() {
67
+ @Nullable
68
+ @Override
69
+ public String currentToken(String playerId) {
70
+ PlayerFacts f = facts.get(playerId);
71
+ return f == null ? null : f.token;
72
+ }
73
+
74
+ @Nullable
75
+ @Override
76
+ public String currentUri(String playerId) {
77
+ PlayerFacts f = facts.get(playerId);
78
+ return f == null ? null : f.uri;
79
+ }
80
+ },
81
+ new RNVideoAttachCoordinator.Binder<ExoPlayer>() {
82
+ @Override
83
+ public void bind(String instanceId, String identifier, String playerId, ExoPlayer player) {
84
+ bindOnMain(instanceId, identifier, playerId, player);
85
+ }
86
+
87
+ @Override
88
+ public void unbind(
89
+ String instanceId, String identifier, String playerId, boolean fireStop) {
90
+ unbindOnMain(instanceId, identifier, playerId, fireStop);
91
+ }
92
+ });
93
+
94
+ public NPAWForgeVideoModule(ReactApplicationContext reactContext) {
95
+ super(reactContext);
96
+ ReactNativeVideoManager.Companion.getInstance().registerPlugin(this);
97
+ }
98
+
99
+ @Override
100
+ public String getName() {
101
+ return NAME;
102
+ }
103
+
104
+ // ---- spec surface ----
105
+
106
+ @Override
107
+ public void attach(String instanceId, String identifier, @Nullable ReadableMap options, Promise promise) {
108
+ NPAWForge forge = ForgeInstanceRegistry.resolve(instanceId);
109
+ if (forge == null) {
110
+ promise.reject(E_UNKNOWN_INSTANCE, "No NPAWForge instance '" + instanceId + "'");
111
+ return;
112
+ }
113
+ ensureVideo(forge, identifier);
114
+
115
+ Map<String, Object> map = options == null ? new HashMap<>() : options.toHashMap();
116
+ String headerToken = stringOrNull(map.get("headerToken"));
117
+ String sourceUri = stringOrNull(map.get("sourceUri"));
118
+ String policy = stringOrNull(map.get("policy"));
119
+ if (policy == null) {
120
+ policy = (headerToken != null || sourceUri != null) ? "match" : "auto";
121
+ }
122
+ boolean stopOnPlayerRemoved =
123
+ !(map.get("stopOnPlayerRemoved") instanceof Boolean)
124
+ || (Boolean) map.get("stopOnPlayerRemoved");
125
+
126
+ RNVideoAttachCoordinator.AttachOutcome outcome =
127
+ coordinator.attach(
128
+ new RNVideoAttachCoordinator.AttachRequest(
129
+ instanceId, identifier, policy, headerToken, sourceUri, stopOnPlayerRemoved));
130
+ scheduleFactRefreshes();
131
+ promise.resolve(attachResult(outcome));
132
+ }
133
+
134
+ @Override
135
+ public void detach(String instanceId, String identifier, Promise promise) {
136
+ boolean removed = coordinator.detach(instanceId, identifier, true);
137
+ WritableMap result = Arguments.createMap();
138
+ result.putString("code", removed ? "accepted" : "ignored_invalid_state");
139
+ result.putBoolean("isAccepted", removed);
140
+ result.putString("attachment", "pending");
141
+ promise.resolve(result);
142
+ }
143
+
144
+ @Override
145
+ public void invalidate() {
146
+ ReactNativeVideoManager.Companion.getInstance().unregisterPlugin(this);
147
+ coordinator.clear();
148
+ facts.clear();
149
+ playersById.clear();
150
+ adaptersByPlayerId.clear();
151
+ super.invalidate();
152
+ }
153
+
154
+ // ---- RNVExoplayerPlugin ----
155
+
156
+ @Override
157
+ public void onInstanceCreated(String id, ExoPlayer player) {
158
+ facts.putIfAbsent(id, new PlayerFacts());
159
+ playersById.put(id, player);
160
+ UiThreadUtil.runOnUiThread(
161
+ () -> {
162
+ refreshFacts(id, player);
163
+ coordinator.playerCreated(id, player);
164
+ });
165
+ scheduleFactRefreshes();
166
+ }
167
+
168
+ @Override
169
+ public void onInstanceRemoved(String id, ExoPlayer player) {
170
+ playersById.remove(id);
171
+ facts.remove(id);
172
+ coordinator.playerRemoved(id);
173
+ }
174
+
175
+ // ---- RNVExoplayerPlugin optional hooks ----
176
+
177
+ @Nullable
178
+ @Override
179
+ public DRMManagerSpec getDRMManager() {
180
+ return null;
181
+ }
182
+
183
+ @Nullable
184
+ @Override
185
+ public DrmSessionManager overrideDrmSessionManager(Source source, DrmSessionManager drmSessionManager) {
186
+ return null;
187
+ }
188
+
189
+ @Nullable
190
+ @Override
191
+ public DataSource.Factory overrideMediaDataSourceFactory(
192
+ Source source, DataSource.Factory mediaDataSourceFactory) {
193
+ return null;
194
+ }
195
+
196
+ @Nullable
197
+ @Override
198
+ public MediaSource.Factory overrideMediaSourceFactory(
199
+ Source source, MediaSource.Factory mediaSourceFactory, DataSource.Factory mediaDataSourceFactory) {
200
+ return null;
201
+ }
202
+
203
+ @Nullable
204
+ @Override
205
+ public MediaItem.Builder overrideMediaItemBuilder(Source source, MediaItem.Builder mediaItemBuilder) {
206
+ String token = tokenFromHeaders(source.getHeaders());
207
+ if (token == null) {
208
+ return null;
209
+ }
210
+ // The tag rides the MediaItem so introspection can read it back from
211
+ // player.currentMediaItem on the main thread - deterministic multi-player
212
+ // correlation without joining override->create call ordering.
213
+ return mediaItemBuilder.setTag(TAG_PREFIX + token);
214
+ }
215
+
216
+ @Override
217
+ public boolean shouldDisableCache(Source source) {
218
+ return false;
219
+ }
220
+
221
+ @Override
222
+ public void onInstanceCreated(String id, Object player) {
223
+ if (player instanceof ExoPlayer) {
224
+ onInstanceCreated(id, (ExoPlayer) player);
225
+ }
226
+ }
227
+
228
+ @Override
229
+ public void onInstanceRemoved(String id, Object player) {
230
+ if (player instanceof ExoPlayer) {
231
+ onInstanceRemoved(id, (ExoPlayer) player);
232
+ }
233
+ }
234
+
235
+ // ---- internals ----
236
+
237
+ private void ensureVideo(NPAWForge forge, String identifier) {
238
+ if (forge.getVideoAdapter(identifier) == null) {
239
+ forge.videoBuilder().setIdentifier(identifier).build();
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Sources settle after player creation; instead of a media3 Player.Listener
245
+ * (whose default-method desugaring is fragile across media3 versions), a
246
+ * few delayed main-thread refreshes converge token/URI facts and re-run the
247
+ * pending-match evaluation.
248
+ */
249
+ private void scheduleFactRefreshes() {
250
+ for (long delayMs : new long[] {0L, 500L, 1500L, 3000L}) {
251
+ mainHandler.postDelayed(
252
+ () -> {
253
+ for (Map.Entry<String, ExoPlayer> entry : playersById.entrySet()) {
254
+ refreshFacts(entry.getKey(), entry.getValue());
255
+ }
256
+ coordinator.playerSourceSettled();
257
+ },
258
+ delayMs);
259
+ }
260
+ }
261
+
262
+ /** Main thread only. */
263
+ private void refreshFacts(String playerId, ExoPlayer player) {
264
+ PlayerFacts f = facts.computeIfAbsent(playerId, key -> new PlayerFacts());
265
+ MediaItem item = player.getCurrentMediaItem();
266
+ if (item != null && item.localConfiguration != null) {
267
+ Object tag = item.localConfiguration.tag;
268
+ f.token =
269
+ tag instanceof String && ((String) tag).startsWith(TAG_PREFIX)
270
+ ? ((String) tag).substring(TAG_PREFIX.length())
271
+ : null;
272
+ f.uri = item.localConfiguration.uri.toString();
273
+ }
274
+ }
275
+
276
+ private void bindOnMain(String instanceId, String identifier, String playerId, ExoPlayer player) {
277
+ UiThreadUtil.runOnUiThread(
278
+ () -> {
279
+ NPAWForge forge = ForgeInstanceRegistry.resolve(instanceId);
280
+ if (forge == null || player == null) {
281
+ return;
282
+ }
283
+ ensureVideo(forge, identifier);
284
+ VideoAdapter video = forge.getVideoAdapter(identifier);
285
+ if (video == null) {
286
+ return;
287
+ }
288
+ Media3PlayerAdapter adapter = new Media3PlayerAdapter(player);
289
+ video.setPlayerAdapter(adapter);
290
+ adaptersByPlayerId.put(playerId, adapter);
291
+ });
292
+ }
293
+
294
+ private void unbindOnMain(String instanceId, String identifier, String playerId, boolean fireStop) {
295
+ UiThreadUtil.runOnUiThread(
296
+ () -> {
297
+ adaptersByPlayerId.remove(playerId);
298
+ VideoAdapter video = ForgeInstanceRegistry.resolveVideoAdapter(instanceId, identifier);
299
+ if (video == null) {
300
+ return;
301
+ }
302
+ if (fireStop) {
303
+ video.fireStop();
304
+ }
305
+ video.setPlayerAdapter(null);
306
+ });
307
+ }
308
+
309
+ @Nullable
310
+ private static String tokenFromHeaders(@Nullable Map<String, String> headers) {
311
+ if (headers == null) {
312
+ return null;
313
+ }
314
+ for (Map.Entry<String, String> entry : headers.entrySet()) {
315
+ if (entry.getKey() != null
316
+ && TOKEN_HEADER.equals(entry.getKey().toLowerCase(Locale.ROOT))) {
317
+ return entry.getValue();
318
+ }
319
+ }
320
+ return null;
321
+ }
322
+
323
+ @Nullable
324
+ private static String stringOrNull(@Nullable Object value) {
325
+ if (value instanceof String && !((String) value).isEmpty()) {
326
+ return (String) value;
327
+ }
328
+ return null;
329
+ }
330
+
331
+ private static WritableMap attachResult(RNVideoAttachCoordinator.AttachOutcome outcome) {
332
+ WritableMap result = Arguments.createMap();
333
+ result.putString("code", outcome.code);
334
+ result.putBoolean("isAccepted", outcome.accepted);
335
+ result.putString("attachment", outcome.attachment);
336
+ if (outcome.reason != null) {
337
+ result.putString("reason", outcome.reason);
338
+ }
339
+ return result;
340
+ }
341
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Copyright (C) NPAW - All Rights Reserved
3
+ *
4
+ * This source code is protected under international copyright law. All rights
5
+ * reserved and protected by the copyright holders.
6
+ * This file is confidential and only available to authorized individuals with the
7
+ * permission of the copyright holders. If you encounter this file and do not have
8
+ * permission, please contact the copyright holders and delete this file.
9
+ *
10
+ *
11
+ * @author: Victor Soto <victor.soto@nicepeopleatwork.com>
12
+ * @description: React package registering the NPAWForgeVideo TurboModule for autolinking.
13
+ */
14
+
15
+ package com.npaw.forge.reactnative.video;
16
+
17
+ import com.facebook.react.TurboReactPackage;
18
+ import com.facebook.react.bridge.NativeModule;
19
+ import com.facebook.react.bridge.ReactApplicationContext;
20
+ import com.facebook.react.module.model.ReactModuleInfo;
21
+ import com.facebook.react.module.model.ReactModuleInfoProvider;
22
+ import java.util.HashMap;
23
+ import java.util.Map;
24
+ import androidx.annotation.Nullable;
25
+
26
+ public class NPAWForgeVideoPackage extends TurboReactPackage {
27
+
28
+ @Nullable
29
+ @Override
30
+ public NativeModule getModule(String name, ReactApplicationContext reactContext) {
31
+ if (NPAWForgeVideoModule.NAME.equals(name)) {
32
+ return new NPAWForgeVideoModule(reactContext);
33
+ }
34
+ return null;
35
+ }
36
+
37
+ @Override
38
+ public ReactModuleInfoProvider getReactModuleInfoProvider() {
39
+ return () -> {
40
+ Map<String, ReactModuleInfo> modules = new HashMap<>();
41
+ modules.put(
42
+ NPAWForgeVideoModule.NAME,
43
+ new ReactModuleInfo(
44
+ NPAWForgeVideoModule.NAME,
45
+ NPAWForgeVideoModule.class.getName(),
46
+ false,
47
+ false,
48
+ false,
49
+ true));
50
+ return modules;
51
+ };
52
+ }
53
+ }