react-native-unified-player 0.3.0 → 0.3.2

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.
@@ -9,7 +9,7 @@ buildscript {
9
9
  }
10
10
 
11
11
  dependencies {
12
- classpath "com.android.tools.build:gradle:7.3.1"
12
+ classpath "com.android.tools.build:gradle:8.1.0"
13
13
  // noinspection DifferentKotlinGradleVersion
14
14
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0"
15
15
  }
@@ -68,6 +68,7 @@ android {
68
68
  repositories {
69
69
  mavenCentral()
70
70
  google()
71
+ maven { url "$rootDir/../node_modules/react-native/android" }
71
72
  }
72
73
 
73
74
  def kotlin_version = getExtOrDefault("kotlinVersion")
@@ -3,3 +3,4 @@ UnifiedPlayer_minSdkVersion=24
3
3
  UnifiedPlayer_targetSdkVersion=34
4
4
  UnifiedPlayer_compileSdkVersion=35
5
5
  UnifiedPlayer_ndkVersion=27.1.12297006
6
+ android.useAndroidX=true
@@ -6,89 +6,166 @@ import com.facebook.react.bridge.ReactMethod
6
6
  import com.facebook.react.bridge.Promise
7
7
  import com.facebook.react.uimanager.UIManagerModule
8
8
  import android.util.Log
9
+ import com.facebook.react.bridge.UiThreadUtil
10
+ import android.view.View
9
11
 
10
12
  class UnifiedPlayerModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
11
13
  companion object {
12
14
  private const val TAG = "UnifiedPlayerModule"
13
15
  }
14
16
 
17
+ init {
18
+ Log.d(TAG, "UnifiedPlayerModule initialized")
19
+ }
20
+
15
21
  override fun getName(): String {
22
+ Log.d(TAG, "getName() called, returning 'UnifiedPlayer'")
16
23
  return "UnifiedPlayer"
17
24
  }
18
25
 
19
- private fun getPlayerView(viewId: Int): UnifiedPlayerView? {
20
- val uiManager = reactContext.getNativeModule(UIManagerModule::class.java)
21
- val view = uiManager?.resolveView(viewId) as? UnifiedPlayerView
22
-
23
- if (view == null) {
24
- Log.e(TAG, "Unable to find UnifiedPlayerView with id $viewId")
26
+ private fun getPlayerViewByTag(viewTag: Int): UnifiedPlayerView? {
27
+ try {
28
+ val view = reactApplicationContext.currentActivity?.findViewById<View>(viewTag)
29
+ Log.d(TAG, "Looking for view with tag: $viewTag, found: ${view != null}")
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}")
35
+ }
36
+ } catch (e: Exception) {
37
+ Log.e(TAG, "Error finding view with tag $viewTag: ${e.message}", e)
25
38
  }
26
-
27
- return view
39
+ return null
28
40
  }
29
41
 
30
42
  @ReactMethod
31
- fun play(viewId: Int) {
43
+ fun play(viewTag: Int, promise: Promise) {
44
+ Log.d(TAG, "Native play method called with viewTag: $viewTag")
32
45
  try {
33
- Log.d(TAG, "Play command received for view $viewId")
34
- reactContext.runOnUiQueueThread {
35
- getPlayerView(viewId)?.play()
46
+ val playerView = getPlayerViewByTag(viewTag)
47
+ if (playerView != null) {
48
+ UiThreadUtil.runOnUiThread {
49
+ try {
50
+ playerView.play()
51
+ Log.d(TAG, "Play command executed successfully")
52
+ promise.resolve(true)
53
+ } catch (e: Exception) {
54
+ Log.e(TAG, "Error during play: ${e.message}", e)
55
+ promise.reject("PLAY_ERROR", "Error during play: ${e.message}", e)
56
+ }
57
+ }
58
+ } else {
59
+ Log.e(TAG, "Player view not found for tag: $viewTag")
60
+ promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
36
61
  }
37
62
  } catch (e: Exception) {
38
- Log.e(TAG, "Error playing video: ${e.message}")
63
+ Log.e(TAG, "Error in play method: ${e.message}", e)
64
+ promise.reject("PLAY_ERROR", "Error in play method: ${e.message}", e)
39
65
  }
40
66
  }
41
-
67
+
42
68
  @ReactMethod
43
- fun pause(viewId: Int) {
69
+ fun pause(viewTag: Int, promise: Promise) {
70
+ Log.d(TAG, "Native pause method called with viewTag: $viewTag")
44
71
  try {
45
- Log.d(TAG, "pause called in module for viewId: $viewId") // Add this log
46
- Log.d(TAG, "Pause command received for view $viewId")
47
- reactContext.runOnUiQueueThread {
48
- getPlayerView(viewId)?.pause()
72
+ val playerView = getPlayerViewByTag(viewTag)
73
+ if (playerView != null) {
74
+ UiThreadUtil.runOnUiThread {
75
+ try {
76
+ playerView.pause()
77
+ Log.d(TAG, "Pause command executed successfully")
78
+ promise.resolve(true)
79
+ } catch (e: Exception) {
80
+ Log.e(TAG, "Error during pause: ${e.message}", e)
81
+ promise.reject("PAUSE_ERROR", "Error during pause: ${e.message}", e)
82
+ }
83
+ }
84
+ } else {
85
+ Log.e(TAG, "Player view not found for tag: $viewTag")
86
+ promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
49
87
  }
50
88
  } catch (e: Exception) {
51
- Log.e(TAG, "Error pausing video: ${e.message}")
89
+ Log.e(TAG, "Error in pause method: ${e.message}", e)
90
+ promise.reject("PAUSE_ERROR", "Error in pause method: ${e.message}", e)
52
91
  }
53
92
  }
54
-
93
+
55
94
  @ReactMethod
56
- fun seekTo(viewId: Int, time: Float) {
95
+ fun seekTo(viewTag: Int, seconds: Float, promise: Promise) {
96
+ Log.d(TAG, "Native seekTo method called with viewTag: $viewTag, seconds: $seconds")
57
97
  try {
58
- Log.d(TAG, "Seek command received for view $viewId to time $time")
59
- reactContext.runOnUiQueueThread {
60
- getPlayerView(viewId)?.seekTo(time)
98
+ val playerView = getPlayerViewByTag(viewTag)
99
+ if (playerView != null) {
100
+ UiThreadUtil.runOnUiThread {
101
+ try {
102
+ playerView.seekTo(seconds)
103
+ Log.d(TAG, "SeekTo command executed successfully to $seconds seconds")
104
+ promise.resolve(true)
105
+ } catch (e: Exception) {
106
+ Log.e(TAG, "Error during seekTo: ${e.message}", e)
107
+ promise.reject("SEEK_ERROR", "Error during seekTo: ${e.message}", e)
108
+ }
109
+ }
110
+ } else {
111
+ Log.e(TAG, "Player view not found for tag: $viewTag")
112
+ promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
61
113
  }
62
114
  } catch (e: Exception) {
63
- Log.e(TAG, "Error seeking: ${e.message}")
115
+ Log.e(TAG, "Error in seekTo method: ${e.message}", e)
116
+ promise.reject("SEEK_ERROR", "Error in seekTo method: ${e.message}", e)
64
117
  }
65
118
  }
66
-
119
+
67
120
  @ReactMethod
68
- fun getCurrentTime(viewId: Int, promise: Promise) {
121
+ fun getCurrentTime(viewTag: Int, promise: Promise) {
122
+ Log.d(TAG, "Native getCurrentTime method called with viewTag: $viewTag")
69
123
  try {
70
- Log.d(TAG, "Get current time for view $viewId")
71
- reactContext.runOnUiQueueThread {
72
- val time = getPlayerView(viewId)?.getCurrentTime() ?: 0f
73
- promise.resolve(time)
124
+ val playerView = getPlayerViewByTag(viewTag)
125
+ if (playerView != null) {
126
+ UiThreadUtil.runOnUiThread {
127
+ try {
128
+ val currentTime = playerView.getCurrentTime()
129
+ Log.d(TAG, "getCurrentTime executed successfully, current time: $currentTime")
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)
134
+ }
135
+ }
136
+ } else {
137
+ Log.e(TAG, "Player view not found for tag: $viewTag")
138
+ promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
74
139
  }
75
140
  } catch (e: Exception) {
76
- Log.e(TAG, "Error getting current time: ${e.message}")
77
- promise.reject("ERROR", "Failed to get current time: ${e.message}")
141
+ Log.e(TAG, "Error in getCurrentTime method: ${e.message}", e)
142
+ promise.reject("GET_TIME_ERROR", "Error in getCurrentTime method: ${e.message}", e)
78
143
  }
79
144
  }
80
-
145
+
81
146
  @ReactMethod
82
- fun getDuration(viewId: Int, promise: Promise) {
147
+ fun getDuration(viewTag: Int, promise: Promise) {
148
+ Log.d(TAG, "Native getDuration method called with viewTag: $viewTag")
83
149
  try {
84
- Log.d(TAG, "Get duration for view $viewId")
85
- reactContext.runOnUiQueueThread {
86
- val duration = getPlayerView(viewId)?.getDuration() ?: 0f
87
- promise.resolve(duration)
150
+ val playerView = getPlayerViewByTag(viewTag)
151
+ if (playerView != null) {
152
+ UiThreadUtil.runOnUiThread {
153
+ try {
154
+ val duration = playerView.getDuration()
155
+ Log.d(TAG, "getDuration executed successfully, duration: $duration")
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)
160
+ }
161
+ }
162
+ } else {
163
+ Log.e(TAG, "Player view not found for tag: $viewTag")
164
+ promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
88
165
  }
89
166
  } catch (e: Exception) {
90
- Log.e(TAG, "Error getting duration: ${e.message}")
91
- promise.reject("ERROR", "Failed to get duration: ${e.message}")
167
+ Log.e(TAG, "Error in getDuration method: ${e.message}", e)
168
+ promise.reject("GET_DURATION_ERROR", "Error in getDuration method: ${e.message}", e)
92
169
  }
93
170
  }
94
171
 
@@ -4,17 +4,20 @@ import com.facebook.react.ReactPackage
4
4
  import com.facebook.react.bridge.NativeModule
5
5
  import com.facebook.react.bridge.ReactApplicationContext
6
6
  import com.facebook.react.uimanager.ViewManager
7
-
7
+ import android.util.Log
8
8
 
9
9
  class UnifiedPlayerPackage : ReactPackage {
10
+ private val TAG = "UnifiedPlayerPackage"
11
+
10
12
  override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
13
+ Log.d(TAG, "Creating native modules")
11
14
  return listOf(
12
- UnifiedPlayerModule(reactContext),
13
- UnifiedPlayerEventEmitter(reactContext)
15
+ UnifiedPlayerModule(reactContext)
14
16
  )
15
17
  }
16
18
 
17
19
  override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
20
+ Log.d(TAG, "Creating view managers")
18
21
  return listOf(UnifiedPlayerViewManager())
19
22
  }
20
23
  }
@@ -13,11 +13,12 @@ import com.google.android.exoplayer2.ExoPlayer
13
13
  import com.google.android.exoplayer2.MediaItem
14
14
  import com.google.android.exoplayer2.Player
15
15
  import com.google.android.exoplayer2.PlaybackException
16
- import com.google.android.exoplayer2.Timeline
17
16
  import com.google.android.exoplayer2.Tracks
18
17
  import com.google.android.exoplayer2.ui.PlayerView
19
18
  import com.google.android.exoplayer2.video.VideoSize
20
19
  import com.facebook.react.bridge.WritableMap
20
+ import com.facebook.react.bridge.ReactContext
21
+ import com.facebook.react.uimanager.events.RCTEventEmitter
21
22
 
22
23
  class UnifiedPlayerView(context: Context) : FrameLayout(context) {
23
24
  companion object {
@@ -25,12 +26,12 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
25
26
  }
26
27
 
27
28
  private var videoUrl: String? = null
28
- private var authToken: String? = null
29
29
  private var autoplay: Boolean = true
30
30
  private var loop: Boolean = false
31
31
  private var playerView: PlayerView
32
32
  private var player: ExoPlayer? = null
33
33
  private var currentProgress = 0
34
+ private var isPaused = false
34
35
 
35
36
  private val progressHandler = Handler(Looper.getMainLooper())
36
37
  private val progressRunnable: Runnable = object : Runnable {
@@ -39,14 +40,22 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
39
40
  val currentTime = it.currentPosition.toFloat() / 1000f
40
41
  val duration = it.duration.toFloat() / 1000f
41
42
 
42
- if (duration > 0) {
43
- val event = Arguments.createMap().apply {
44
- putDouble("currentTime", currentTime.toDouble())
45
- putDouble("duration", duration.toDouble())
46
- }
47
- sendEvent(UnifiedPlayerEventEmitter.EVENT_PROGRESS, event)
43
+ // Log the actual values for debugging
44
+ Log.d(TAG, "Progress values - currentTime: $currentTime, duration: $duration, raw duration: ${it.duration}")
45
+
46
+ // Only send valid duration values
47
+ if (it.duration > 0) {
48
+ val event = Arguments.createMap()
49
+ event.putDouble("currentTime", currentTime.toDouble())
50
+ event.putDouble("duration", duration.toDouble())
51
+
52
+ Log.d(TAG, "Sending progress event: currentTime=$currentTime, duration=$duration")
53
+ sendEvent("topProgress", event)
54
+ } else {
55
+ Log.d(TAG, "Not sending progress event because duration is $duration (raw: ${it.duration})")
48
56
  }
49
- }
57
+ } ?: Log.e(TAG, "Cannot send progress event: player is null")
58
+
50
59
  // Schedule the next update
51
60
  progressHandler.postDelayed(this, 250) // Update every 250ms
52
61
  }
@@ -80,11 +89,11 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
80
89
  when (playbackState) {
81
90
  Player.STATE_READY -> {
82
91
  Log.d(TAG, "ExoPlayer STATE_READY")
83
- sendEvent("onReadyToPlay", Arguments.createMap())
92
+ sendEvent("topReadyToPlay", Arguments.createMap())
84
93
  }
85
94
  Player.STATE_ENDED -> {
86
95
  Log.d(TAG, "ExoPlayer STATE_ENDED")
87
- sendEvent("onPlaybackComplete", Arguments.createMap())
96
+ sendEvent("topPlaybackComplete", Arguments.createMap())
88
97
  }
89
98
  Player.STATE_BUFFERING -> {
90
99
  Log.d(TAG, "ExoPlayer STATE_BUFFERING")
@@ -92,34 +101,33 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
92
101
  Player.STATE_IDLE -> {
93
102
  Log.d(TAG, "ExoPlayer STATE_IDLE")
94
103
  }
95
- Player.STATE_BUFFERING -> {
96
- Log.d(TAG, "ExoPlayer STATE_BUFFERING")
97
- }
98
104
  }
99
105
  }
100
106
 
101
107
  override fun onIsPlayingChanged(isPlaying: Boolean) {
108
+ Log.d(TAG, "onIsPlayingChanged: $isPlaying")
102
109
  if (isPlaying) {
103
110
  Log.d(TAG, "ExoPlayer isPlaying")
104
- sendEvent("onPlay", Arguments.createMap())
111
+ // Use the defined event constant for playback resumed
112
+ sendEvent("topPlaybackResumed", Arguments.createMap())
105
113
  } else {
106
114
  Log.d(TAG, "ExoPlayer isPaused")
107
- sendEvent("onPause", Arguments.createMap())
115
+ // Add event emission for pause state
116
+ sendEvent("topPlaybackPaused", Arguments.createMap())
108
117
  }
109
118
  }
110
119
 
111
120
  override fun onPlayerError(error: PlaybackException) {
112
- Log.e(TAG, "ExoPlayer Error: ${error.message}, errorCode: ${error.errorCodeName}, errorCode বিস্তারিত: ${error.errorCode}")
121
+ Log.d(TAG, "ExoPlayer onPlayerError: ${error.message}")
113
122
  val event = Arguments.createMap().apply {
114
- putInt("code", error.errorCode)
115
- putString("message", error.message)
123
+ putString("error", error.message)
116
124
  }
117
- sendEvent("onError", event)
125
+ sendEvent("topError", event)
118
126
  }
119
127
 
120
128
  override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
121
129
  Log.d(TAG, "ExoPlayer onMediaItemTransition")
122
- sendEvent("onLoadStart", Arguments.createMap())
130
+ sendEvent("topLoadStart", Arguments.createMap())
123
131
  }
124
132
 
125
133
  override fun onPlaybackSuppressionReasonChanged(playbackSuppressionReason: Int) {
@@ -177,39 +185,67 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
177
185
  // Called when skip silence is enabled or disabled.
178
186
  Log.d(TAG, "ExoPlayer onSkipSilenceEnabledChanged: skipSilenceEnabled=$skipSilenceEnabled")
179
187
  }
180
-
181
- override fun onTimelineChanged(timeline: Timeline, reason: Int) {
182
- // Called when the timeline changes, like when a new media source is loaded or an ad break starts or ends.
183
- Log.d(TAG, "ExoPlayer onTimelineChanged: timeline=$timeline, reason=$reason")
184
- }
185
188
  })
186
189
  }
187
190
 
188
191
  fun setVideoUrl(url: String?) {
189
192
  Log.d(TAG, "Setting video URL: $url")
190
- if (url.isNullOrEmpty()) {
191
- Log.d(TAG, "Video URL is null or empty, skipping load")
193
+
194
+ if (url == null || url.isEmpty()) {
195
+ Log.e(TAG, "Empty or null URL provided")
192
196
  return
193
197
  }
194
-
198
+
195
199
  videoUrl = url
196
-
197
-
198
- // Load video with ExoPlayer
199
- Log.d(TAG, "Creating MediaItem from URI: $videoUrl")
200
- val mediaItem = MediaItem.fromUri(videoUrl!!)
201
- player?.setMediaItem(mediaItem)
202
- Log.d(TAG, "Preparing ExoPlayer")
203
- player?.prepare()
204
- Log.d(TAG, "ExoPlayer prepared")
200
+
201
+ try {
202
+ // Create a MediaItem
203
+ val mediaItem = MediaItem.fromUri(url)
204
+
205
+ // Reset the player to ensure clean state
206
+ player?.stop()
207
+ player?.clearMediaItems()
208
+
209
+ // Set the media item
210
+ player?.setMediaItem(mediaItem)
211
+
212
+ // Prepare the player (this will start loading the media)
213
+ player?.prepare()
214
+
215
+ // Set playWhenReady based on autoplay setting
216
+ player?.playWhenReady = autoplay && !isPaused
217
+
218
+ // Set repeat mode based on loop setting
219
+ player?.repeatMode = if (loop) Player.REPEAT_MODE_ALL else Player.REPEAT_MODE_OFF
220
+
221
+ // Log that we've set up the player
222
+ Log.d(TAG, "ExoPlayer configured with URL: $url, autoplay: $autoplay, loop: $loop")
223
+
224
+ // Add a listener to check when the player is ready and has duration
225
+ player?.addListener(object : Player.Listener {
226
+ override fun onPlaybackStateChanged(state: Int) {
227
+ if (state == Player.STATE_READY) {
228
+ val duration = player?.duration ?: 0
229
+ Log.d(TAG, "Player ready with duration: ${duration / 1000f} seconds")
230
+
231
+ // Force a progress update immediately
232
+ progressRunnable.run()
233
+ }
234
+ }
235
+ })
236
+ } catch (e: Exception) {
237
+ Log.e(TAG, "Error setting video URL: ${e.message}", e)
238
+
239
+ // Send error event
240
+ val event = Arguments.createMap()
241
+ event.putString("error", "Failed to load video: ${e.message}")
242
+ sendEvent("topError", event)
243
+ }
205
244
  }
206
245
 
207
246
  fun setAuthToken(token: String?) {
208
- authToken = token
209
- // If URL already set, reload with new token
210
- if (!videoUrl.isNullOrEmpty()) {
211
- setVideoUrl(videoUrl) // reload video
212
- }
247
+ // Removed as per request
248
+ Log.d(TAG, "Auth token handling removed")
213
249
  }
214
250
 
215
251
  fun setAutoplay(value: Boolean) {
@@ -224,6 +260,7 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
224
260
 
225
261
  fun setIsPaused(isPaused: Boolean) {
226
262
  Log.d(TAG, "setIsPaused called with value: $isPaused")
263
+ this.isPaused = isPaused
227
264
  if (isPaused) {
228
265
  player?.pause()
229
266
  } else {
@@ -232,30 +269,76 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
232
269
  }
233
270
 
234
271
  fun play() {
235
- Log.d(TAG, "Play called")
236
- player?.play()
272
+ Log.d(TAG, "Play method called")
273
+ player?.playWhenReady = true
237
274
  }
238
275
 
239
276
  fun pause() {
240
- Log.d(TAG, "Pause called from module") // Add this log
241
- player?.pause()
277
+ Log.d(TAG, "Pause method called")
278
+ player?.playWhenReady = false
242
279
  }
243
280
 
244
- fun seekTo(time: Float) {
245
- Log.d(TAG, "Seek called: $time")
246
- player?.seekTo((time * 1000).toLong()) // time in seconds, ExoPlayer in milliseconds
281
+ fun seekTo(seconds: Float) {
282
+ Log.d(TAG, "SeekTo method called with seconds: $seconds")
283
+ player?.let {
284
+ val milliseconds = (seconds * 1000).toLong()
285
+ Log.d(TAG, "Seeking to $milliseconds ms")
286
+ it.seekTo(milliseconds)
287
+
288
+ // Force a progress update after seeking
289
+ progressRunnable.run()
290
+ } ?: Log.e(TAG, "Cannot seek: player is null")
247
291
  }
248
292
 
249
293
  fun getCurrentTime(): Float {
250
- return (player?.currentPosition?.toFloat() ?: 0f) / 1000f // to seconds
294
+ Log.d(TAG, "GetCurrentTime method called")
295
+ return player?.let {
296
+ val currentTime = it.currentPosition.toFloat() / 1000f
297
+ Log.d(TAG, "Current time: $currentTime seconds")
298
+ currentTime
299
+ } ?: run {
300
+ Log.e(TAG, "Cannot get current time: player is null")
301
+ 0f
302
+ }
251
303
  }
252
304
 
253
305
  fun getDuration(): Float {
254
- return (player?.duration?.toFloat() ?: 0f) / 1000f // to seconds
306
+ Log.d(TAG, "GetDuration method called")
307
+ return player?.let {
308
+ val duration = it.duration.toFloat() / 1000f
309
+ Log.d(TAG, "Duration: $duration seconds (raw: ${it.duration})")
310
+ if (it.duration > 0) duration else 0f
311
+ } ?: run {
312
+ Log.e(TAG, "Cannot get duration: player is null")
313
+ 0f
314
+ }
255
315
  }
256
316
 
317
+ // Add a getter for the ExoPlayer instance
318
+ val exoPlayer: ExoPlayer?
319
+ get() = this.player
320
+
257
321
  private fun sendEvent(eventName: String, params: WritableMap) {
258
- UnifiedPlayerEventEmitter.getInstance()?.sendEvent(eventName, params)
322
+ try {
323
+ // Log the event for debugging
324
+ Log.d(TAG, "Sending direct event: $eventName with params: $params")
325
+
326
+ // Use the ReactContext to dispatch the event directly to the view
327
+ val reactContext = context as ReactContext
328
+ reactContext.getJSModule(RCTEventEmitter::class.java)
329
+ .receiveEvent(id, eventName, params)
330
+ } catch (e: Exception) {
331
+ Log.e(TAG, "Error sending event $eventName: ${e.message}", e)
332
+ }
333
+ }
334
+
335
+ // Add a method to explicitly start progress updates
336
+ private fun startProgressUpdates() {
337
+ Log.d(TAG, "Starting progress updates")
338
+ // Remove any existing callbacks to avoid duplicates
339
+ progressHandler.removeCallbacks(progressRunnable)
340
+ // Post the runnable to start updates
341
+ progressHandler.post(progressRunnable)
259
342
  }
260
343
 
261
344
  override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
@@ -271,7 +354,7 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
271
354
  super.onAttachedToWindow()
272
355
  Log.d(TAG, "UnifiedPlayerView onAttachedToWindow")
273
356
  playerView.setPlayer(player)
274
- progressHandler.post(progressRunnable) // Start progress updates
357
+ startProgressUpdates() // Use the new method to start progress updates
275
358
  }
276
359
 
277
360
  override fun onDetachedFromWindow() {
@@ -3,11 +3,18 @@ package com.unifiedplayer
3
3
  import com.facebook.react.uimanager.SimpleViewManager
4
4
  import com.facebook.react.uimanager.ThemedReactContext
5
5
  import com.facebook.react.uimanager.annotations.ReactProp
6
+ import com.facebook.react.common.MapBuilder
7
+ import android.util.Log
8
+ import com.facebook.react.bridge.ReadableArray
9
+ import com.facebook.react.uimanager.events.RCTEventEmitter
6
10
 
7
11
  class UnifiedPlayerViewManager : SimpleViewManager<UnifiedPlayerView>() {
12
+ private val TAG = "UnifiedPlayerViewManager"
13
+
8
14
  override fun getName() = "UnifiedPlayerView"
9
15
 
10
16
  override fun createViewInstance(reactContext: ThemedReactContext): UnifiedPlayerView {
17
+ Log.d(TAG, "Creating UnifiedPlayerView instance")
11
18
  return UnifiedPlayerView(reactContext)
12
19
  }
13
20
 
@@ -16,11 +23,6 @@ class UnifiedPlayerViewManager : SimpleViewManager<UnifiedPlayerView>() {
16
23
  view.setVideoUrl(url)
17
24
  }
18
25
 
19
- @ReactProp(name = "authToken")
20
- fun setAuthToken(view: UnifiedPlayerView, token: String?) {
21
- view.setAuthToken(token)
22
- }
23
-
24
26
  @ReactProp(name = "autoplay")
25
27
  fun setAutoplay(view: UnifiedPlayerView, autoplay: Boolean) {
26
28
  view.setAutoplay(autoplay)
@@ -35,4 +37,20 @@ class UnifiedPlayerViewManager : SimpleViewManager<UnifiedPlayerView>() {
35
37
  fun setIsPaused(view: UnifiedPlayerView, isPaused: Boolean) {
36
38
  view.setIsPaused(isPaused)
37
39
  }
40
+
41
+ // Register direct events
42
+ override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {
43
+ Log.d(TAG, "Registering direct events")
44
+
45
+ // Create a map of event names to their registration names
46
+ return MapBuilder.builder<String, Any>()
47
+ .put("topReadyToPlay", MapBuilder.of("registrationName", "onReadyToPlay"))
48
+ .put("topError", MapBuilder.of("registrationName", "onError"))
49
+ .put("topProgress", MapBuilder.of("registrationName", "onProgress"))
50
+ .put("topPlaybackComplete", MapBuilder.of("registrationName", "onPlaybackComplete"))
51
+ .put("topPlaybackResumed", MapBuilder.of("registrationName", "onPlaybackResumed"))
52
+ .put("topPlaybackPaused", MapBuilder.of("registrationName", "onPlaybackPaused"))
53
+ .put("topLoadStart", MapBuilder.of("registrationName", "onLoadStart"))
54
+ .build()
55
+ }
38
56
  }
@@ -1,31 +1,39 @@
1
1
  "use strict";
2
2
 
3
3
  import { forwardRef } from 'react'; // Import from 'react'
4
- import { requireNativeComponent, UIManager, Platform, NativeModules, NativeEventEmitter } from 'react-native'; // Import from 'react-native'
4
+ import { requireNativeComponent, UIManager, NativeModules, Platform } from 'react-native';
5
+
6
+ // Check if the native module is available
5
7
  import { jsx as _jsx } from "react/jsx-runtime";
6
8
  const LINKING_ERROR = `The package 'react-native-unified-player' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
7
9
  ios: "- You have run 'pod install'\n",
8
10
  default: ''
9
11
  }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
10
12
 
11
- /**
12
- * Props for the UnifiedPlayerView component
13
- */
13
+ // Verify the native module exists
14
+ if (!UIManager.getViewManagerConfig('UnifiedPlayerView') && !NativeModules.UnifiedPlayer) {
15
+ throw new Error(LINKING_ERROR);
16
+ }
14
17
 
15
- // Name of the native component
16
- const ComponentName = 'UnifiedPlayerView';
18
+ // Define the props for the UnifiedPlayerView component
17
19
 
18
- // Props for the native component including ref
20
+ // Native component registration
21
+ const NativeUnifiedPlayerView = requireNativeComponent('UnifiedPlayerView');
19
22
 
20
- // Native component import
21
- const NativeUnifiedPlayerView = UIManager.getViewManagerConfig(ComponentName) != null ? requireNativeComponent(ComponentName) : () => {
22
- throw new Error(LINKING_ERROR);
23
- };
23
+ // Newline added here
24
+
25
+ // Native module for player control methods
26
+ const UnifiedPlayerModule = NativeModules.UnifiedPlayer;
24
27
 
25
- // Native module for additional control methods
26
- const UnifiedPlayerModule = NativeModules.UnifiedPlayerModule;
27
- // Native module for events
28
- const UnifiedPlayerEventEmitterModule = NativeModules.UnifiedPlayerEvents;
28
+ // Export event types for reference
29
+ export const UnifiedPlayerEventTypes = {
30
+ READY: 'onReadyToPlay',
31
+ ERROR: 'onError',
32
+ PROGRESS: 'onProgress',
33
+ COMPLETE: 'onPlaybackComplete',
34
+ STALLED: 'onPlaybackStalled',
35
+ RESUMED: 'onPlaybackResumed'
36
+ };
29
37
 
30
38
  /**
31
39
  * UnifiedPlayerView component for video playback
@@ -41,69 +49,73 @@ export const UnifiedPlayerView = /*#__PURE__*/forwardRef((props, ref) => {
41
49
  * API methods for controlling playback
42
50
  */
43
51
  export const UnifiedPlayer = {
44
- // Play the video
52
+ /**
53
+ * Start playback
54
+ * @param viewTag - The tag of the player view
55
+ */
45
56
  play: viewTag => {
46
- if (UnifiedPlayerModule?.play) {
57
+ try {
58
+ console.log('UnifiedPlayer.play called with viewTag:', viewTag);
47
59
  UnifiedPlayerModule.play(viewTag);
60
+ console.log('Native play method called successfully');
61
+ } catch (error) {
62
+ console.log('Error calling play:', error instanceof Error ? error.message : String(error));
48
63
  }
49
64
  },
50
- // Pause the video
65
+ /**
66
+ * Pause playback
67
+ * @param viewTag - The tag of the player view
68
+ */
51
69
  pause: viewTag => {
52
- if (UnifiedPlayerModule?.pause) {
70
+ try {
71
+ console.log('UnifiedPlayer.pause called with viewTag:', viewTag);
53
72
  UnifiedPlayerModule.pause(viewTag);
73
+ console.log('Native pause method called successfully');
74
+ } catch (error) {
75
+ console.log('Error calling pause:', error instanceof Error ? error.message : String(error));
54
76
  }
55
77
  },
56
- // Seek to a specific time
78
+ /**
79
+ * Seek to a specific time
80
+ * @param viewTag - The tag of the player view
81
+ * @param time - Time in seconds to seek to
82
+ */
57
83
  seekTo: (viewTag, time) => {
58
- if (UnifiedPlayerModule?.seekTo) {
84
+ try {
85
+ console.log('UnifiedPlayer.seekTo called with viewTag:', viewTag, 'time:', time);
59
86
  UnifiedPlayerModule.seekTo(viewTag, time);
87
+ console.log('Native seekTo method called successfully');
88
+ } catch (error) {
89
+ console.log('Error calling seekTo:', error instanceof Error ? error.message : String(error));
60
90
  }
61
91
  },
62
- // Get the current playback time
92
+ /**
93
+ * Get current playback time
94
+ * @param viewTag - The tag of the player view
95
+ * @returns Promise resolving to current time in seconds
96
+ */
63
97
  getCurrentTime: viewTag => {
64
- if (UnifiedPlayerModule?.getCurrentTime) {
98
+ try {
99
+ console.log('UnifiedPlayer.getCurrentTime called with viewTag:', viewTag);
65
100
  return UnifiedPlayerModule.getCurrentTime(viewTag);
101
+ } catch (error) {
102
+ console.log('Error calling getCurrentTime:', error instanceof Error ? error.message : String(error));
103
+ return Promise.reject(error);
66
104
  }
67
- return Promise.resolve(0);
68
105
  },
69
- // Get the duration of the video
106
+ /**
107
+ * Get video duration
108
+ * @param viewTag - The tag of the player view
109
+ * @returns Promise resolving to duration in seconds
110
+ */
70
111
  getDuration: viewTag => {
71
- if (UnifiedPlayerModule?.getDuration) {
112
+ try {
113
+ console.log('UnifiedPlayer.getDuration called with viewTag:', viewTag);
72
114
  return UnifiedPlayerModule.getDuration(viewTag);
115
+ } catch (error) {
116
+ console.log('Error calling getDuration:', error instanceof Error ? error.message : String(error));
117
+ return Promise.reject(error);
73
118
  }
74
- return Promise.resolve(0);
75
- },
76
- // Test method
77
- testMethod: message => {
78
- if (UnifiedPlayerModule?.testMethod) {
79
- UnifiedPlayerModule.testMethod(message);
80
- }
81
- }
82
- };
83
-
84
- // Events emitter for native events
85
- let eventEmitter = null;
86
- if (UnifiedPlayerEventEmitterModule) {
87
- eventEmitter = new NativeEventEmitter(UnifiedPlayerEventEmitterModule);
88
- }
89
- export const UnifiedPlayerEvents = {
90
- addListener: (eventType, listener) => {
91
- if (eventEmitter) {
92
- return eventEmitter.addListener(eventType, listener);
93
- }
94
- return {
95
- remove: () => {}
96
- };
97
119
  }
98
120
  };
99
-
100
- // Event names
101
- export const UnifiedPlayerEventTypes = {
102
- READY: 'onReadyToPlay',
103
- ERROR: 'onError',
104
- PROGRESS: 'onProgress',
105
- COMPLETE: 'onPlaybackComplete',
106
- STALLED: 'onPlaybackStalled',
107
- RESUMED: 'onPlaybackResumed'
108
- };
109
121
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","requireNativeComponent","UIManager","Platform","NativeModules","NativeEventEmitter","jsx","_jsx","LINKING_ERROR","select","ios","default","ComponentName","NativeUnifiedPlayerView","getViewManagerConfig","Error","UnifiedPlayerModule","UnifiedPlayerEventEmitterModule","UnifiedPlayerEvents","UnifiedPlayerView","props","ref","UnifiedPlayer","play","viewTag","pause","seekTo","time","getCurrentTime","Promise","resolve","getDuration","testMethod","message","eventEmitter","addListener","eventType","listener","remove","UnifiedPlayerEventTypes","READY","ERROR","PROGRESS","COMPLETE","STALLED","RESUMED"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAAoCA,UAAU,QAAQ,OAAO,CAAC,CAAC;AAC/D,SACEC,sBAAsB,EACtBC,SAAS,EACTC,QAAQ,EAERC,aAAa,EACbC,kBAAkB,QACb,cAAc,CAAC,CAAC;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAEvB,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;;AAiCA;AACA,MAAMC,aAAa,GAAG,mBAAmB;;AAEzC;;AAKA;AACA,MAAMC,uBAAuB,GAC3BX,SAAS,CAACY,oBAAoB,CAACF,aAAa,CAAC,IAAI,IAAI,GACjDX,sBAAsB,CAA+BW,aAAa,CAAC,GACnE,MAAM;EACJ,MAAM,IAAIG,KAAK,CAACP,aAAa,CAAC;AAChC,CAAC;;AAEP;AACA,MAAMQ,mBAAmB,GAAGZ,aAAa,CAACY,mBAAmB;AAC7D;AACA,MAAMC,+BAA+B,GAAGb,aAAa,CAACc,mBAAmB;;AAEzE;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,gBAAGnB,UAAU,CAGzC,CAACoB,KAAK,EAAEC,GAAG,KAAK;EAChB,oBAAOd,IAAA,CAACM,uBAAuB;IAAA,GAAKO,KAAK;IAAEC,GAAG,EAAEA;EAAI,CAAE,CAAC;AACzD,CAAC,CAAC;;AAEF;AACA;AACA;AACA,OAAO,MAAMC,aAAa,GAAG;EAC3B;EACAC,IAAI,EAAGC,OAAe,IAAK;IACzB,IAAIR,mBAAmB,EAAEO,IAAI,EAAE;MAC7BP,mBAAmB,CAACO,IAAI,CAACC,OAAO,CAAC;IACnC;EACF,CAAC;EAED;EACAC,KAAK,EAAGD,OAAe,IAAK;IAC1B,IAAIR,mBAAmB,EAAES,KAAK,EAAE;MAC9BT,mBAAmB,CAACS,KAAK,CAACD,OAAO,CAAC;IACpC;EACF,CAAC;EAED;EACAE,MAAM,EAAEA,CAACF,OAAe,EAAEG,IAAY,KAAK;IACzC,IAAIX,mBAAmB,EAAEU,MAAM,EAAE;MAC/BV,mBAAmB,CAACU,MAAM,CAACF,OAAO,EAAEG,IAAI,CAAC;IAC3C;EACF,CAAC;EAED;EACAC,cAAc,EAAGJ,OAAe,IAAsB;IACpD,IAAIR,mBAAmB,EAAEY,cAAc,EAAE;MACvC,OAAOZ,mBAAmB,CAACY,cAAc,CAACJ,OAAO,CAAC;IACpD;IACA,OAAOK,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAC3B,CAAC;EAED;EACAC,WAAW,EAAGP,OAAe,IAAsB;IACjD,IAAIR,mBAAmB,EAAEe,WAAW,EAAE;MACpC,OAAOf,mBAAmB,CAACe,WAAW,CAACP,OAAO,CAAC;IACjD;IACA,OAAOK,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAC3B,CAAC;EAED;EACAE,UAAU,EAAGC,OAAe,IAAK;IAC/B,IAAIjB,mBAAmB,EAAEgB,UAAU,EAAE;MACnChB,mBAAmB,CAACgB,UAAU,CAACC,OAAO,CAAC;IACzC;EACF;AACF,CAAC;;AAED;AACA,IAAIC,YAAuC,GAAG,IAAI;AAElD,IAAIjB,+BAA+B,EAAE;EACnCiB,YAAY,GAAG,IAAI7B,kBAAkB,CAACY,+BAA+B,CAAC;AACxE;AAEA,OAAO,MAAMC,mBAAmB,GAAG;EACjCiB,WAAW,EAAEA,CAACC,SAAiB,EAAEC,QAAiC,KAAK;IACrE,IAAIH,YAAY,EAAE;MAChB,OAAOA,YAAY,CAACC,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":[]}
1
+ {"version":3,"names":["forwardRef","requireNativeComponent","UIManager","NativeModules","Platform","jsx","_jsx","LINKING_ERROR","select","ios","default","getViewManagerConfig","UnifiedPlayer","Error","NativeUnifiedPlayerView","UnifiedPlayerModule","UnifiedPlayerEventTypes","READY","ERROR","PROGRESS","COMPLETE","STALLED","RESUMED","UnifiedPlayerView","props","ref","play","viewTag","console","log","error","message","String","pause","seekTo","time","getCurrentTime","Promise","reject","getDuration"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,14 +1,10 @@
1
1
  import { type ViewStyle } from 'react-native';
2
- /**
3
- * Props for the UnifiedPlayerView component
4
- */
5
2
  export type UnifiedPlayerProps = {
6
3
  videoUrl: string;
7
4
  style: ViewStyle;
8
5
  autoplay?: boolean;
9
6
  loop?: boolean;
10
7
  isPaused?: boolean;
11
- authToken?: string;
12
8
  onReadyToPlay?: () => void;
13
9
  onError?: (error: any) => void;
14
10
  onPlaybackComplete?: () => void;
@@ -17,32 +13,49 @@ export type UnifiedPlayerProps = {
17
13
  duration: number;
18
14
  }) => void;
19
15
  };
16
+ export declare const UnifiedPlayerEventTypes: {
17
+ READY: string;
18
+ ERROR: string;
19
+ PROGRESS: string;
20
+ COMPLETE: string;
21
+ STALLED: string;
22
+ RESUMED: string;
23
+ };
20
24
  /**
21
25
  * UnifiedPlayerView component for video playback
22
26
  */
23
- export declare const UnifiedPlayerView: import("react").ForwardRefExoticComponent<UnifiedPlayerProps & import("react").RefAttributes<never>>;
27
+ export declare const UnifiedPlayerView: import("react").ForwardRefExoticComponent<UnifiedPlayerProps & import("react").RefAttributes<import("react").Component<UnifiedPlayerProps, {}, any> & import("react-native").NativeMethods>>;
24
28
  /**
25
29
  * API methods for controlling playback
26
30
  */
27
31
  export declare const UnifiedPlayer: {
32
+ /**
33
+ * Start playback
34
+ * @param viewTag - The tag of the player view
35
+ */
28
36
  play: (viewTag: number) => void;
37
+ /**
38
+ * Pause playback
39
+ * @param viewTag - The tag of the player view
40
+ */
29
41
  pause: (viewTag: number) => void;
42
+ /**
43
+ * Seek to a specific time
44
+ * @param viewTag - The tag of the player view
45
+ * @param time - Time in seconds to seek to
46
+ */
30
47
  seekTo: (viewTag: number, time: number) => void;
48
+ /**
49
+ * Get current playback time
50
+ * @param viewTag - The tag of the player view
51
+ * @returns Promise resolving to current time in seconds
52
+ */
31
53
  getCurrentTime: (viewTag: number) => Promise<number>;
54
+ /**
55
+ * Get video duration
56
+ * @param viewTag - The tag of the player view
57
+ * @returns Promise resolving to duration in seconds
58
+ */
32
59
  getDuration: (viewTag: number) => Promise<number>;
33
- testMethod: (message: string) => void;
34
- };
35
- export declare const UnifiedPlayerEvents: {
36
- addListener: (eventType: string, listener: (...args: any[]) => any) => import("react-native").EmitterSubscription | {
37
- remove: () => void;
38
- };
39
- };
40
- export declare const UnifiedPlayerEventTypes: {
41
- READY: string;
42
- ERROR: string;
43
- PROGRESS: string;
44
- COMPLETE: string;
45
- STALLED: string;
46
- RESUMED: string;
47
60
  };
48
61
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,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,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,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;AAuBF;;GAEG;AACH,eAAO,MAAM,iBAAiB,sGAK5B,CAAC;AAEH;;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;0BAQzB,MAAM;CAK7B,CAAC;AASF,eAAO,MAAM,mBAAmB;6BACL,MAAM,YAAY,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;;;CAMnE,CAAC;AAGF,eAAO,MAAM,uBAAuB;;;;;;;CAOnC,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,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;AAYF,eAAO,MAAM,uBAAuB;;;;;;;CAOnC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,8LAK5B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB;;;OAGG;oBACa,MAAM,KAAG,IAAI;IAa7B;;;OAGG;qBACc,MAAM,KAAG,IAAI;IAa9B;;;;OAIG;sBACe,MAAM,QAAQ,MAAM,KAAG,IAAI;IAkB7C;;;;OAIG;8BACuB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;IAalD;;;;OAIG;2BACoB,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;CAYhD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-unified-player",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Unified Player",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/module/index.js",
package/src/index.tsx CHANGED
@@ -1,22 +1,28 @@
1
- import { type Ref, type ElementRef, forwardRef } from 'react'; // Import from 'react'
1
+ import { type ElementRef, forwardRef } from 'react'; // Import from 'react'
2
2
  import {
3
3
  requireNativeComponent,
4
4
  UIManager,
5
+ NativeModules,
5
6
  Platform,
6
7
  type ViewStyle,
7
- NativeModules,
8
- NativeEventEmitter,
9
- } from 'react-native'; // Import from 'react-native'
8
+ } from 'react-native';
10
9
 
10
+ // Check if the native module is available
11
11
  const LINKING_ERROR =
12
12
  `The package 'react-native-unified-player' doesn't seem to be linked. Make sure: \n\n` +
13
13
  Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
14
14
  '- You rebuilt the app after installing the package\n' +
15
15
  '- You are not using Expo Go\n';
16
16
 
17
- /**
18
- * Props for the UnifiedPlayerView component
19
- */
17
+ // Verify the native module exists
18
+ if (
19
+ !UIManager.getViewManagerConfig('UnifiedPlayerView') &&
20
+ !NativeModules.UnifiedPlayer
21
+ ) {
22
+ throw new Error(LINKING_ERROR);
23
+ }
24
+
25
+ // Define the props for the UnifiedPlayerView component
20
26
  export type UnifiedPlayerProps = {
21
27
  // Video source URL
22
28
  videoUrl: string;
@@ -33,9 +39,6 @@ export type UnifiedPlayerProps = {
33
39
  // Is the player currently paused
34
40
  isPaused?: boolean;
35
41
 
36
- // Optional auth token for protected streams
37
- authToken?: string;
38
-
39
42
  // Callback when video is ready to play
40
43
  onReadyToPlay?: () => void;
41
44
 
@@ -49,26 +52,24 @@ export type UnifiedPlayerProps = {
49
52
  onProgress?: (data: { currentTime: number; duration: number }) => void;
50
53
  };
51
54
 
52
- // Name of the native component
53
- const ComponentName = 'UnifiedPlayerView';
55
+ // Native component registration
56
+ const NativeUnifiedPlayerView =
57
+ requireNativeComponent<UnifiedPlayerProps>('UnifiedPlayerView');
54
58
 
55
- // Props for the native component including ref
56
- type NativeUnifiedPlayerViewProps = UnifiedPlayerProps & {
57
- ref?: Ref<ElementRef<typeof NativeUnifiedPlayerView>>;
58
- };
59
+ // Newline added here
59
60
 
60
- // Native component import
61
- const NativeUnifiedPlayerView =
62
- UIManager.getViewManagerConfig(ComponentName) != null
63
- ? requireNativeComponent<NativeUnifiedPlayerViewProps>(ComponentName)
64
- : () => {
65
- throw new Error(LINKING_ERROR);
66
- };
61
+ // Native module for player control methods
62
+ const UnifiedPlayerModule = NativeModules.UnifiedPlayer;
67
63
 
68
- // Native module for additional control methods
69
- const UnifiedPlayerModule = NativeModules.UnifiedPlayerModule;
70
- // Native module for events
71
- const UnifiedPlayerEventEmitterModule = NativeModules.UnifiedPlayerEvents;
64
+ // Export event types for reference
65
+ export const UnifiedPlayerEventTypes = {
66
+ READY: 'onReadyToPlay',
67
+ ERROR: 'onError',
68
+ PROGRESS: 'onProgress',
69
+ COMPLETE: 'onPlaybackComplete',
70
+ STALLED: 'onPlaybackStalled',
71
+ RESUMED: 'onPlaybackResumed',
72
+ };
72
73
 
73
74
  /**
74
75
  * UnifiedPlayerView component for video playback
@@ -84,73 +85,96 @@ export const UnifiedPlayerView = forwardRef<
84
85
  * API methods for controlling playback
85
86
  */
86
87
  export const UnifiedPlayer = {
87
- // Play the video
88
- play: (viewTag: number) => {
89
- if (UnifiedPlayerModule?.play) {
88
+ /**
89
+ * Start playback
90
+ * @param viewTag - The tag of the player view
91
+ */
92
+ play: (viewTag: number): void => {
93
+ try {
94
+ console.log('UnifiedPlayer.play called with viewTag:', viewTag);
90
95
  UnifiedPlayerModule.play(viewTag);
96
+ console.log('Native play method called successfully');
97
+ } catch (error) {
98
+ console.log(
99
+ 'Error calling play:',
100
+ error instanceof Error ? error.message : String(error)
101
+ );
91
102
  }
92
103
  },
93
104
 
94
- // Pause the video
95
- pause: (viewTag: number) => {
96
- if (UnifiedPlayerModule?.pause) {
105
+ /**
106
+ * Pause playback
107
+ * @param viewTag - The tag of the player view
108
+ */
109
+ pause: (viewTag: number): void => {
110
+ try {
111
+ console.log('UnifiedPlayer.pause called with viewTag:', viewTag);
97
112
  UnifiedPlayerModule.pause(viewTag);
113
+ console.log('Native pause method called successfully');
114
+ } catch (error) {
115
+ console.log(
116
+ 'Error calling pause:',
117
+ error instanceof Error ? error.message : String(error)
118
+ );
98
119
  }
99
120
  },
100
121
 
101
- // Seek to a specific time
102
- seekTo: (viewTag: number, time: number) => {
103
- if (UnifiedPlayerModule?.seekTo) {
122
+ /**
123
+ * Seek to a specific time
124
+ * @param viewTag - The tag of the player view
125
+ * @param time - Time in seconds to seek to
126
+ */
127
+ seekTo: (viewTag: number, time: number): void => {
128
+ try {
129
+ console.log(
130
+ 'UnifiedPlayer.seekTo called with viewTag:',
131
+ viewTag,
132
+ 'time:',
133
+ time
134
+ );
104
135
  UnifiedPlayerModule.seekTo(viewTag, time);
136
+ console.log('Native seekTo method called successfully');
137
+ } catch (error) {
138
+ console.log(
139
+ 'Error calling seekTo:',
140
+ error instanceof Error ? error.message : String(error)
141
+ );
105
142
  }
106
143
  },
107
144
 
108
- // Get the current playback time
145
+ /**
146
+ * Get current playback time
147
+ * @param viewTag - The tag of the player view
148
+ * @returns Promise resolving to current time in seconds
149
+ */
109
150
  getCurrentTime: (viewTag: number): Promise<number> => {
110
- if (UnifiedPlayerModule?.getCurrentTime) {
151
+ try {
152
+ console.log('UnifiedPlayer.getCurrentTime called with viewTag:', viewTag);
111
153
  return UnifiedPlayerModule.getCurrentTime(viewTag);
154
+ } catch (error) {
155
+ console.log(
156
+ 'Error calling getCurrentTime:',
157
+ error instanceof Error ? error.message : String(error)
158
+ );
159
+ return Promise.reject(error);
112
160
  }
113
- return Promise.resolve(0);
114
161
  },
115
162
 
116
- // Get the duration of the video
163
+ /**
164
+ * Get video duration
165
+ * @param viewTag - The tag of the player view
166
+ * @returns Promise resolving to duration in seconds
167
+ */
117
168
  getDuration: (viewTag: number): Promise<number> => {
118
- if (UnifiedPlayerModule?.getDuration) {
169
+ try {
170
+ console.log('UnifiedPlayer.getDuration called with viewTag:', viewTag);
119
171
  return UnifiedPlayerModule.getDuration(viewTag);
172
+ } catch (error) {
173
+ console.log(
174
+ 'Error calling getDuration:',
175
+ error instanceof Error ? error.message : String(error)
176
+ );
177
+ return Promise.reject(error);
120
178
  }
121
- return Promise.resolve(0);
122
179
  },
123
-
124
- // Test method
125
- testMethod: (message: string) => {
126
- if (UnifiedPlayerModule?.testMethod) {
127
- UnifiedPlayerModule.testMethod(message);
128
- }
129
- },
130
- };
131
-
132
- // Events emitter for native events
133
- let eventEmitter: NativeEventEmitter | null = null;
134
-
135
- if (UnifiedPlayerEventEmitterModule) {
136
- eventEmitter = new NativeEventEmitter(UnifiedPlayerEventEmitterModule);
137
- }
138
-
139
- export const UnifiedPlayerEvents = {
140
- addListener: (eventType: string, listener: (...args: any[]) => any) => {
141
- if (eventEmitter) {
142
- return eventEmitter.addListener(eventType, listener);
143
- }
144
- return { remove: () => {} };
145
- },
146
- };
147
-
148
- // Event names
149
- export const UnifiedPlayerEventTypes = {
150
- READY: 'onReadyToPlay',
151
- ERROR: 'onError',
152
- PROGRESS: 'onProgress',
153
- COMPLETE: 'onPlaybackComplete',
154
- STALLED: 'onPlaybackStalled',
155
- RESUMED: 'onPlaybackResumed',
156
180
  };