expo-video 2.0.0 → 2.0.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.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,17 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 2.0.2 — 2024-11-29
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
17
+ ## 2.0.1 — 2024-11-19
18
+
19
+ ### 🐛 Bug fixes
20
+
21
+ - [Android] Fixed `border` related props weren't applied correctly. ([#33075](https://github.com/expo/expo/pull/33075) by [@lukmccall](https://github.com/lukmccall))
22
+ - [Android] Fix controls sometimes flashing on initial display of the view, when `useNativeControls` is `false` ([#33238](https://github.com/expo/expo/pull/33238) by [@behenate](https://github.com/behenate))
23
+
13
24
  ## 2.0.0 — 2024-11-11
14
25
 
15
26
  ### 💡 Others
@@ -1,7 +1,7 @@
1
1
  apply plugin: 'com.android.library'
2
2
 
3
3
  group = 'host.exp.exponent'
4
- version = '2.0.0'
4
+ version = '2.0.2'
5
5
 
6
6
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
7
  apply from: expoModulesCorePlugin
@@ -14,7 +14,7 @@ android {
14
14
  namespace "expo.modules.video"
15
15
  defaultConfig {
16
16
  versionCode 1
17
- versionName '2.0.0'
17
+ versionName '2.0.2'
18
18
  }
19
19
  }
20
20
 
@@ -7,10 +7,6 @@ import androidx.media3.common.PlaybackParameters
7
7
  import androidx.media3.common.Player.REPEAT_MODE_OFF
8
8
  import androidx.media3.common.Player.REPEAT_MODE_ONE
9
9
  import com.facebook.react.common.annotations.UnstableReactNativeAPI
10
- import com.facebook.react.uimanager.PixelUtil
11
- import com.facebook.react.uimanager.Spacing
12
- import com.facebook.react.uimanager.ViewProps
13
- import com.facebook.yoga.YogaConstants
14
10
  import expo.modules.kotlin.apifeatures.EitherType
15
11
  import expo.modules.kotlin.functions.Coroutine
16
12
  import expo.modules.kotlin.modules.Module
@@ -22,8 +18,6 @@ import expo.modules.video.player.VideoPlayer
22
18
  import expo.modules.video.records.BufferOptions
23
19
  import expo.modules.video.records.SubtitleTrack
24
20
  import expo.modules.video.records.VideoSource
25
- import expo.modules.video.utils.ifYogaDefinedUse
26
- import expo.modules.video.utils.makeYogaUndefinedIfNegative
27
21
  import expo.modules.video.utils.runWithPiPMisconfigurationSoftHandling
28
22
  import kotlinx.coroutines.async
29
23
  import kotlinx.coroutines.awaitAll
@@ -80,55 +74,6 @@ class VideoModule : Module() {
80
74
  view.videoPlayer?.requiresLinearPlayback = linearPlayback
81
75
  }
82
76
 
83
- PropGroup(
84
- ViewProps.BORDER_RADIUS to 0,
85
- ViewProps.BORDER_TOP_LEFT_RADIUS to 1,
86
- ViewProps.BORDER_TOP_RIGHT_RADIUS to 2,
87
- ViewProps.BORDER_BOTTOM_RIGHT_RADIUS to 3,
88
- ViewProps.BORDER_BOTTOM_LEFT_RADIUS to 4,
89
- ViewProps.BORDER_TOP_START_RADIUS to 5,
90
- ViewProps.BORDER_TOP_END_RADIUS to 6,
91
- ViewProps.BORDER_BOTTOM_START_RADIUS to 7,
92
- ViewProps.BORDER_BOTTOM_END_RADIUS to 8
93
- ) { view: VideoView, index: Int, borderRadius: Float? ->
94
- val radius = makeYogaUndefinedIfNegative(borderRadius ?: YogaConstants.UNDEFINED)
95
- view.setBorderRadius(index, radius)
96
- }
97
-
98
- PropGroup(
99
- ViewProps.BORDER_WIDTH to Spacing.ALL,
100
- ViewProps.BORDER_LEFT_WIDTH to Spacing.LEFT,
101
- ViewProps.BORDER_RIGHT_WIDTH to Spacing.RIGHT,
102
- ViewProps.BORDER_TOP_WIDTH to Spacing.TOP,
103
- ViewProps.BORDER_BOTTOM_WIDTH to Spacing.BOTTOM,
104
- ViewProps.BORDER_START_WIDTH to Spacing.START,
105
- ViewProps.BORDER_END_WIDTH to Spacing.END
106
- ) { view: VideoView, index: Int, width: Float? ->
107
- val pixelWidth = makeYogaUndefinedIfNegative(width ?: YogaConstants.UNDEFINED)
108
- .ifYogaDefinedUse(PixelUtil::toPixelFromDIP)
109
- view.setBorderWidth(index, pixelWidth)
110
- }
111
-
112
- PropGroup(
113
- ViewProps.BORDER_COLOR to Spacing.ALL,
114
- ViewProps.BORDER_LEFT_COLOR to Spacing.LEFT,
115
- ViewProps.BORDER_RIGHT_COLOR to Spacing.RIGHT,
116
- ViewProps.BORDER_TOP_COLOR to Spacing.TOP,
117
- ViewProps.BORDER_BOTTOM_COLOR to Spacing.BOTTOM,
118
- ViewProps.BORDER_START_COLOR to Spacing.START,
119
- ViewProps.BORDER_END_COLOR to Spacing.END
120
- ) { view: VideoView, index: Int, color: Int ->
121
- view.setBorderColor(index, color)
122
- }
123
-
124
- Prop("borderStyle") { view: VideoView, borderStyle: String? ->
125
- view.setBorderStyle(borderStyle)
126
- }
127
-
128
- OnViewDidUpdateProps { view: VideoView ->
129
- view.didUpdateProps()
130
- }
131
-
132
77
  AsyncFunction("enterFullscreen") { view: VideoView ->
133
78
  view.enterFullscreen()
134
79
  }
@@ -150,6 +95,12 @@ class VideoModule : Module() {
150
95
  OnViewDestroys {
151
96
  VideoManager.unregisterVideoView(it)
152
97
  }
98
+
99
+ OnViewDidUpdateProps { view ->
100
+ if (view.playerView.useController != view.useNativeControls) {
101
+ view.playerView.useController = view.useNativeControls
102
+ }
103
+ }
153
104
  }
154
105
 
155
106
  Class(VideoPlayer::class) {
@@ -4,7 +4,6 @@ import android.app.Activity
4
4
  import android.app.PictureInPictureParams
5
5
  import android.content.Context
6
6
  import android.content.Intent
7
- import android.graphics.Canvas
8
7
  import android.os.Build
9
8
  import android.util.Rational
10
9
  import android.view.View
@@ -14,27 +13,16 @@ import android.widget.ImageButton
14
13
  import androidx.fragment.app.FragmentActivity
15
14
  import androidx.media3.common.Tracks
16
15
  import androidx.media3.ui.PlayerView
17
- import com.facebook.react.common.annotations.UnstableReactNativeAPI
18
- import com.facebook.react.modules.i18nmanager.I18nUtil
19
- import com.facebook.react.uimanager.LengthPercentage
20
- import com.facebook.react.uimanager.LengthPercentageType
21
- import com.facebook.react.uimanager.PixelUtil
22
- import com.facebook.react.uimanager.Spacing
23
- import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable
24
- import com.facebook.react.uimanager.style.BorderRadiusProp
25
- import com.facebook.yoga.YogaConstants
26
16
  import expo.modules.kotlin.AppContext
27
17
  import expo.modules.kotlin.viewevent.EventDispatcher
28
18
  import expo.modules.kotlin.views.ExpoView
29
19
  import expo.modules.video.delegates.IgnoreSameSet
30
- import expo.modules.video.drawing.OutlineProvider
31
20
  import expo.modules.video.enums.ContentFit
32
21
  import expo.modules.video.player.VideoPlayer
33
22
  import expo.modules.video.player.VideoPlayerListener
34
23
  import expo.modules.video.utils.applyAutoEnterPiP
35
24
  import expo.modules.video.utils.applyRectHint
36
25
  import expo.modules.video.utils.calculateRectHint
37
- import expo.modules.video.utils.ifYogaDefinedUse
38
26
  import java.util.UUID
39
27
 
40
28
  // https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide#improvements_in_media3
@@ -64,32 +52,6 @@ class VideoView(context: Context, appContext: AppContext) : ExpoView(context, ap
64
52
  private val rootViewChildrenOriginalVisibility: ArrayList<Int> = arrayListOf()
65
53
  private var pictureInPictureHelperTag: String? = null
66
54
 
67
- private var shouldInvalided = false
68
-
69
- private val outlineProvider = OutlineProvider(context)
70
-
71
- @UnstableReactNativeAPI
72
- private val borderDrawableLazyHolder = lazy {
73
- CSSBackgroundDrawable(context).apply {
74
- callback = this@VideoView
75
-
76
- outlineProvider.borderRadiiConfig
77
- .map { it.ifYogaDefinedUse(PixelUtil::toPixelFromDIP) }
78
- .withIndex()
79
- .forEach { (i, radius) ->
80
- if (i == 0) {
81
- setBorderRadius(BorderRadiusProp.BORDER_RADIUS, LengthPercentage(radius, LengthPercentageType.POINT))
82
- } else {
83
- setBorderRadius(BorderRadiusProp.entries[i - 1], LengthPercentage(radius, LengthPercentageType.POINT))
84
- }
85
- }
86
- }
87
- }
88
-
89
- @UnstableReactNativeAPI
90
- private val borderDrawable
91
- get() = borderDrawableLazyHolder.value
92
-
93
55
  var autoEnterPiP: Boolean by IgnoreSameSet(false) { new, _ ->
94
56
  applyAutoEnterPiP(currentActivity, new)
95
57
  }
@@ -145,6 +107,9 @@ class VideoView(context: Context, appContext: AppContext) : ExpoView(context, ap
145
107
  init {
146
108
  VideoManager.registerVideoView(this)
147
109
  playerView.setFullscreenButtonClickListener { enterFullscreen() }
110
+ // The prop `useNativeControls` prop is sometimes applied after the view is created, and sometimes there is a visible
111
+ // flash of controls event when they are set to off. Initially we set it to `false` and apply it in `onAttachedToWindow` to avoid this.
112
+ this.playerView.useController = false
148
113
  addView(
149
114
  playerView,
150
115
  ViewGroup.LayoutParams(
@@ -277,31 +242,6 @@ class VideoView(context: Context, appContext: AppContext) : ExpoView(context, ap
277
242
  applyRectHint(currentActivity, calculateRectHint(playerView))
278
243
  }
279
244
 
280
- @UnstableReactNativeAPI
281
- override fun draw(canvas: Canvas) {
282
- // When the border-radii are not all the same, a convex-path
283
- // is used for the Outline. Unfortunately clipping is not supported
284
- // for convex-paths and we fallback to Canvas clipping.
285
- outlineProvider.clipCanvasIfNeeded(canvas, this)
286
-
287
- super.draw(canvas)
288
-
289
- // Draw borders on top of the video
290
- if (borderDrawableLazyHolder.isInitialized()) {
291
- val newLayoutDirection = if (I18nUtil.instance.isRTL(context)) {
292
- LAYOUT_DIRECTION_RTL
293
- } else {
294
- LAYOUT_DIRECTION_LTR
295
- }
296
-
297
- borderDrawable.apply {
298
- layoutDirection = newLayoutDirection
299
- setBounds(0, 0, width, height)
300
- draw(canvas)
301
- }
302
- }
303
- }
304
-
305
245
  override fun onAttachedToWindow() {
306
246
  super.onAttachedToWindow()
307
247
  (currentActivity as? FragmentActivity)?.let {
@@ -326,78 +266,6 @@ class VideoView(context: Context, appContext: AppContext) : ExpoView(context, ap
326
266
  applyAutoEnterPiP(currentActivity, false)
327
267
  }
328
268
 
329
- @UnstableReactNativeAPI
330
- internal fun setBorderRadius(position: Int, borderRadius: Float) {
331
- val isInvalidated = outlineProvider.setBorderRadius(borderRadius, position)
332
- if (isInvalidated) {
333
- invalidateOutline()
334
- if (!outlineProvider.hasEqualCorners()) {
335
- shouldInvalided = true
336
- }
337
- }
338
-
339
- // Setting the border-radius doesn't necessarily mean that a border
340
- // should to be drawn. Only update the border-drawable when needed.
341
- if (borderDrawableLazyHolder.isInitialized()) {
342
- shouldInvalided = true
343
- val radius = borderRadius.ifYogaDefinedUse(PixelUtil::toPixelFromDIP)
344
- borderDrawableLazyHolder.value.apply {
345
- if (position == 0) {
346
- setBorderRadius(BorderRadiusProp.BORDER_RADIUS, LengthPercentage(radius, LengthPercentageType.POINT))
347
- } else {
348
- setBorderRadius(BorderRadiusProp.entries[position - 1], LengthPercentage(radius, LengthPercentageType.POINT))
349
- }
350
- }
351
- }
352
- }
353
-
354
- @UnstableReactNativeAPI
355
- internal fun setBorderWidth(position: Int, width: Float) {
356
- borderDrawable.setBorderWidth(position, width)
357
- shouldInvalided = true
358
- }
359
-
360
- @UnstableReactNativeAPI
361
- internal fun setBorderColor(position: Int, rgb: Int) {
362
- borderDrawable.setBorderColor(position, rgb)
363
- shouldInvalided = true
364
- }
365
-
366
- @UnstableReactNativeAPI
367
- internal fun setBorderStyle(style: String?) {
368
- borderDrawable.setBorderStyle(style)
369
- shouldInvalided = true
370
- }
371
-
372
- @UnstableReactNativeAPI
373
- fun didUpdateProps() {
374
- val hasBorder = if (borderDrawableLazyHolder.isInitialized()) {
375
- val spacings = listOf(
376
- Spacing.ALL,
377
- Spacing.LEFT,
378
- Spacing.RIGHT,
379
- Spacing.TOP,
380
- Spacing.BOTTOM,
381
- Spacing.START,
382
- Spacing.END
383
- )
384
- spacings
385
- .any {
386
- val boarderWidth = borderDrawable.getBorderWidthOrDefaultTo(YogaConstants.UNDEFINED, it)
387
- boarderWidth != YogaConstants.UNDEFINED && boarderWidth > 0f
388
- }
389
- } else {
390
- false
391
- }
392
-
393
- // We need to enable drawing on the view to draw the border or background
394
- setWillNotDraw(!isOpaque && !hasBorder)
395
- if (shouldInvalided) {
396
- shouldInvalided = false
397
- invalidate()
398
- }
399
- }
400
-
401
269
  companion object {
402
270
  fun isPictureInPictureSupported(currentActivity: Activity): Boolean {
403
271
  return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && currentActivity.packageManager.hasSystemFeature(
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-video",
3
3
  "title": "Expo Video",
4
- "version": "2.0.0",
4
+ "version": "2.0.2",
5
5
  "description": "A cross-platform, performant video component for React Native and Expo with Web support",
6
6
  "main": "build/index.js",
7
7
  "types": "build/index.d.ts",
@@ -38,5 +38,5 @@
38
38
  "react": "*",
39
39
  "react-native": "*"
40
40
  },
41
- "gitHead": "8f11fad6f46b878de4746b49b18599fc57b5729f"
41
+ "gitHead": "728158f99d680cf64fb06f08301d3806c18c6f63"
42
42
  }