@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 +10 -0
- package/NPAWForgeReactNativeVideo.podspec +48 -0
- package/README.md +41 -0
- package/android/build.gradle +98 -0
- package/android/src/main/AndroidManifest.xml +14 -0
- package/android/src/main/java/com/npaw/forge/reactnative/video/NPAWForgeVideoModule.java +341 -0
- package/android/src/main/java/com/npaw/forge/reactnative/video/NPAWForgeVideoPackage.java +53 -0
- package/android/src/main/java/com/npaw/forge/reactnative/video/RNVideoAttachCoordinator.java +0 -0
- package/android/src/test/java/com/npaw/forge/reactnative/video/RNVideoAttachCoordinatorTest.java +218 -0
- package/ios/ForgeRNVPlayerPlugin.swift +80 -0
- package/ios/ForgeVideoModuleImpl.swift +347 -0
- package/ios/NPAWForgeVideoTurboModule.mm +89 -0
- package/package.json +34 -0
- package/src/index.ts +79 -0
- package/src/specs/NativeNPAWForgeVideo.ts +30 -0
|
@@ -0,0 +1,89 @@
|
|
|
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: ObjC++ TurboModule shell for the NPAWForgeVideo module; forwards to the Swift ForgeVideoModuleImpl.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
#import <React/RCTBridgeModule.h>
|
|
16
|
+
#import <React/RCTInvalidating.h>
|
|
17
|
+
|
|
18
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
19
|
+
#import <NPAWForgeVideoSpec/NPAWForgeVideoSpec.h>
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
#if __has_include("NPAWForgeReactNativeVideo-Swift.h")
|
|
23
|
+
#import "NPAWForgeReactNativeVideo-Swift.h"
|
|
24
|
+
#else
|
|
25
|
+
#import <NPAWForgeReactNativeVideo/NPAWForgeReactNativeVideo-Swift.h>
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
29
|
+
@interface NPAWForgeVideoReactNative : NSObject <NativeNPAWForgeVideoSpec, RCTInvalidating>
|
|
30
|
+
@end
|
|
31
|
+
#else
|
|
32
|
+
@interface NPAWForgeVideoReactNative : NSObject <RCTBridgeModule, RCTInvalidating>
|
|
33
|
+
@end
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
@implementation NPAWForgeVideoReactNative
|
|
37
|
+
|
|
38
|
+
RCT_EXPORT_MODULE(NPAWForgeVideoRN)
|
|
39
|
+
|
|
40
|
+
+ (BOOL)requiresMainQueueSetup
|
|
41
|
+
{
|
|
42
|
+
return NO;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Swift closure typealiases are not exported to the generated header; the
|
|
46
|
+
// Swift methods surface their reject parameters as plain ObjC blocks.
|
|
47
|
+
typedef void (^ForgeVideoRejectBlockObjC)(NSString *code, NSString *message);
|
|
48
|
+
|
|
49
|
+
static ForgeVideoRejectBlockObjC ForgeVideoMakeReject(RCTPromiseRejectBlock reject)
|
|
50
|
+
{
|
|
51
|
+
return ^(NSString *code, NSString *message) {
|
|
52
|
+
reject(code, message, nil);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
RCT_EXPORT_METHOD(attach : (NSString *)instanceId identifier : (NSString *)identifier options : (
|
|
57
|
+
NSDictionary *)options resolve : (RCTPromiseResolveBlock)resolve reject : (
|
|
58
|
+
RCTPromiseRejectBlock)reject)
|
|
59
|
+
{
|
|
60
|
+
[ForgeVideoModuleImpl.shared attach:instanceId
|
|
61
|
+
identifier:identifier
|
|
62
|
+
options:options
|
|
63
|
+
resolve:resolve
|
|
64
|
+
reject:ForgeVideoMakeReject(reject)];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
RCT_EXPORT_METHOD(detach : (NSString *)instanceId identifier : (NSString *)identifier resolve : (
|
|
68
|
+
RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject)
|
|
69
|
+
{
|
|
70
|
+
[ForgeVideoModuleImpl.shared detach:instanceId
|
|
71
|
+
identifier:identifier
|
|
72
|
+
resolve:resolve
|
|
73
|
+
reject:ForgeVideoMakeReject(reject)];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
- (void)invalidate
|
|
77
|
+
{
|
|
78
|
+
[ForgeVideoModuleImpl.shared invalidate];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
82
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
83
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
84
|
+
{
|
|
85
|
+
return std::make_shared<facebook::react::NativeNPAWForgeVideoSpecJSI>(params);
|
|
86
|
+
}
|
|
87
|
+
#endif
|
|
88
|
+
|
|
89
|
+
@end
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@npaw/forge-react-native-video",
|
|
3
|
+
"version": "9.6.1",
|
|
4
|
+
"description": "react-native-video adapter glue for NPAW Forge: attaches the native Media3/AVPlayer Forge adapters to react-native-video's internal players via its native plugin API.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"author": "Victor Soto <victor.soto@nicepeopleatwork.com>",
|
|
7
|
+
"main": "src/index.ts",
|
|
8
|
+
"types": "src/index.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"LICENSE",
|
|
11
|
+
"NPAWForgeReactNativeVideo.podspec",
|
|
12
|
+
"README.md",
|
|
13
|
+
"android",
|
|
14
|
+
"ios",
|
|
15
|
+
"src"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"typecheck": "tsc --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@npaw/forge-react-native": "^9.6.1",
|
|
22
|
+
"react": "*",
|
|
23
|
+
"react-native": "*",
|
|
24
|
+
"react-native-video": ">=6.11.0 <7"
|
|
25
|
+
},
|
|
26
|
+
"codegenConfig": {
|
|
27
|
+
"name": "NPAWForgeVideoSpec",
|
|
28
|
+
"type": "modules",
|
|
29
|
+
"jsSrcsDir": "src/specs",
|
|
30
|
+
"android": {
|
|
31
|
+
"javaPackageName": "com.npaw.forge.reactnative.video"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
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: Public API for @npaw/forge-react-native-video - binds Forge's native player adapters to react-native-video with auto/token/uri correlation policies.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import NativeNPAWForgeVideo from './specs/NativeNPAWForgeVideo';
|
|
16
|
+
|
|
17
|
+
type ForgeLike = string | { instanceId: string };
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The request header used for deterministic multi-player matching. Set the
|
|
21
|
+
* same opaque value on the <Video> source and in attach options:
|
|
22
|
+
*
|
|
23
|
+
* <Video source={{uri, headers: {[FORGE_VIDEO_TOKEN_HEADER]: 'main'}}} />
|
|
24
|
+
* attachReactNativeVideo(forge, {headerToken: 'main'});
|
|
25
|
+
*
|
|
26
|
+
* Note: the header travels to the CDN with every media request; use a short
|
|
27
|
+
* opaque value.
|
|
28
|
+
*/
|
|
29
|
+
export const FORGE_VIDEO_TOKEN_HEADER = 'X-NPAW-Forge';
|
|
30
|
+
|
|
31
|
+
export type AttachPolicy = 'auto' | 'match';
|
|
32
|
+
|
|
33
|
+
export type AttachOptions = {
|
|
34
|
+
/** Forge video identifier; defaults to the native 'default'. */
|
|
35
|
+
identifier?: string;
|
|
36
|
+
/** 'auto' binds the single live unbound player; 'match' needs token/uri. */
|
|
37
|
+
policy?: AttachPolicy;
|
|
38
|
+
/** Matches the player whose source carries this X-NPAW-Forge header value. */
|
|
39
|
+
headerToken?: string;
|
|
40
|
+
/** Exact source-URI fallback matcher (breaks on duplicate URIs). */
|
|
41
|
+
sourceUri?: string;
|
|
42
|
+
/** Fire Stop + detach when react-native-video removes the player. Default true. */
|
|
43
|
+
stopOnPlayerRemoved?: boolean;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type AttachResult = {
|
|
47
|
+
code: string;
|
|
48
|
+
isAccepted: boolean;
|
|
49
|
+
reason?: string;
|
|
50
|
+
attachment: 'bound' | 'pending';
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function resolveInstanceId(forge: ForgeLike): string {
|
|
54
|
+
return typeof forge === 'string' ? forge : forge.instanceId;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Binds Forge's native player adapter (Media3 on Android, AVPlayer on iOS)
|
|
59
|
+
* to a react-native-video player. With no options: single-player auto-attach
|
|
60
|
+
* (ambiguity fails closed as unsupported_capability/ambiguous_auto_attach).
|
|
61
|
+
*/
|
|
62
|
+
export function attachReactNativeVideo(
|
|
63
|
+
forge: ForgeLike,
|
|
64
|
+
options: AttachOptions = {}
|
|
65
|
+
): Promise<AttachResult> {
|
|
66
|
+
const { identifier = 'default', ...rest } = options;
|
|
67
|
+
return NativeNPAWForgeVideo.attach(
|
|
68
|
+
resolveInstanceId(forge),
|
|
69
|
+
identifier,
|
|
70
|
+
rest
|
|
71
|
+
) as Promise<AttachResult>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function detachReactNativeVideo(
|
|
75
|
+
forge: ForgeLike,
|
|
76
|
+
identifier: string = 'default'
|
|
77
|
+
): Promise<AttachResult> {
|
|
78
|
+
return NativeNPAWForgeVideo.detach(resolveInstanceId(forge), identifier) as Promise<AttachResult>;
|
|
79
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
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: TurboModule codegen spec for the react-native-video Forge adapter glue (attach/detach with correlation policy options).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import type { TurboModule } from 'react-native';
|
|
16
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
17
|
+
import type { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';
|
|
18
|
+
|
|
19
|
+
export interface Spec extends TurboModule {
|
|
20
|
+
/**
|
|
21
|
+
* Requests a native adapter bind for (instanceId, identifier). Options:
|
|
22
|
+
* policy 'auto' | 'match', headerToken, sourceUri, stopOnPlayerRemoved.
|
|
23
|
+
* Resolves a ForgeOutcome DTO plus { attachment: 'bound' | 'pending' }.
|
|
24
|
+
*/
|
|
25
|
+
attach(instanceId: string, identifier: string, options: UnsafeObject): Promise<UnsafeObject>;
|
|
26
|
+
/** Unbinds the identifier's adapter from its player (fires Stop first). */
|
|
27
|
+
detach(instanceId: string, identifier: string): Promise<UnsafeObject>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default TurboModuleRegistry.getEnforcing<Spec>('NPAWForgeVideoRN');
|