react-native-unified-player 0.3.3 → 0.3.4
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/UnifiedPlayer.podspec +1 -1
- package/android/src/main/java/com/unifiedplayer/UnifiedPlayerModule.kt +131 -116
- package/android/src/main/java/com/unifiedplayer/UnifiedPlayerPackage.kt +6 -1
- package/android/src/main/java/com/unifiedplayer/UnifiedPlayerView.kt +38 -10
- package/ios/UnifiedPlayerModule.h +5 -1
- package/ios/UnifiedPlayerModule.m +31 -22
- package/ios/UnifiedPlayerUIView.h +42 -0
- package/ios/UnifiedPlayerViewManager.m +55 -38
- package/lib/module/index.js +20 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +6 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +29 -0
package/UnifiedPlayer.podspec
CHANGED
|
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.license = package["license"]
|
|
11
11
|
s.authors = package["author"]
|
|
12
12
|
|
|
13
|
-
s.platforms = { :ios => "
|
|
13
|
+
s.platforms = { :ios => "13.0" }
|
|
14
14
|
s.source = { :git => "https://github.com/blueromans/react-native-unified-player.git", :tag => "#{s.version}" }
|
|
15
15
|
|
|
16
16
|
s.source_files = "ios/**/*.{h,m,mm}"
|
|
@@ -1,172 +1,187 @@
|
|
|
1
1
|
package com.unifiedplayer
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import com.facebook.react.bridge.ReactMethod
|
|
6
|
-
import com.facebook.react.bridge.Promise
|
|
7
|
-
import com.facebook.react.uimanager.UIManagerModule
|
|
3
|
+
import android.graphics.Bitmap
|
|
4
|
+
import android.util.Base64
|
|
8
5
|
import android.util.Log
|
|
9
|
-
import com.facebook.react.bridge
|
|
10
|
-
import
|
|
6
|
+
import com.facebook.react.bridge.*
|
|
7
|
+
import com.facebook.react.uimanager.UIManagerModule
|
|
8
|
+
import com.facebook.react.uimanager.UIBlock
|
|
9
|
+
import com.facebook.react.uimanager.NativeViewHierarchyManager
|
|
10
|
+
import java.io.ByteArrayOutputStream
|
|
11
11
|
|
|
12
12
|
class UnifiedPlayerModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
init {
|
|
18
|
-
Log.d(TAG, "UnifiedPlayerModule initialized")
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
override fun getName(): String {
|
|
22
|
-
Log.d(TAG, "getName() called, returning 'UnifiedPlayer'")
|
|
23
|
-
return "UnifiedPlayer"
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
private fun getPlayerViewByTag(viewTag: Int): UnifiedPlayerView? {
|
|
13
|
+
private var isModuleReady = false
|
|
14
|
+
|
|
15
|
+
override fun initialize() {
|
|
16
|
+
super.initialize()
|
|
27
17
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (view is UnifiedPlayerView) {
|
|
32
|
-
return view
|
|
33
|
-
} else if (view != null) {
|
|
34
|
-
Log.e(TAG, "View with tag $viewTag is not a UnifiedPlayerView, it's a ${view.javaClass.simpleName}")
|
|
18
|
+
reactContext.getNativeModule(UIManagerModule::class.java)?.let {
|
|
19
|
+
isModuleReady = true
|
|
20
|
+
Log.d(TAG, "Module successfully initialized")
|
|
35
21
|
}
|
|
36
22
|
} catch (e: Exception) {
|
|
37
|
-
Log.e(TAG, "
|
|
23
|
+
Log.e(TAG, "Initialization failed", e)
|
|
38
24
|
}
|
|
39
|
-
return null
|
|
40
25
|
}
|
|
41
|
-
|
|
26
|
+
companion object {
|
|
27
|
+
private const val TAG = "UnifiedPlayerModule"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override fun getName(): String = "UnifiedPlayer"
|
|
31
|
+
|
|
42
32
|
@ReactMethod
|
|
43
33
|
fun play(viewTag: Int, promise: Promise) {
|
|
44
|
-
Log.d(TAG, "Native play method called with viewTag: $viewTag")
|
|
45
34
|
try {
|
|
46
|
-
val
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
val uiManager = reactApplicationContext.getNativeModule(UIManagerModule::class.java)
|
|
36
|
+
?: throw IllegalStateException("UIManagerModule not available")
|
|
37
|
+
|
|
38
|
+
uiManager.addUIBlock(UIBlock { nativeViewHierarchyManager ->
|
|
39
|
+
try {
|
|
40
|
+
val view = nativeViewHierarchyManager.resolveView(viewTag) as? UnifiedPlayerView
|
|
41
|
+
if (view != null) {
|
|
42
|
+
view.play()
|
|
52
43
|
promise.resolve(true)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
promise.reject("PLAY_ERROR", "Error during play: ${e.message}", e)
|
|
44
|
+
} else {
|
|
45
|
+
promise.reject("INVALID_VIEW", "View with tag $viewTag not found")
|
|
56
46
|
}
|
|
47
|
+
} catch (e: Exception) {
|
|
48
|
+
Log.e(TAG, "Error in play method", e)
|
|
49
|
+
promise.reject("PLAY_ERROR", "Error in play method", e)
|
|
57
50
|
}
|
|
58
|
-
}
|
|
59
|
-
Log.e(TAG, "Player view not found for tag: $viewTag")
|
|
60
|
-
promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
|
|
61
|
-
}
|
|
51
|
+
})
|
|
62
52
|
} catch (e: Exception) {
|
|
63
|
-
Log.e(TAG, "Error in play method
|
|
64
|
-
promise.reject("
|
|
53
|
+
Log.e(TAG, "Error in play method", e)
|
|
54
|
+
promise.reject("UIMANAGER_ERROR", "UIManagerModule not available", e)
|
|
65
55
|
}
|
|
66
56
|
}
|
|
67
57
|
|
|
68
58
|
@ReactMethod
|
|
69
59
|
fun pause(viewTag: Int, promise: Promise) {
|
|
70
|
-
Log.d(TAG, "Native pause method called with viewTag: $viewTag")
|
|
71
60
|
try {
|
|
72
|
-
val
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
61
|
+
val uiManager = reactApplicationContext.getNativeModule(UIManagerModule::class.java)
|
|
62
|
+
?: throw IllegalStateException("UIManagerModule not available")
|
|
63
|
+
|
|
64
|
+
uiManager.addUIBlock(UIBlock { nativeViewHierarchyManager ->
|
|
65
|
+
try {
|
|
66
|
+
val view = nativeViewHierarchyManager.resolveView(viewTag) as? UnifiedPlayerView
|
|
67
|
+
if (view != null) {
|
|
68
|
+
view.pause()
|
|
78
69
|
promise.resolve(true)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
promise.reject("PAUSE_ERROR", "Error during pause: ${e.message}", e)
|
|
70
|
+
} else {
|
|
71
|
+
promise.reject("INVALID_VIEW", "View with tag $viewTag not found")
|
|
82
72
|
}
|
|
73
|
+
} catch (e: Exception) {
|
|
74
|
+
Log.e(TAG, "Error in pause method", e)
|
|
75
|
+
promise.reject("PAUSE_ERROR", "Error in pause method", e)
|
|
83
76
|
}
|
|
84
|
-
}
|
|
85
|
-
Log.e(TAG, "Player view not found for tag: $viewTag")
|
|
86
|
-
promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
|
|
87
|
-
}
|
|
77
|
+
})
|
|
88
78
|
} catch (e: Exception) {
|
|
89
|
-
Log.e(TAG, "Error in pause method
|
|
90
|
-
promise.reject("
|
|
79
|
+
Log.e(TAG, "Error in pause method", e)
|
|
80
|
+
promise.reject("UIMANAGER_ERROR", "UIManagerModule not available", e)
|
|
91
81
|
}
|
|
92
82
|
}
|
|
93
83
|
|
|
94
84
|
@ReactMethod
|
|
95
85
|
fun seekTo(viewTag: Int, seconds: Float, promise: Promise) {
|
|
96
|
-
Log.d(TAG, "Native seekTo method called with viewTag: $viewTag, seconds: $seconds")
|
|
97
86
|
try {
|
|
98
|
-
val
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
87
|
+
val uiManager = reactApplicationContext.getNativeModule(UIManagerModule::class.java)
|
|
88
|
+
?: throw IllegalStateException("UIManagerModule not available")
|
|
89
|
+
|
|
90
|
+
uiManager.addUIBlock(UIBlock { nativeViewHierarchyManager ->
|
|
91
|
+
try {
|
|
92
|
+
val view = nativeViewHierarchyManager.resolveView(viewTag) as? UnifiedPlayerView
|
|
93
|
+
if (view != null) {
|
|
94
|
+
view.seekTo(seconds)
|
|
104
95
|
promise.resolve(true)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
promise.reject("SEEK_ERROR", "Error during seekTo: ${e.message}", e)
|
|
96
|
+
} else {
|
|
97
|
+
promise.reject("INVALID_VIEW", "View with tag $viewTag not found")
|
|
108
98
|
}
|
|
99
|
+
} catch (e: Exception) {
|
|
100
|
+
Log.e(TAG, "Error in seekTo method", e)
|
|
101
|
+
promise.reject("SEEK_ERROR", "Error in seekTo method", e)
|
|
109
102
|
}
|
|
110
|
-
}
|
|
111
|
-
Log.e(TAG, "Player view not found for tag: $viewTag")
|
|
112
|
-
promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
|
|
113
|
-
}
|
|
103
|
+
})
|
|
114
104
|
} catch (e: Exception) {
|
|
115
|
-
Log.e(TAG, "Error in seekTo method
|
|
116
|
-
promise.reject("
|
|
105
|
+
Log.e(TAG, "Error in seekTo method", e)
|
|
106
|
+
promise.reject("UIMANAGER_ERROR", "UIManagerModule not available", e)
|
|
117
107
|
}
|
|
118
108
|
}
|
|
119
109
|
|
|
120
110
|
@ReactMethod
|
|
121
111
|
fun getCurrentTime(viewTag: Int, promise: Promise) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
promise.resolve(currentTime)
|
|
131
|
-
} catch (e: Exception) {
|
|
132
|
-
Log.e(TAG, "Error getting current time: ${e.message}", e)
|
|
133
|
-
promise.reject("GET_TIME_ERROR", "Error getting current time: ${e.message}", e)
|
|
112
|
+
reactApplicationContext.getNativeModule(UIManagerModule::class.java)?.let { uiManager ->
|
|
113
|
+
uiManager.addUIBlock(UIBlock { nativeViewHierarchyManager ->
|
|
114
|
+
try {
|
|
115
|
+
val view = nativeViewHierarchyManager.resolveView(viewTag) as? UnifiedPlayerView
|
|
116
|
+
if (view != null) {
|
|
117
|
+
promise.resolve(view.getCurrentTime())
|
|
118
|
+
} else {
|
|
119
|
+
promise.reject("INVALID_VIEW", "View with tag $viewTag not found")
|
|
134
120
|
}
|
|
121
|
+
} catch (e: Exception) {
|
|
122
|
+
Log.e(TAG, "Error in getCurrentTime method", e)
|
|
123
|
+
promise.reject("GET_TIME_ERROR", "Error in getCurrentTime method", e)
|
|
135
124
|
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
} catch (e: Exception) {
|
|
141
|
-
Log.e(TAG, "Error in getCurrentTime method: ${e.message}", e)
|
|
142
|
-
promise.reject("GET_TIME_ERROR", "Error in getCurrentTime method: ${e.message}", e)
|
|
125
|
+
})
|
|
126
|
+
} ?: run {
|
|
127
|
+
promise.reject("ERROR", "UIManagerModule not available")
|
|
143
128
|
}
|
|
144
129
|
}
|
|
145
130
|
|
|
146
131
|
@ReactMethod
|
|
147
132
|
fun getDuration(viewTag: Int, promise: Promise) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
promise.resolve(duration)
|
|
157
|
-
} catch (e: Exception) {
|
|
158
|
-
Log.e(TAG, "Error getting duration: ${e.message}", e)
|
|
159
|
-
promise.reject("GET_DURATION_ERROR", "Error getting duration: ${e.message}", e)
|
|
133
|
+
reactApplicationContext.getNativeModule(UIManagerModule::class.java)?.let { uiManager ->
|
|
134
|
+
uiManager.addUIBlock(UIBlock { nativeViewHierarchyManager ->
|
|
135
|
+
try {
|
|
136
|
+
val view = nativeViewHierarchyManager.resolveView(viewTag) as? UnifiedPlayerView
|
|
137
|
+
if (view != null) {
|
|
138
|
+
promise.resolve(view.getDuration())
|
|
139
|
+
} else {
|
|
140
|
+
promise.reject("INVALID_VIEW", "View with tag $viewTag not found")
|
|
160
141
|
}
|
|
142
|
+
} catch (e: Exception) {
|
|
143
|
+
Log.e(TAG, "Error in getDuration method", e)
|
|
144
|
+
promise.reject("GET_DURATION_ERROR", "Error in getDuration method", e)
|
|
161
145
|
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
146
|
+
})
|
|
147
|
+
} ?: run {
|
|
148
|
+
promise.reject("ERROR", "UIManagerModule not available")
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@ReactMethod
|
|
153
|
+
fun capture(viewTag: Int, promise: Promise) {
|
|
154
|
+
try {
|
|
155
|
+
if (!isModuleReady) {
|
|
156
|
+
throw IllegalStateException("Module not ready. Ensure React Native bridge is initialized.")
|
|
165
157
|
}
|
|
158
|
+
val uiManager = reactApplicationContext.getNativeModule(UIManagerModule::class.java)
|
|
159
|
+
?: throw IllegalStateException("UIManagerModule not available. Is the bridge active?")
|
|
160
|
+
|
|
161
|
+
uiManager.addUIBlock(UIBlock { nativeViewHierarchyManager ->
|
|
162
|
+
try {
|
|
163
|
+
val view = nativeViewHierarchyManager.resolveView(viewTag) as? UnifiedPlayerView
|
|
164
|
+
if (view != null) {
|
|
165
|
+
val bitmap = view.captureFrame()
|
|
166
|
+
if (bitmap != null) {
|
|
167
|
+
val outputStream = ByteArrayOutputStream()
|
|
168
|
+
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
|
|
169
|
+
val base64 = Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT)
|
|
170
|
+
promise.resolve(base64)
|
|
171
|
+
} else {
|
|
172
|
+
promise.reject("CAPTURE_ERROR", "Failed to capture frame")
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
promise.reject("INVALID_VIEW", "View with tag $viewTag not found")
|
|
176
|
+
}
|
|
177
|
+
} catch (e: Exception) {
|
|
178
|
+
Log.e(TAG, "Error in capture method", e)
|
|
179
|
+
promise.reject("CAPTURE_ERROR", "Error in capture method", e)
|
|
180
|
+
}
|
|
181
|
+
})
|
|
166
182
|
} catch (e: Exception) {
|
|
167
|
-
Log.e(TAG, "Error in
|
|
168
|
-
promise.reject("
|
|
183
|
+
Log.e(TAG, "Error in capture method", e)
|
|
184
|
+
promise.reject("UIMANAGER_ERROR", "UIManagerModule not available", e)
|
|
169
185
|
}
|
|
170
186
|
}
|
|
171
|
-
|
|
172
187
|
}
|
|
@@ -12,7 +12,12 @@ class UnifiedPlayerPackage : ReactPackage {
|
|
|
12
12
|
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
13
13
|
Log.d(TAG, "Creating native modules")
|
|
14
14
|
return listOf(
|
|
15
|
-
UnifiedPlayerModule(reactContext)
|
|
15
|
+
UnifiedPlayerModule(reactContext).apply {
|
|
16
|
+
reactContext.runOnUiQueueThread {
|
|
17
|
+
// Initialize module on UI thread
|
|
18
|
+
Log.d(TAG, "Module initialized on UI thread")
|
|
19
|
+
}
|
|
20
|
+
}
|
|
16
21
|
)
|
|
17
22
|
}
|
|
18
23
|
|
|
@@ -4,9 +4,13 @@ import android.annotation.SuppressLint
|
|
|
4
4
|
import android.content.Context
|
|
5
5
|
import android.graphics.Color
|
|
6
6
|
import android.util.Log
|
|
7
|
+
import android.graphics.Bitmap
|
|
8
|
+
import android.graphics.Canvas
|
|
7
9
|
import android.os.Handler
|
|
8
10
|
import android.os.Looper
|
|
9
11
|
import android.view.Gravity
|
|
12
|
+
import android.view.TextureView
|
|
13
|
+
import android.view.View
|
|
10
14
|
import android.widget.FrameLayout
|
|
11
15
|
import com.facebook.react.bridge.Arguments
|
|
12
16
|
import com.google.android.exoplayer2.ExoPlayer
|
|
@@ -312,17 +316,41 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
|
|
|
312
316
|
}
|
|
313
317
|
}
|
|
314
318
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
319
|
+
fun getDuration(): Float {
|
|
320
|
+
Log.d(TAG, "GetDuration method called")
|
|
321
|
+
return player?.let {
|
|
322
|
+
val duration = it.duration.toFloat() / 1000f
|
|
323
|
+
Log.d(TAG, "Duration: $duration seconds (raw: ${it.duration})")
|
|
324
|
+
if (it.duration > 0) duration else 0f
|
|
325
|
+
} ?: run {
|
|
326
|
+
Log.e(TAG, "Cannot get duration: player is null")
|
|
327
|
+
0f
|
|
325
328
|
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
fun captureFrame(): Bitmap? {
|
|
332
|
+
Log.d(TAG, "CaptureFrame method called")
|
|
333
|
+
try {
|
|
334
|
+
// Create a bitmap with the same dimensions as the player view
|
|
335
|
+
val bitmap = Bitmap.createBitmap(
|
|
336
|
+
playerView.width,
|
|
337
|
+
playerView.height,
|
|
338
|
+
Bitmap.Config.ARGB_8888
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
// Create a canvas with the bitmap
|
|
342
|
+
val canvas = Canvas(bitmap)
|
|
343
|
+
|
|
344
|
+
// Draw the player view onto the canvas
|
|
345
|
+
playerView.draw(canvas)
|
|
346
|
+
|
|
347
|
+
Log.d(TAG, "Successfully captured frame from PlayerView")
|
|
348
|
+
return bitmap
|
|
349
|
+
} catch (e: Exception) {
|
|
350
|
+
Log.e(TAG, "Error capturing frame: ${e.message}", e)
|
|
351
|
+
return null
|
|
352
|
+
}
|
|
353
|
+
}
|
|
326
354
|
|
|
327
355
|
// Add a getter for the ExoPlayer instance
|
|
328
356
|
val exoPlayer: ExoPlayer?
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#import <React/RCTEventEmitter.h>
|
|
2
2
|
#import <React/RCTBridgeModule.h>
|
|
3
|
+
#import <MobileVLCKit/MobileVLCKit.h> // Import MobileVLCKit
|
|
4
|
+
|
|
5
|
+
// Forward declaration for UnifiedPlayerUIView
|
|
6
|
+
@class UnifiedPlayerUIView;
|
|
3
7
|
|
|
4
8
|
@interface UnifiedPlayerModule : RCTEventEmitter <RCTBridgeModule>
|
|
5
|
-
@end
|
|
9
|
+
@end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#import "UnifiedPlayerModule.h"
|
|
2
|
+
#import "UnifiedPlayerUIView.h"
|
|
2
3
|
#import <React/RCTLog.h>
|
|
3
4
|
#import <React/RCTBridgeModule.h>
|
|
4
5
|
#import <React/RCTEventEmitter.h>
|
|
@@ -175,35 +176,43 @@ RCT_EXPORT_METHOD(getCurrentTime:(nonnull NSNumber *)reactTag
|
|
|
175
176
|
// Get video duration
|
|
176
177
|
RCT_EXPORT_METHOD(getDuration:(nonnull NSNumber *)reactTag
|
|
177
178
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
178
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
179
|
-
|
|
179
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
180
|
+
{
|
|
181
|
+
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
180
182
|
UIView *view = viewRegistry[reactTag];
|
|
181
|
-
if (!view) {
|
|
182
|
-
|
|
183
|
-
|
|
183
|
+
if (![view isKindOfClass:[UnifiedPlayerUIView class]]) {
|
|
184
|
+
RCTLogError(@"Invalid view returned from registry, expecting UnifiedPlayerUIView, got: %@", view);
|
|
185
|
+
reject(@"E_INVALID_VIEW", @"Expected UnifiedPlayerUIView", nil);
|
|
186
|
+
} else {
|
|
187
|
+
UnifiedPlayerUIView *playerView = (UnifiedPlayerUIView *)view;
|
|
188
|
+
float duration = [playerView getDuration];
|
|
189
|
+
resolve(@(duration));
|
|
184
190
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
191
|
+
}];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
RCT_EXPORT_METHOD(capture:(nonnull NSNumber *)reactTag
|
|
195
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
196
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
197
|
+
{
|
|
198
|
+
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
199
|
+
UIView *view = viewRegistry[reactTag];
|
|
200
|
+
if (![view isKindOfClass:[UnifiedPlayerUIView class]]) {
|
|
201
|
+
RCTLogError(@"Invalid view returned from registry, expecting UnifiedPlayerUIView, got: %@", view);
|
|
202
|
+
reject(@"E_INVALID_VIEW", @"Expected UnifiedPlayerUIView", nil);
|
|
190
203
|
return;
|
|
191
204
|
}
|
|
192
205
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
duration = player.media.length.intValue / 1000.0f;
|
|
200
|
-
resolve(@(duration));
|
|
206
|
+
UnifiedPlayerUIView *playerView = (UnifiedPlayerUIView *)view;
|
|
207
|
+
[playerView captureFrameWithCompletion:^(NSString * _Nullable base64String, NSError * _Nullable error) {
|
|
208
|
+
if (error) {
|
|
209
|
+
reject(@"E_CAPTURE_FAILED", error.localizedDescription, error);
|
|
210
|
+
} else if (base64String) {
|
|
211
|
+
resolve(base64String);
|
|
201
212
|
} else {
|
|
202
|
-
reject(@"
|
|
213
|
+
reject(@"E_CAPTURE_FAILED", @"Unknown capture error", nil);
|
|
203
214
|
}
|
|
204
|
-
}
|
|
205
|
-
reject(@"error", [NSString stringWithFormat:@"Error getting duration: %@", exception.reason], nil);
|
|
206
|
-
}
|
|
215
|
+
}];
|
|
207
216
|
}];
|
|
208
217
|
}
|
|
209
218
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
#import <React/RCTView.h>
|
|
3
|
+
#import <React/RCTComponent.h>
|
|
4
|
+
#import <MobileVLCKit/MobileVLCKit.h>
|
|
5
|
+
|
|
6
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
7
|
+
|
|
8
|
+
@interface UnifiedPlayerUIView : UIView <VLCMediaPlayerDelegate>
|
|
9
|
+
|
|
10
|
+
@property (nonatomic, strong) VLCMediaPlayer *player;
|
|
11
|
+
@property (nonatomic, copy) NSString *videoUrlString;
|
|
12
|
+
@property (nonatomic, assign) BOOL autoplay;
|
|
13
|
+
@property (nonatomic, assign) BOOL loop;
|
|
14
|
+
@property (nonatomic, assign) BOOL isPaused;
|
|
15
|
+
@property (nonatomic, strong) NSArray *mediaOptions;
|
|
16
|
+
@property (nonatomic, weak) RCTBridge *bridge;
|
|
17
|
+
@property (nonatomic, assign) VLCMediaPlayerState previousState;
|
|
18
|
+
@property (nonatomic, assign) BOOL hasRenderedVideo;
|
|
19
|
+
|
|
20
|
+
// Event callbacks
|
|
21
|
+
@property (nonatomic, copy) RCTDirectEventBlock onLoadStart;
|
|
22
|
+
@property (nonatomic, copy) RCTDirectEventBlock onReadyToPlay;
|
|
23
|
+
@property (nonatomic, copy) RCTDirectEventBlock onError;
|
|
24
|
+
@property (nonatomic, copy) RCTDirectEventBlock onProgress;
|
|
25
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPlaybackComplete;
|
|
26
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPlaybackStalled;
|
|
27
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPlaybackResumed;
|
|
28
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPlaying;
|
|
29
|
+
@property (nonatomic, copy) RCTDirectEventBlock onPaused;
|
|
30
|
+
|
|
31
|
+
// Method declarations
|
|
32
|
+
- (void)setupWithVideoUrlString:(NSString *)videoUrlString;
|
|
33
|
+
- (void)play;
|
|
34
|
+
- (void)pause;
|
|
35
|
+
- (void)seekToTime:(NSNumber *)timeNumber;
|
|
36
|
+
- (float)getCurrentTime;
|
|
37
|
+
- (float)getDuration;
|
|
38
|
+
- (void)captureFrameWithCompletion:(void (^)(NSString * _Nullable base64String, NSError * _Nullable error))completion;
|
|
39
|
+
|
|
40
|
+
@end
|
|
41
|
+
|
|
42
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -8,37 +8,7 @@
|
|
|
8
8
|
#import <React/RCTComponent.h>
|
|
9
9
|
#import <MobileVLCKit/MobileVLCKit.h>
|
|
10
10
|
#import "UnifiedPlayerModule.h"
|
|
11
|
-
|
|
12
|
-
// Forward declarations
|
|
13
|
-
@interface UnifiedPlayerUIView : UIView <VLCMediaPlayerDelegate>
|
|
14
|
-
@property (nonatomic, strong) VLCMediaPlayer *player;
|
|
15
|
-
@property (nonatomic, copy) NSString *videoUrlString;
|
|
16
|
-
@property (nonatomic, assign) BOOL autoplay;
|
|
17
|
-
@property (nonatomic, assign) BOOL loop;
|
|
18
|
-
@property (nonatomic, assign) BOOL isPaused;
|
|
19
|
-
@property (nonatomic, strong) NSArray *mediaOptions;
|
|
20
|
-
@property (nonatomic, weak) RCTBridge *bridge;
|
|
21
|
-
@property (nonatomic, assign) VLCMediaPlayerState previousState;
|
|
22
|
-
@property (nonatomic, assign) BOOL hasRenderedVideo;
|
|
23
|
-
|
|
24
|
-
// Event callbacks
|
|
25
|
-
@property (nonatomic, copy) RCTDirectEventBlock onLoadStart;
|
|
26
|
-
@property (nonatomic, copy) RCTDirectEventBlock onReadyToPlay;
|
|
27
|
-
@property (nonatomic, copy) RCTDirectEventBlock onError;
|
|
28
|
-
@property (nonatomic, copy) RCTDirectEventBlock onProgress;
|
|
29
|
-
@property (nonatomic, copy) RCTDirectEventBlock onPlaybackComplete;
|
|
30
|
-
@property (nonatomic, copy) RCTDirectEventBlock onPlaybackStalled;
|
|
31
|
-
@property (nonatomic, copy) RCTDirectEventBlock onPlaybackResumed;
|
|
32
|
-
@property (nonatomic, copy) RCTDirectEventBlock onPlaying;
|
|
33
|
-
@property (nonatomic, copy) RCTDirectEventBlock onPaused;
|
|
34
|
-
|
|
35
|
-
- (void)setupWithVideoUrlString:(NSString *)videoUrlString;
|
|
36
|
-
- (void)play;
|
|
37
|
-
- (void)pause;
|
|
38
|
-
- (void)seekToTime:(NSNumber *)timeNumber;
|
|
39
|
-
- (float)getCurrentTime;
|
|
40
|
-
- (float)getDuration;
|
|
41
|
-
@end
|
|
11
|
+
#import "UnifiedPlayerUIView.h"
|
|
42
12
|
|
|
43
13
|
// Main player view implementation
|
|
44
14
|
@implementation UnifiedPlayerUIView
|
|
@@ -179,13 +149,15 @@
|
|
|
179
149
|
self.onPlaying(body);
|
|
180
150
|
} else if ([eventName isEqualToString:@"onPaused"] && self.onPaused) {
|
|
181
151
|
self.onPaused(body);
|
|
152
|
+
} else {
|
|
153
|
+
RCTLogInfo(@"[UnifiedPlayerViewManager] No direct event block found for event: %@", eventName);
|
|
182
154
|
}
|
|
183
155
|
|
|
184
|
-
//
|
|
185
|
-
UnifiedPlayerModule *eventEmitter = [self.bridge moduleForClass:[UnifiedPlayerModule class]];
|
|
186
|
-
if (eventEmitter != nil) {
|
|
187
|
-
|
|
188
|
-
}
|
|
156
|
+
// Removed the redundant event sending via UnifiedPlayerModule emitter
|
|
157
|
+
// UnifiedPlayerModule *eventEmitter = [self.bridge moduleForClass:[UnifiedPlayerModule class]];
|
|
158
|
+
// if (eventEmitter != nil) {
|
|
159
|
+
// [eventEmitter sendEventWithName:eventName body:body];
|
|
160
|
+
// }
|
|
189
161
|
}
|
|
190
162
|
|
|
191
163
|
- (void)setupWithVideoUrlString:(NSString *)videoUrlString {
|
|
@@ -369,11 +341,49 @@
|
|
|
369
341
|
}
|
|
370
342
|
|
|
371
343
|
- (float)getCurrentTime {
|
|
372
|
-
|
|
344
|
+
if (_player) {
|
|
345
|
+
return _player.time.intValue / 1000.0f;
|
|
346
|
+
}
|
|
347
|
+
return 0.0f;
|
|
373
348
|
}
|
|
374
349
|
|
|
375
350
|
- (float)getDuration {
|
|
376
|
-
|
|
351
|
+
if (_player && _player.media) {
|
|
352
|
+
return _player.media.length.intValue / 1000.0f;
|
|
353
|
+
}
|
|
354
|
+
return 0.0f;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
- (void)captureFrameWithCompletion:(void (^)(NSString * _Nullable base64String, NSError * _Nullable error))completion {
|
|
358
|
+
if (!_player || !_player.drawable) {
|
|
359
|
+
NSError *error = [NSError errorWithDomain:@"UnifiedPlayerUIView" code:100 userInfo:@{NSLocalizedDescriptionKey: @"Player not initialized"}];
|
|
360
|
+
if (completion) {
|
|
361
|
+
completion(nil, error);
|
|
362
|
+
}
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Create a snapshot of the current view
|
|
367
|
+
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);
|
|
368
|
+
[self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
|
|
369
|
+
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
|
|
370
|
+
UIGraphicsEndImageContext();
|
|
371
|
+
|
|
372
|
+
if (!image) {
|
|
373
|
+
NSError *error = [NSError errorWithDomain:@"UnifiedPlayerUIView" code:101 userInfo:@{NSLocalizedDescriptionKey: @"Failed to capture frame"}];
|
|
374
|
+
if (completion) {
|
|
375
|
+
completion(nil, error);
|
|
376
|
+
}
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Convert to base64
|
|
381
|
+
NSData *imageData = UIImageJPEGRepresentation(image, 0.8);
|
|
382
|
+
NSString *base64String = [imageData base64EncodedStringWithOptions:0];
|
|
383
|
+
|
|
384
|
+
if (completion) {
|
|
385
|
+
completion(base64String, nil);
|
|
386
|
+
}
|
|
377
387
|
}
|
|
378
388
|
|
|
379
389
|
- (void)setAutoplay:(BOOL)autoplay {
|
|
@@ -406,6 +416,12 @@
|
|
|
406
416
|
float currentTime = [self getCurrentTime];
|
|
407
417
|
float duration = [self getDuration];
|
|
408
418
|
|
|
419
|
+
// Avoid sending progress events for invalid durations
|
|
420
|
+
if (duration > 0 && !isnan(duration)) {
|
|
421
|
+
[self sendProgressEvent:currentTime duration:duration];
|
|
422
|
+
}
|
|
423
|
+
RCTLogInfo(@"[UnifiedPlayerViewManager] mediaPlayerTimeChanged - CurrentTime: %f, Duration: %f", currentTime, duration); // Added Log
|
|
424
|
+
|
|
409
425
|
// Avoid sending progress events for invalid durations
|
|
410
426
|
if (duration > 0 && !isnan(duration)) {
|
|
411
427
|
[self sendProgressEvent:currentTime duration:duration];
|
|
@@ -414,6 +430,7 @@
|
|
|
414
430
|
|
|
415
431
|
- (void)mediaPlayerStateChanged:(NSNotification *)notification {
|
|
416
432
|
VLCMediaPlayerState state = _player.state;
|
|
433
|
+
RCTLogInfo(@"[UnifiedPlayerViewManager] mediaPlayerStateChanged - New State: %d", state); // Added Log
|
|
417
434
|
|
|
418
435
|
// Debug information for video output
|
|
419
436
|
if (state == VLCMediaPlayerStatePlaying) {
|
package/lib/module/index.js
CHANGED
|
@@ -143,6 +143,26 @@ export const UnifiedPlayer = {
|
|
|
143
143
|
console.log('Error calling getDuration:', error instanceof Error ? error.message : String(error));
|
|
144
144
|
return Promise.reject(error);
|
|
145
145
|
}
|
|
146
|
+
},
|
|
147
|
+
/**
|
|
148
|
+
* Capture the current video frame as a base64 encoded image
|
|
149
|
+
* @param viewTag - The tag of the player view
|
|
150
|
+
* @returns Promise resolving to the base64 encoded image string
|
|
151
|
+
*/
|
|
152
|
+
capture: viewTag => {
|
|
153
|
+
try {
|
|
154
|
+
console.log('UnifiedPlayer.capture called with viewTag:', viewTag);
|
|
155
|
+
return UnifiedPlayerModule.capture(viewTag).then(base64String => {
|
|
156
|
+
console.log('Native capture method called successfully');
|
|
157
|
+
return base64String;
|
|
158
|
+
}).catch(error => {
|
|
159
|
+
console.log('Error calling capture:', error instanceof Error ? error.message : String(error));
|
|
160
|
+
throw error;
|
|
161
|
+
});
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.log('Error calling capture:', error instanceof Error ? error.message : String(error));
|
|
164
|
+
return Promise.reject(error);
|
|
165
|
+
}
|
|
146
166
|
}
|
|
147
167
|
};
|
|
148
168
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["forwardRef","requireNativeComponent","UIManager","NativeModules","Platform","jsx","_jsx","LINKING_ERROR","select","ios","default","getViewManagerConfig","UnifiedPlayer","Error","NativeUnifiedPlayerView","UnifiedPlayerModule","UnifiedPlayerEventTypes","LOAD_START","READY","ERROR","PROGRESS","COMPLETE","STALLED","RESUMED","PLAYING","PAUSED","UnifiedPlayerEvents","UnifiedPlayerView","props","ref","play","viewTag","console","log","then","result","catch","error","message","String","Promise","reject","pause","seekTo","time","getCurrentTime","getDuration"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["forwardRef","requireNativeComponent","UIManager","NativeModules","Platform","jsx","_jsx","LINKING_ERROR","select","ios","default","getViewManagerConfig","UnifiedPlayer","Error","NativeUnifiedPlayerView","UnifiedPlayerModule","UnifiedPlayerEventTypes","LOAD_START","READY","ERROR","PROGRESS","COMPLETE","STALLED","RESUMED","PLAYING","PAUSED","UnifiedPlayerEvents","UnifiedPlayerView","props","ref","play","viewTag","console","log","then","result","catch","error","message","String","Promise","reject","pause","seekTo","time","getCurrentTime","getDuration","capture","base64String"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -69,5 +69,11 @@ export declare const UnifiedPlayer: {
|
|
|
69
69
|
* @returns Promise resolving to duration in seconds
|
|
70
70
|
*/
|
|
71
71
|
getDuration: (viewTag: number) => Promise<number>;
|
|
72
|
+
/**
|
|
73
|
+
* Capture the current video frame as a base64 encoded image
|
|
74
|
+
* @param viewTag - The tag of the player view
|
|
75
|
+
* @returns Promise resolving to the base64 encoded image string
|
|
76
|
+
*/
|
|
77
|
+
capture: (viewTag: number) => Promise<string>;
|
|
72
78
|
};
|
|
73
79
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAkBtB,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,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IAGzB,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;IAGvE,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAG/B,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAG/B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAGtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAYF,eAAO,MAAM,uBAAuB;;;;;;;;;;CAUnC,CAAC;AAGF,eAAO,MAAM,mBAAmB,KAA8B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,8LAK5B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB;;;;OAIG;oBACa,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;IAwBzC;;;;OAIG;qBACc,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;IAwB1C;;;;;OAKG;sBACe,MAAM,QAAQ,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;IA6BzD;;;;OAIG;8BACuB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;IAalD;;;;OAIG;2BACoB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAkBtB,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,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IAGzB,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;IAGvE,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAG/B,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAG/B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAGtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAYF,eAAO,MAAM,uBAAuB;;;;;;;;;;CAUnC,CAAC;AAGF,eAAO,MAAM,mBAAmB,KAA8B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,8LAK5B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB;;;;OAIG;oBACa,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;IAwBzC;;;;OAIG;qBACc,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;IAwB1C;;;;;OAKG;sBACe,MAAM,QAAQ,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;IA6BzD;;;;OAIG;8BACuB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;IAalD;;;;OAIG;2BACoB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;IAa/C;;;;OAIG;uBACgB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;CAuB5C,CAAC"}
|
package/package.json
CHANGED
package/src/index.tsx
CHANGED
|
@@ -234,4 +234,33 @@ export const UnifiedPlayer = {
|
|
|
234
234
|
return Promise.reject(error);
|
|
235
235
|
}
|
|
236
236
|
},
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Capture the current video frame as a base64 encoded image
|
|
240
|
+
* @param viewTag - The tag of the player view
|
|
241
|
+
* @returns Promise resolving to the base64 encoded image string
|
|
242
|
+
*/
|
|
243
|
+
capture: (viewTag: number): Promise<string> => {
|
|
244
|
+
try {
|
|
245
|
+
console.log('UnifiedPlayer.capture called with viewTag:', viewTag);
|
|
246
|
+
return UnifiedPlayerModule.capture(viewTag)
|
|
247
|
+
.then((base64String: string) => {
|
|
248
|
+
console.log('Native capture method called successfully');
|
|
249
|
+
return base64String;
|
|
250
|
+
})
|
|
251
|
+
.catch((error: any) => {
|
|
252
|
+
console.log(
|
|
253
|
+
'Error calling capture:',
|
|
254
|
+
error instanceof Error ? error.message : String(error)
|
|
255
|
+
);
|
|
256
|
+
throw error;
|
|
257
|
+
});
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.log(
|
|
260
|
+
'Error calling capture:',
|
|
261
|
+
error instanceof Error ? error.message : String(error)
|
|
262
|
+
);
|
|
263
|
+
return Promise.reject(error);
|
|
264
|
+
}
|
|
265
|
+
},
|
|
237
266
|
};
|