react-native-unified-player 0.3.5 → 0.3.6

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.
@@ -169,4 +169,30 @@ class UnifiedPlayerModule(private val reactContext: ReactApplicationContext) : R
169
169
  }
170
170
  }
171
171
 
172
- }
172
+ @ReactMethod
173
+ fun capture(viewTag: Int, promise: Promise) {
174
+ Log.d(TAG, "Native capture method called with viewTag: $viewTag")
175
+ try {
176
+ val playerView = getPlayerViewByTag(viewTag)
177
+ if (playerView != null) {
178
+ UiThreadUtil.runOnUiThread {
179
+ try {
180
+ // Assuming playerView has a method called capture() that returns a String
181
+ val captureResult = playerView.capture()
182
+ Log.d(TAG, "Capture command executed successfully, result: $captureResult")
183
+ promise.resolve(captureResult)
184
+ } catch (e: Exception) {
185
+ Log.e(TAG, "Error during capture: ${e.message}", e)
186
+ promise.reject("CAPTURE_ERROR", "Error during capture: ${e.message}", e)
187
+ }
188
+ }
189
+ } else {
190
+ Log.e(TAG, "Player view not found for tag: $viewTag")
191
+ promise.reject("VIEW_NOT_FOUND", "Player view not found for tag: $viewTag")
192
+ }
193
+ } catch (e: Exception) {
194
+ Log.e(TAG, "Error in capture method: ${e.message}", e)
195
+ promise.reject("CAPTURE_ERROR", "Error in capture method: ${e.message}", e)
196
+ }
197
+ }
198
+ }
@@ -2,11 +2,17 @@ package com.unifiedplayer
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.content.Context
5
+ import android.graphics.Bitmap
6
+ import android.graphics.Canvas
5
7
  import android.graphics.Color
8
+ import android.view.PixelCopy
9
+ import android.util.Base64
10
+ import java.io.ByteArrayOutputStream
6
11
  import android.util.Log
7
12
  import android.os.Handler
8
13
  import android.os.Looper
9
14
  import android.view.Gravity
15
+ import android.view.View
10
16
  import android.widget.FrameLayout
11
17
  import com.facebook.react.bridge.Arguments
12
18
  import com.google.android.exoplayer2.ExoPlayer
@@ -38,6 +44,7 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
38
44
  private var autoplay: Boolean = true
39
45
  private var loop: Boolean = false
40
46
  private var playerView: PlayerView
47
+ private var textureView: android.view.TextureView? = null
41
48
  private var player: ExoPlayer? = null
42
49
  private var currentProgress = 0
43
50
  private var isPaused = false
@@ -76,17 +83,30 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
76
83
  // Create ExoPlayer
77
84
  player = ExoPlayer.Builder(context).build()
78
85
 
79
- // Create PlayerView
86
+ // Create TextureView for video rendering
87
+ textureView = android.view.TextureView(context).apply {
88
+ layoutParams = LayoutParams(
89
+ LayoutParams.MATCH_PARENT,
90
+ LayoutParams.MATCH_PARENT
91
+ )
92
+ }
93
+
94
+ // Create PlayerView without SurfaceView
80
95
  playerView = PlayerView(context).apply {
81
96
  layoutParams = LayoutParams(
82
97
  LayoutParams.MATCH_PARENT,
83
98
  LayoutParams.MATCH_PARENT
84
99
  )
85
100
  setPlayer(player)
86
- // playerView.surfaceView?.surfaceType = android.view.SurfaceView.SURFACE_TYPE_SOFTWARE // Reverted: Let's remove surfaceType setting
101
+ useController = false // Disable default controls
87
102
  }
88
103
 
104
+ // Add views to hierarchy
105
+ addView(textureView)
89
106
  addView(playerView)
107
+
108
+ // Set TextureView as video surface
109
+ player?.setVideoTextureView(textureView)
90
110
  // Add logging for playerView dimensions and post play call
91
111
  playerView.post {
92
112
  Log.d(TAG, "PlayerView dimensions after addView: width=${playerView.width}, height=${playerView.height}")
@@ -387,4 +407,42 @@ class UnifiedPlayerView(context: Context) : FrameLayout(context) {
387
407
  progressHandler.removeCallbacks(progressRunnable) // Stop progress updates
388
408
  player?.release()
389
409
  }
390
- }
410
+
411
+ fun capture(): String {
412
+ Log.d(TAG, "Capture method called")
413
+ return try {
414
+ player?.let { exoPlayer ->
415
+ // Get the video size from the player
416
+ val videoSize = exoPlayer.videoSize
417
+ if (videoSize.width <= 0 || videoSize.height <= 0) {
418
+ Log.e(TAG, "Invalid video dimensions: ${videoSize.width}x${videoSize.height}")
419
+ return ""
420
+ }
421
+
422
+ // Get bitmap directly from TextureView
423
+ val bitmap = textureView?.bitmap ?: run {
424
+ Log.e(TAG, "Failed to get bitmap from TextureView")
425
+ return ""
426
+ }
427
+
428
+ // Compress and encode the bitmap
429
+ val byteArrayOutputStream = ByteArrayOutputStream()
430
+ if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream)) {
431
+ val byteArray = byteArrayOutputStream.toByteArray()
432
+ val base64EncodedString = Base64.encodeToString(byteArray, Base64.DEFAULT)
433
+ Log.d(TAG, "Capture successful, base64 length: ${base64EncodedString.length}")
434
+ base64EncodedString
435
+ } else {
436
+ Log.e(TAG, "Failed to compress bitmap")
437
+ ""
438
+ }
439
+ } ?: run {
440
+ Log.e(TAG, "Cannot capture: player is null")
441
+ ""
442
+ }
443
+ } catch (e: Exception) {
444
+ Log.e(TAG, "Error during capture: ${e.message}", e)
445
+ ""
446
+ }
447
+ }
448
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-unified-player",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "Unified Player",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/module/index.js",