react-native-unified-player 0.2.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 +20 -0
- package/README.md +95 -0
- package/UnifiedPlayer.podspec +32 -0
- package/android/build.gradle +81 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +7 -0
- package/android/src/main/AndroidManifestNew.xml +4 -0
- package/android/src/main/java/com/unifiedplayer/UnifiedPlayerEventEmitter.kt +62 -0
- package/android/src/main/java/com/unifiedplayer/UnifiedPlayerModule.kt +93 -0
- package/android/src/main/java/com/unifiedplayer/UnifiedPlayerPackage.kt +20 -0
- package/android/src/main/java/com/unifiedplayer/UnifiedPlayerView.kt +265 -0
- package/android/src/main/java/com/unifiedplayer/UnifiedPlayerViewManager.kt +33 -0
- package/ios/UnifiedPlayerModule.h +5 -0
- package/ios/UnifiedPlayerViewManager.m +670 -0
- package/lib/module/index.js +97 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/index.d.ts +46 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +154 -0
- package/src/index.tsx +135 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { requireNativeComponent, UIManager, Platform, NativeModules, NativeEventEmitter } from 'react-native';
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
const LINKING_ERROR = `The package 'react-native-unified-player' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
|
|
6
|
+
ios: "- You have run 'pod install'\n",
|
|
7
|
+
default: ''
|
|
8
|
+
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Props for the UnifiedPlayerView component
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Name of the native component
|
|
15
|
+
const ComponentName = 'UnifiedPlayerView';
|
|
16
|
+
|
|
17
|
+
// Native component import
|
|
18
|
+
const NativeUnifiedPlayerView = UIManager.getViewManagerConfig(ComponentName) != null ? requireNativeComponent(ComponentName) : () => {
|
|
19
|
+
throw new Error(LINKING_ERROR);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Native module for additional control methods
|
|
23
|
+
const UnifiedPlayerModule = NativeModules.UnifiedPlayerModule;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* UnifiedPlayerView component for video playback
|
|
27
|
+
*/
|
|
28
|
+
export const UnifiedPlayerView = props => {
|
|
29
|
+
return /*#__PURE__*/_jsx(NativeUnifiedPlayerView, {
|
|
30
|
+
...props
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* API methods for controlling playback
|
|
36
|
+
*/
|
|
37
|
+
export const UnifiedPlayer = {
|
|
38
|
+
// Play the video
|
|
39
|
+
play: viewTag => {
|
|
40
|
+
if (UnifiedPlayerModule?.play) {
|
|
41
|
+
UnifiedPlayerModule.play(viewTag);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
// Pause the video
|
|
45
|
+
pause: viewTag => {
|
|
46
|
+
if (UnifiedPlayerModule?.pause) {
|
|
47
|
+
UnifiedPlayerModule.pause(viewTag);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
// Seek to a specific time
|
|
51
|
+
seekTo: (viewTag, time) => {
|
|
52
|
+
if (UnifiedPlayerModule?.seekTo) {
|
|
53
|
+
UnifiedPlayerModule.seekTo(viewTag, time);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
// Get the current playback time
|
|
57
|
+
getCurrentTime: viewTag => {
|
|
58
|
+
if (UnifiedPlayerModule?.getCurrentTime) {
|
|
59
|
+
return UnifiedPlayerModule.getCurrentTime(viewTag);
|
|
60
|
+
}
|
|
61
|
+
return Promise.resolve(0);
|
|
62
|
+
},
|
|
63
|
+
// Get the duration of the video
|
|
64
|
+
getDuration: viewTag => {
|
|
65
|
+
if (UnifiedPlayerModule?.getDuration) {
|
|
66
|
+
return UnifiedPlayerModule.getDuration(viewTag);
|
|
67
|
+
}
|
|
68
|
+
return Promise.resolve(0);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Events emitter for native events
|
|
73
|
+
let eventEmitter = null;
|
|
74
|
+
if (UnifiedPlayerModule) {
|
|
75
|
+
eventEmitter = new NativeEventEmitter(UnifiedPlayerModule);
|
|
76
|
+
}
|
|
77
|
+
export const UnifiedPlayerEvents = {
|
|
78
|
+
addListener: (eventType, listener) => {
|
|
79
|
+
if (eventEmitter) {
|
|
80
|
+
return eventEmitter.addListener(eventType, listener);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
remove: () => {}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// Event names
|
|
89
|
+
export const UnifiedPlayerEventTypes = {
|
|
90
|
+
READY: 'onReadyToPlay',
|
|
91
|
+
ERROR: 'onError',
|
|
92
|
+
PROGRESS: 'onProgress',
|
|
93
|
+
COMPLETE: 'onPlaybackComplete',
|
|
94
|
+
STALLED: 'onPlaybackStalled',
|
|
95
|
+
RESUMED: 'onPlaybackResumed'
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["requireNativeComponent","UIManager","Platform","NativeModules","NativeEventEmitter","jsx","_jsx","LINKING_ERROR","select","ios","default","ComponentName","NativeUnifiedPlayerView","getViewManagerConfig","Error","UnifiedPlayerModule","UnifiedPlayerView","props","UnifiedPlayer","play","viewTag","pause","seekTo","time","getCurrentTime","Promise","resolve","getDuration","eventEmitter","UnifiedPlayerEvents","addListener","eventType","listener","remove","UnifiedPlayerEventTypes","READY","ERROR","PROGRESS","COMPLETE","STALLED","RESUMED"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SACEA,sBAAsB,EACtBC,SAAS,EACTC,QAAQ,EAERC,aAAa,EACbC,kBAAkB,QACb,cAAc;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAEtB,MAAMC,aAAa,GACjB,sFAAsF,GACtFL,QAAQ,CAACM,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;;AAEjC;AACA;AACA;;AA8BA;AACA,MAAMC,aAAa,GAAG,mBAAmB;;AAEzC;AACA,MAAMC,uBAAuB,GAC3BX,SAAS,CAACY,oBAAoB,CAACF,aAAa,CAAC,IAAI,IAAI,GACjDX,sBAAsB,CAAqBW,aAAa,CAAC,GACzD,MAAM;EACJ,MAAM,IAAIG,KAAK,CAACP,aAAa,CAAC;AAChC,CAAC;;AAEP;AACA,MAAMQ,mBAAmB,GAAGZ,aAAa,CAACY,mBAAmB;;AAE7D;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,GAAIC,KAAyB,IAAK;EAC9D,oBAAOX,IAAA,CAACM,uBAAuB;IAAA,GAAKK;EAAK,CAAG,CAAC;AAC/C,CAAC;;AAED;AACA;AACA;AACA,OAAO,MAAMC,aAAa,GAAG;EAC3B;EACAC,IAAI,EAAGC,OAAe,IAAK;IACzB,IAAIL,mBAAmB,EAAEI,IAAI,EAAE;MAC7BJ,mBAAmB,CAACI,IAAI,CAACC,OAAO,CAAC;IACnC;EACF,CAAC;EAED;EACAC,KAAK,EAAGD,OAAe,IAAK;IAC1B,IAAIL,mBAAmB,EAAEM,KAAK,EAAE;MAC9BN,mBAAmB,CAACM,KAAK,CAACD,OAAO,CAAC;IACpC;EACF,CAAC;EAED;EACAE,MAAM,EAAEA,CAACF,OAAe,EAAEG,IAAY,KAAK;IACzC,IAAIR,mBAAmB,EAAEO,MAAM,EAAE;MAC/BP,mBAAmB,CAACO,MAAM,CAACF,OAAO,EAAEG,IAAI,CAAC;IAC3C;EACF,CAAC;EAED;EACAC,cAAc,EAAGJ,OAAe,IAAsB;IACpD,IAAIL,mBAAmB,EAAES,cAAc,EAAE;MACvC,OAAOT,mBAAmB,CAACS,cAAc,CAACJ,OAAO,CAAC;IACpD;IACA,OAAOK,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAC3B,CAAC;EAED;EACAC,WAAW,EAAGP,OAAe,IAAsB;IACjD,IAAIL,mBAAmB,EAAEY,WAAW,EAAE;MACpC,OAAOZ,mBAAmB,CAACY,WAAW,CAACP,OAAO,CAAC;IACjD;IACA,OAAOK,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAC3B;AACF,CAAC;;AAED;AACA,IAAIE,YAAuC,GAAG,IAAI;AAElD,IAAIb,mBAAmB,EAAE;EACvBa,YAAY,GAAG,IAAIxB,kBAAkB,CAACW,mBAAmB,CAAC;AAC5D;AAEA,OAAO,MAAMc,mBAAmB,GAAG;EACjCC,WAAW,EAAEA,CAACC,SAAiB,EAAEC,QAAiC,KAAK;IACrE,IAAIJ,YAAY,EAAE;MAChB,OAAOA,YAAY,CAACE,WAAW,CAACC,SAAS,EAAEC,QAAQ,CAAC;IACtD;IACA,OAAO;MAAEC,MAAM,EAAEA,CAAA,KAAM,CAAC;IAAE,CAAC;EAC7B;AACF,CAAC;;AAED;AACA,OAAO,MAAMC,uBAAuB,GAAG;EACrCC,KAAK,EAAE,eAAe;EACtBC,KAAK,EAAE,SAAS;EAChBC,QAAQ,EAAE,YAAY;EACtBC,QAAQ,EAAE,oBAAoB;EAC9BC,OAAO,EAAE,mBAAmB;EAC5BC,OAAO,EAAE;AACX,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type ViewStyle } from 'react-native';
|
|
2
|
+
/**
|
|
3
|
+
* Props for the UnifiedPlayerView component
|
|
4
|
+
*/
|
|
5
|
+
export type UnifiedPlayerProps = {
|
|
6
|
+
videoUrl: string;
|
|
7
|
+
style: ViewStyle;
|
|
8
|
+
autoplay?: boolean;
|
|
9
|
+
loop?: boolean;
|
|
10
|
+
authToken?: string;
|
|
11
|
+
onReadyToPlay?: () => void;
|
|
12
|
+
onError?: (error: any) => void;
|
|
13
|
+
onPlaybackComplete?: () => void;
|
|
14
|
+
onProgress?: (data: {
|
|
15
|
+
currentTime: number;
|
|
16
|
+
duration: number;
|
|
17
|
+
}) => void;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* UnifiedPlayerView component for video playback
|
|
21
|
+
*/
|
|
22
|
+
export declare const UnifiedPlayerView: (props: UnifiedPlayerProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
/**
|
|
24
|
+
* API methods for controlling playback
|
|
25
|
+
*/
|
|
26
|
+
export declare const UnifiedPlayer: {
|
|
27
|
+
play: (viewTag: number) => void;
|
|
28
|
+
pause: (viewTag: number) => void;
|
|
29
|
+
seekTo: (viewTag: number, time: number) => void;
|
|
30
|
+
getCurrentTime: (viewTag: number) => Promise<number>;
|
|
31
|
+
getDuration: (viewTag: number) => Promise<number>;
|
|
32
|
+
};
|
|
33
|
+
export declare const UnifiedPlayerEvents: {
|
|
34
|
+
addListener: (eventType: string, listener: (...args: any[]) => any) => import("react-native").EmitterSubscription | {
|
|
35
|
+
remove: () => void;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export declare const UnifiedPlayerEventTypes: {
|
|
39
|
+
READY: string;
|
|
40
|
+
ERROR: string;
|
|
41
|
+
PROGRESS: string;
|
|
42
|
+
COMPLETE: string;
|
|
43
|
+
STALLED: string;
|
|
44
|
+
RESUMED: string;
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EAGf,MAAM,cAAc,CAAC;AAQtB;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAE/B,QAAQ,EAAE,MAAM,CAAC;IAGjB,KAAK,EAAE,SAAS,CAAC;IAGjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,IAAI,CAAC,EAAE,OAAO,CAAC;IAGf,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAG3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAG/B,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAGhC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACxE,CAAC;AAgBF;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,kBAAkB,4CAE1D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;oBAER,MAAM;qBAOL,MAAM;sBAOL,MAAM,QAAQ,MAAM;8BAOZ,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;2BAQ3B,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;CAMhD,CAAC;AASF,eAAO,MAAM,mBAAmB;6BACL,MAAM,YAAY,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;;;CAMnE,CAAC;AAGF,eAAO,MAAM,uBAAuB;;;;;;;CAOnC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-unified-player",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Unified Player",
|
|
5
|
+
"source": "./src/index.tsx",
|
|
6
|
+
"main": "./lib/module/index.js",
|
|
7
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
11
|
+
"default": "./lib/module/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"src",
|
|
17
|
+
"lib",
|
|
18
|
+
"android",
|
|
19
|
+
"ios",
|
|
20
|
+
"cpp",
|
|
21
|
+
"*.podspec",
|
|
22
|
+
"react-native.config.js",
|
|
23
|
+
"!ios/build",
|
|
24
|
+
"!android/build",
|
|
25
|
+
"!android/gradle",
|
|
26
|
+
"!android/gradlew",
|
|
27
|
+
"!android/gradlew.bat",
|
|
28
|
+
"!android/local.properties",
|
|
29
|
+
"!**/__tests__",
|
|
30
|
+
"!**/__fixtures__",
|
|
31
|
+
"!**/__mocks__",
|
|
32
|
+
"!**/.*"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"example": "yarn workspace react-native-unified-player-example",
|
|
36
|
+
"test": "jest",
|
|
37
|
+
"typecheck": "tsc",
|
|
38
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
39
|
+
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
40
|
+
"prepare": "bob build",
|
|
41
|
+
"release": "release-it"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"react-native",
|
|
45
|
+
"ios",
|
|
46
|
+
"android"
|
|
47
|
+
],
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/blueromans/react-native-unified-player.git"
|
|
51
|
+
},
|
|
52
|
+
"author": "Yaşar Özyurt <blueromans@hotmail.com> (https://github.com/blueromans)",
|
|
53
|
+
"license": "MIT",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/blueromans/react-native-unified-player/issues"
|
|
56
|
+
},
|
|
57
|
+
"homepage": "https://github.com/blueromans/react-native-unified-player#readme",
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"registry": "https://registry.npmjs.org/"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@commitlint/config-conventional": "^19.6.0",
|
|
63
|
+
"@eslint/compat": "^1.2.7",
|
|
64
|
+
"@eslint/eslintrc": "^3.3.0",
|
|
65
|
+
"@eslint/js": "^9.22.0",
|
|
66
|
+
"@evilmartians/lefthook": "^1.5.0",
|
|
67
|
+
"@react-native/eslint-config": "^0.78.0",
|
|
68
|
+
"@release-it/conventional-changelog": "^8.0.0",
|
|
69
|
+
"@types/jest": "^29.5.5",
|
|
70
|
+
"@types/react": "^19.0.0",
|
|
71
|
+
"commitlint": "^19.6.1",
|
|
72
|
+
"del-cli": "^5.1.0",
|
|
73
|
+
"eslint": "^9.22.0",
|
|
74
|
+
"eslint-config-prettier": "^10.1.1",
|
|
75
|
+
"eslint-plugin-prettier": "^5.2.3",
|
|
76
|
+
"jest": "^29.7.0",
|
|
77
|
+
"prettier": "^3.0.3",
|
|
78
|
+
"react": "19.0.0",
|
|
79
|
+
"react-native": "0.78.2",
|
|
80
|
+
"react-native-builder-bob": "^0.40.6",
|
|
81
|
+
"release-it": "^17.10.0",
|
|
82
|
+
"turbo": "^1.10.7",
|
|
83
|
+
"typescript": "^5.2.2"
|
|
84
|
+
},
|
|
85
|
+
"peerDependencies": {
|
|
86
|
+
"react": "*",
|
|
87
|
+
"react-native": "*"
|
|
88
|
+
},
|
|
89
|
+
"packageManager": "yarn@3.6.1",
|
|
90
|
+
"jest": {
|
|
91
|
+
"preset": "react-native",
|
|
92
|
+
"modulePathIgnorePatterns": [
|
|
93
|
+
"<rootDir>/example/node_modules",
|
|
94
|
+
"<rootDir>/lib/"
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
"commitlint": {
|
|
98
|
+
"extends": [
|
|
99
|
+
"@commitlint/config-conventional"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
"release-it": {
|
|
103
|
+
"git": {
|
|
104
|
+
"commitMessage": "chore: release ${version}",
|
|
105
|
+
"tagName": "v${version}"
|
|
106
|
+
},
|
|
107
|
+
"npm": {
|
|
108
|
+
"publish": true
|
|
109
|
+
},
|
|
110
|
+
"github": {
|
|
111
|
+
"release": true
|
|
112
|
+
},
|
|
113
|
+
"plugins": {
|
|
114
|
+
"@release-it/conventional-changelog": {
|
|
115
|
+
"preset": {
|
|
116
|
+
"name": "angular"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"hooks": {
|
|
121
|
+
"before:npm:publish": "yarn prepare-publish"
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"prettier": {
|
|
125
|
+
"quoteProps": "consistent",
|
|
126
|
+
"singleQuote": true,
|
|
127
|
+
"tabWidth": 2,
|
|
128
|
+
"trailingComma": "es5",
|
|
129
|
+
"useTabs": false
|
|
130
|
+
},
|
|
131
|
+
"react-native-builder-bob": {
|
|
132
|
+
"source": "src",
|
|
133
|
+
"output": "lib",
|
|
134
|
+
"targets": [
|
|
135
|
+
[
|
|
136
|
+
"module",
|
|
137
|
+
{
|
|
138
|
+
"esm": true
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
[
|
|
142
|
+
"typescript",
|
|
143
|
+
{
|
|
144
|
+
"project": "tsconfig.build.json"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
"create-react-native-library": {
|
|
150
|
+
"type": "legacy-view",
|
|
151
|
+
"languages": "kotlin-objc",
|
|
152
|
+
"version": "0.49.8"
|
|
153
|
+
}
|
|
154
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
requireNativeComponent,
|
|
3
|
+
UIManager,
|
|
4
|
+
Platform,
|
|
5
|
+
type ViewStyle,
|
|
6
|
+
NativeModules,
|
|
7
|
+
NativeEventEmitter,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
|
|
10
|
+
const LINKING_ERROR =
|
|
11
|
+
`The package 'react-native-unified-player' doesn't seem to be linked. Make sure: \n\n` +
|
|
12
|
+
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
|
|
13
|
+
'- You rebuilt the app after installing the package\n' +
|
|
14
|
+
'- You are not using Expo Go\n';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Props for the UnifiedPlayerView component
|
|
18
|
+
*/
|
|
19
|
+
export type UnifiedPlayerProps = {
|
|
20
|
+
// Video source URL
|
|
21
|
+
videoUrl: string;
|
|
22
|
+
|
|
23
|
+
// Apply custom styling
|
|
24
|
+
style: ViewStyle;
|
|
25
|
+
|
|
26
|
+
// Autoplay video when loaded
|
|
27
|
+
autoplay?: boolean;
|
|
28
|
+
|
|
29
|
+
// Should video loop when finished
|
|
30
|
+
loop?: boolean;
|
|
31
|
+
|
|
32
|
+
// Optional auth token for protected streams
|
|
33
|
+
authToken?: string;
|
|
34
|
+
|
|
35
|
+
// Callback when video is ready to play
|
|
36
|
+
onReadyToPlay?: () => void;
|
|
37
|
+
|
|
38
|
+
// Callback when an error occurs
|
|
39
|
+
onError?: (error: any) => void;
|
|
40
|
+
|
|
41
|
+
// Callback when video playback finishes
|
|
42
|
+
onPlaybackComplete?: () => void;
|
|
43
|
+
|
|
44
|
+
// Callback for playback progress
|
|
45
|
+
onProgress?: (data: { currentTime: number; duration: number }) => void;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Name of the native component
|
|
49
|
+
const ComponentName = 'UnifiedPlayerView';
|
|
50
|
+
|
|
51
|
+
// Native component import
|
|
52
|
+
const NativeUnifiedPlayerView =
|
|
53
|
+
UIManager.getViewManagerConfig(ComponentName) != null
|
|
54
|
+
? requireNativeComponent<UnifiedPlayerProps>(ComponentName)
|
|
55
|
+
: () => {
|
|
56
|
+
throw new Error(LINKING_ERROR);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Native module for additional control methods
|
|
60
|
+
const UnifiedPlayerModule = NativeModules.UnifiedPlayerModule;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* UnifiedPlayerView component for video playback
|
|
64
|
+
*/
|
|
65
|
+
export const UnifiedPlayerView = (props: UnifiedPlayerProps) => {
|
|
66
|
+
return <NativeUnifiedPlayerView {...props} />;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* API methods for controlling playback
|
|
71
|
+
*/
|
|
72
|
+
export const UnifiedPlayer = {
|
|
73
|
+
// Play the video
|
|
74
|
+
play: (viewTag: number) => {
|
|
75
|
+
if (UnifiedPlayerModule?.play) {
|
|
76
|
+
UnifiedPlayerModule.play(viewTag);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
// Pause the video
|
|
81
|
+
pause: (viewTag: number) => {
|
|
82
|
+
if (UnifiedPlayerModule?.pause) {
|
|
83
|
+
UnifiedPlayerModule.pause(viewTag);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
// Seek to a specific time
|
|
88
|
+
seekTo: (viewTag: number, time: number) => {
|
|
89
|
+
if (UnifiedPlayerModule?.seekTo) {
|
|
90
|
+
UnifiedPlayerModule.seekTo(viewTag, time);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// Get the current playback time
|
|
95
|
+
getCurrentTime: (viewTag: number): Promise<number> => {
|
|
96
|
+
if (UnifiedPlayerModule?.getCurrentTime) {
|
|
97
|
+
return UnifiedPlayerModule.getCurrentTime(viewTag);
|
|
98
|
+
}
|
|
99
|
+
return Promise.resolve(0);
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
// Get the duration of the video
|
|
103
|
+
getDuration: (viewTag: number): Promise<number> => {
|
|
104
|
+
if (UnifiedPlayerModule?.getDuration) {
|
|
105
|
+
return UnifiedPlayerModule.getDuration(viewTag);
|
|
106
|
+
}
|
|
107
|
+
return Promise.resolve(0);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Events emitter for native events
|
|
112
|
+
let eventEmitter: NativeEventEmitter | null = null;
|
|
113
|
+
|
|
114
|
+
if (UnifiedPlayerModule) {
|
|
115
|
+
eventEmitter = new NativeEventEmitter(UnifiedPlayerModule);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const UnifiedPlayerEvents = {
|
|
119
|
+
addListener: (eventType: string, listener: (...args: any[]) => any) => {
|
|
120
|
+
if (eventEmitter) {
|
|
121
|
+
return eventEmitter.addListener(eventType, listener);
|
|
122
|
+
}
|
|
123
|
+
return { remove: () => {} };
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// Event names
|
|
128
|
+
export const UnifiedPlayerEventTypes = {
|
|
129
|
+
READY: 'onReadyToPlay',
|
|
130
|
+
ERROR: 'onError',
|
|
131
|
+
PROGRESS: 'onProgress',
|
|
132
|
+
COMPLETE: 'onPlaybackComplete',
|
|
133
|
+
STALLED: 'onPlaybackStalled',
|
|
134
|
+
RESUMED: 'onPlaybackResumed',
|
|
135
|
+
};
|