expo-video 2.1.4 → 2.1.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/video/VideoModule.kt +61 -72
  4. package/android/src/main/java/expo/modules/video/VideoView.kt +14 -3
  5. package/android/src/main/res/layout/surface_player_view.xml +7 -0
  6. package/android/src/main/res/layout/texture_player_view.xml +7 -0
  7. package/build/NativeVideoView.d.ts +1 -0
  8. package/build/NativeVideoView.d.ts.map +1 -1
  9. package/build/NativeVideoView.js +4 -1
  10. package/build/NativeVideoView.js.map +1 -1
  11. package/build/VideoView.d.ts.map +1 -1
  12. package/build/VideoView.js +4 -1
  13. package/build/VideoView.js.map +1 -1
  14. package/build/VideoView.types.d.ts +21 -0
  15. package/build/VideoView.types.d.ts.map +1 -1
  16. package/build/VideoView.types.js.map +1 -1
  17. package/build/VideoView.web.d.ts.map +1 -1
  18. package/build/VideoView.web.js +1 -1
  19. package/build/VideoView.web.js.map +1 -1
  20. package/build/index.d.ts +1 -1
  21. package/build/index.d.ts.map +1 -1
  22. package/build/index.js.map +1 -1
  23. package/expo-module.config.json +1 -1
  24. package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.1.4/expo.modules.video-2.1.4-sources.jar → 2.1.6/expo.modules.video-2.1.6-sources.jar} +0 -0
  25. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6-sources.jar.md5 +1 -0
  26. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6-sources.jar.sha1 +1 -0
  27. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6-sources.jar.sha256 +1 -0
  28. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6-sources.jar.sha512 +1 -0
  29. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.aar +0 -0
  30. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.aar.md5 +1 -0
  31. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.aar.sha1 +1 -0
  32. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.aar.sha256 +1 -0
  33. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.aar.sha512 +1 -0
  34. package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.1.4/expo.modules.video-2.1.4.module → 2.1.6/expo.modules.video-2.1.6.module} +22 -22
  35. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.module.md5 +1 -0
  36. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.module.sha1 +1 -0
  37. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.module.sha256 +1 -0
  38. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.module.sha512 +1 -0
  39. package/local-maven-repo/host/exp/exponent/expo.modules.video/{2.1.4/expo.modules.video-2.1.4.pom → 2.1.6/expo.modules.video-2.1.6.pom} +1 -1
  40. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.pom.md5 +1 -0
  41. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.pom.sha1 +1 -0
  42. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.pom.sha256 +1 -0
  43. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.6/expo.modules.video-2.1.6.pom.sha512 +1 -0
  44. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml +4 -4
  45. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.md5 +1 -1
  46. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha1 +1 -1
  47. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha256 +1 -1
  48. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha512 +1 -1
  49. package/package.json +3 -3
  50. package/src/NativeVideoView.ts +6 -1
  51. package/src/VideoView.tsx +4 -1
  52. package/src/VideoView.types.ts +24 -0
  53. package/src/VideoView.web.tsx +1 -0
  54. package/src/index.ts +1 -1
  55. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4-sources.jar.md5 +0 -1
  56. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4-sources.jar.sha1 +0 -1
  57. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4-sources.jar.sha256 +0 -1
  58. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4-sources.jar.sha512 +0 -1
  59. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.aar +0 -0
  60. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.aar.md5 +0 -1
  61. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.aar.sha1 +0 -1
  62. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.aar.sha256 +0 -1
  63. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.aar.sha512 +0 -1
  64. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.module.md5 +0 -1
  65. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.module.sha1 +0 -1
  66. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.module.sha256 +0 -1
  67. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.module.sha512 +0 -1
  68. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.pom.md5 +0 -1
  69. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.pom.sha1 +0 -1
  70. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.pom.sha256 +0 -1
  71. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.1.4/expo.modules.video-2.1.4.pom.sha512 +0 -1
package/CHANGELOG.md CHANGED
@@ -10,6 +10,18 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 2.1.6 — 2025-04-25
14
+
15
+ ### 🎉 New features
16
+
17
+ - [Android] Add an option to choose the surface type. ([#36212](https://github.com/expo/expo/pull/36212) by [@behenate](https://github.com/behenate))
18
+
19
+ ## 2.1.5 — 2025-04-23
20
+
21
+ ### 🎉 New features
22
+
23
+ - [web] Add playsInline prop ([#36335](https://github.com/expo/expo/pull/36335) by [@jakex7](https://github.com/jakex7))
24
+
13
25
  ## 2.1.4 — 2025-04-22
14
26
 
15
27
  ### 🎉 New features
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '2.1.4'
7
+ version = '2.1.6'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.video"
11
11
  defaultConfig {
12
12
  versionCode 1
13
- versionName '2.1.4'
13
+ versionName '2.1.6'
14
14
  }
15
15
  }
16
16
 
@@ -6,12 +6,15 @@ import android.net.Uri
6
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
+ import androidx.media3.common.util.UnstableApi
9
10
  import com.facebook.react.common.annotations.UnstableReactNativeAPI
10
11
  import expo.modules.kotlin.apifeatures.EitherType
11
12
  import expo.modules.kotlin.functions.Coroutine
13
+ import expo.modules.kotlin.functions.Queues
12
14
  import expo.modules.kotlin.modules.Module
13
15
  import expo.modules.kotlin.modules.ModuleDefinition
14
16
  import expo.modules.kotlin.types.Either
17
+ import expo.modules.kotlin.views.ViewDefinitionBuilder
15
18
  import expo.modules.video.enums.AudioMixingMode
16
19
  import expo.modules.video.enums.ContentFit
17
20
  import expo.modules.video.player.VideoPlayer
@@ -28,7 +31,7 @@ import kotlin.time.Duration
28
31
 
29
32
  // https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide#improvements_in_media3
30
33
  @UnstableReactNativeAPI
31
- @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
34
+ @androidx.annotation.OptIn(UnstableApi::class)
32
35
  class VideoModule : Module() {
33
36
  override fun definition() = ModuleDefinition {
34
37
  Name("ExpoVideo")
@@ -53,77 +56,11 @@ class VideoModule : Module() {
53
56
  VideoManager.cache.clear()
54
57
  }
55
58
 
56
- View(VideoView::class) {
57
- Events(
58
- "onPictureInPictureStart",
59
- "onPictureInPictureStop",
60
- "onFullscreenEnter",
61
- "onFullscreenExit",
62
- "onFirstFrameRender"
63
- )
64
-
65
- Prop("player") { view: VideoView, player: VideoPlayer ->
66
- view.videoPlayer = player
67
- }
68
-
69
- Prop("nativeControls") { view: VideoView, useNativeControls: Boolean ->
70
- view.useNativeControls = useNativeControls
71
- }
72
-
73
- Prop("contentFit") { view: VideoView, contentFit: ContentFit ->
74
- view.contentFit = contentFit
75
- }
76
-
77
- Prop("startsPictureInPictureAutomatically") { view: VideoView, autoEnterPiP: Boolean ->
78
- view.autoEnterPiP = autoEnterPiP
79
- }
80
-
81
- Prop("allowsFullscreen") { view: VideoView, allowsFullscreen: Boolean? ->
82
- view.allowsFullscreen = allowsFullscreen ?: true
83
- }
84
-
85
- Prop("requiresLinearPlayback") { view: VideoView, requiresLinearPlayback: Boolean? ->
86
- val linearPlayback = requiresLinearPlayback ?: false
87
- view.playerView.applyRequiresLinearPlayback(linearPlayback)
88
- view.videoPlayer?.requiresLinearPlayback = linearPlayback
89
- }
90
-
91
- Prop("useExoShutter") { view: VideoView, useExoShutter: Boolean? ->
92
- view.useExoShutter = useExoShutter ?: true
93
- }
94
-
95
- AsyncFunction("enterFullscreen") { view: VideoView ->
96
- view.enterFullscreen()
97
- }
98
-
99
- AsyncFunction("exitFullscreen") {
100
- throw MethodUnsupportedException("exitFullscreen")
101
- }
102
-
103
- AsyncFunction("startPictureInPicture") { view: VideoView ->
104
- runWithPiPMisconfigurationSoftHandling(true) {
105
- view.enterPictureInPicture()
106
- }
107
- }
108
-
109
- AsyncFunction("stopPictureInPicture") {
110
- throw MethodUnsupportedException("stopPictureInPicture")
111
- }
112
-
113
- OnViewDestroys {
114
- VideoManager.unregisterVideoView(it)
115
- // Remove relations with mounted players
116
- it.videoPlayer = null
117
- }
118
-
119
- OnViewDidUpdateProps { view ->
120
- view.useExoShutter = view.useExoShutter ?: true
121
- view.applySurfaceViewVisibility()
122
-
123
- if (view.playerView.useController != view.useNativeControls) {
124
- view.playerView.useController = view.useNativeControls
125
- }
126
- }
59
+ View(SurfaceVideoView::class) {
60
+ VideoViewComponent<SurfaceVideoView>()
61
+ }
62
+ View(TextureVideoView::class) {
63
+ VideoViewComponent<TextureVideoView>()
127
64
  }
128
65
 
129
66
  Class(VideoPlayer::class) {
@@ -387,3 +324,55 @@ class VideoModule : Module() {
387
324
  }
388
325
  }
389
326
  }
327
+
328
+ @androidx.annotation.OptIn(UnstableApi::class)
329
+ private inline fun <reified T : VideoView> ViewDefinitionBuilder<T>.VideoViewComponent() {
330
+ Events(
331
+ "onPictureInPictureStart",
332
+ "onPictureInPictureStop",
333
+ "onFullscreenEnter",
334
+ "onFullscreenExit"
335
+ )
336
+ Prop("player") { view: T, player: VideoPlayer ->
337
+ view.videoPlayer = player
338
+ }
339
+ Prop("nativeControls") { view: T, useNativeControls: Boolean ->
340
+ view.useNativeControls = useNativeControls
341
+ }
342
+ Prop("contentFit") { view: T, contentFit: ContentFit ->
343
+ view.contentFit = contentFit
344
+ }
345
+ Prop("startsPictureInPictureAutomatically") { view: T, autoEnterPiP: Boolean ->
346
+ view.autoEnterPiP = autoEnterPiP
347
+ }
348
+ Prop("allowsFullscreen") { view: T, allowsFullscreen: Boolean? ->
349
+ view.allowsFullscreen = allowsFullscreen ?: true
350
+ }
351
+ Prop("requiresLinearPlayback") { view: T, requiresLinearPlayback: Boolean? ->
352
+ val linearPlayback = requiresLinearPlayback ?: false
353
+ view.playerView.applyRequiresLinearPlayback(linearPlayback)
354
+ view.videoPlayer?.requiresLinearPlayback = linearPlayback
355
+ }
356
+ AsyncFunction("enterFullscreen") { view: T ->
357
+ view.enterFullscreen()
358
+ }.runOnQueue(Queues.MAIN)
359
+ AsyncFunction("exitFullscreen") {
360
+ throw MethodUnsupportedException("exitFullscreen")
361
+ }
362
+ AsyncFunction("startPictureInPicture") { view: T ->
363
+ runWithPiPMisconfigurationSoftHandling(true) {
364
+ view.enterPictureInPicture()
365
+ }
366
+ }
367
+ AsyncFunction("stopPictureInPicture") {
368
+ throw MethodUnsupportedException("stopPictureInPicture")
369
+ }
370
+ OnViewDestroys {
371
+ VideoManager.unregisterVideoView(it)
372
+ }
373
+ OnViewDidUpdateProps { view ->
374
+ if (view.playerView.useController != view.useNativeControls) {
375
+ view.playerView.useController = view.useNativeControls
376
+ }
377
+ }
378
+ }
@@ -7,6 +7,7 @@ import android.content.Intent
7
7
  import android.graphics.Color
8
8
  import android.os.Build
9
9
  import android.util.Rational
10
+ import android.view.LayoutInflater
10
11
  import android.view.MotionEvent
11
12
  import android.view.View
12
13
  import android.view.ViewGroup
@@ -32,11 +33,13 @@ import expo.modules.video.utils.calculateRectHint
32
33
  import expo.modules.video.utils.dispatchMotionEvent
33
34
  import java.util.UUID
34
35
 
35
- // https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide#improvements_in_media3
36
+ class SurfaceVideoView(context: Context, appContext: AppContext) : VideoView(context, appContext)
37
+ class TextureVideoView(context: Context, appContext: AppContext) : VideoView(context, appContext, true)
38
+
36
39
  @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
37
- class VideoView(context: Context, appContext: AppContext) : ExpoView(context, appContext), VideoPlayerListener {
40
+ open class VideoView(context: Context, appContext: AppContext, useTextureView: Boolean = false) : ExpoView(context, appContext), VideoPlayerListener {
38
41
  val videoViewId: String = UUID.randomUUID().toString()
39
- val playerView: PlayerView = PlayerView(context.applicationContext)
42
+ val playerView: PlayerView = LayoutInflater.from(context.applicationContext).inflate(getPlayerViewLayoutId(useTextureView), null) as PlayerView
40
43
  val onPictureInPictureStart by EventDispatcher<Unit>()
41
44
  val onPictureInPictureStop by EventDispatcher<Unit>()
42
45
  val onFullscreenEnter by EventDispatcher<Unit>()
@@ -339,6 +342,14 @@ class VideoView(context: Context, appContext: AppContext) : ExpoView(context, ap
339
342
  return false
340
343
  }
341
344
 
345
+ private fun getPlayerViewLayoutId(useTextureView: Boolean): Int {
346
+ return if (useTextureView) {
347
+ R.layout.texture_player_view
348
+ } else {
349
+ R.layout.surface_player_view
350
+ }
351
+ }
352
+
342
353
  companion object {
343
354
  fun isPictureInPictureSupported(currentActivity: Activity): Boolean {
344
355
  return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && currentActivity.packageManager.hasSystemFeature(
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <androidx.media3.ui.PlayerView xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:app="http://schemas.android.com/apk/res-auto"
4
+ android:id="@+id/surface_player_view"
5
+ android:layout_width="match_parent"
6
+ android:layout_height="match_parent"
7
+ app:surface_type="surface_view" />
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <androidx.media3.ui.PlayerView xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:app="http://schemas.android.com/apk/res-auto"
4
+ android:id="@+id/texture_player_view"
5
+ android:layout_width="match_parent"
6
+ android:layout_height="match_parent"
7
+ app:surface_type="texture_view" />
@@ -1,3 +1,4 @@
1
1
  declare const _default: import("react").ComponentType<any>;
2
2
  export default _default;
3
+ export declare const NativeTextureVideoView: import("react").ComponentType<any> | null;
3
4
  //# sourceMappingURL=NativeVideoView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeVideoView.d.ts","sourceRoot":"","sources":["../src/NativeVideoView.ts"],"names":[],"mappings":";AAEA,wBAAqD"}
1
+ {"version":3,"file":"NativeVideoView.d.ts","sourceRoot":"","sources":["../src/NativeVideoView.ts"],"names":[],"mappings":";AAKA,wBAAsE;AACtE,eAAO,MAAM,sBAAsB,2CAC2D,CAAC"}
@@ -1,3 +1,6 @@
1
1
  import { requireNativeViewManager } from 'expo-modules-core';
2
- export default requireNativeViewManager('ExpoVideo');
2
+ import { Platform } from 'react-native';
3
+ const defaultViewName = Platform.OS === 'android' ? 'SurfaceVideoView' : 'VideoView';
4
+ export default requireNativeViewManager('ExpoVideo', defaultViewName);
5
+ export const NativeTextureVideoView = Platform.OS === 'android' ? requireNativeViewManager('ExpoVideo', 'TextureVideoView') : null;
3
6
  //# sourceMappingURL=NativeVideoView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeVideoView.js","sourceRoot":"","sources":["../src/NativeVideoView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,eAAe,wBAAwB,CAAC,WAAW,CAAC,CAAC","sourcesContent":["import { requireNativeViewManager } from 'expo-modules-core';\n\nexport default requireNativeViewManager('ExpoVideo');\n"]}
1
+ {"version":3,"file":"NativeVideoView.js","sourceRoot":"","sources":["../src/NativeVideoView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,MAAM,eAAe,GAAG,QAAQ,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC;AAErF,eAAe,wBAAwB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;AACtE,MAAM,CAAC,MAAM,sBAAsB,GACjC,QAAQ,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,wBAAwB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC","sourcesContent":["import { requireNativeViewManager } from 'expo-modules-core';\nimport { Platform } from 'react-native';\n\nconst defaultViewName = Platform.OS === 'android' ? 'SurfaceVideoView' : 'VideoView';\n\nexport default requireNativeViewManager('ExpoVideo', defaultViewName);\nexport const NativeTextureVideoView =\n Platform.OS === 'android' ? requireNativeViewManager('ExpoVideo', 'TextureVideoView') : null;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"VideoView.d.ts","sourceRoot":"","sources":["../src/VideoView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAa,MAAM,OAAO,CAAC;AAK5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,qBAAa,SAAU,SAAQ,aAAa,CAAC,cAAc,CAAC;IAC1D,SAAS,iCAAoB;IAE7B;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC;;;;;;;;;OASG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5C;;;;;OAKG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3C,MAAM,IAAI,SAAS;CAMpB"}
1
+ {"version":3,"file":"VideoView.d.ts","sourceRoot":"","sources":["../src/VideoView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAa,MAAM,OAAO,CAAC;AAK5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,qBAAa,SAAU,SAAQ,aAAa,CAAC,cAAc,CAAC;IAC1D,SAAS,iCAAoB;IAE7B;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC;;;;;;;;;OASG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5C;;;;;OAKG;IACG,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3C,MAAM,IAAI,SAAS;CASpB"}
@@ -1,6 +1,6 @@
1
1
  import { PureComponent, createRef } from 'react';
2
2
  import NativeVideoModule from './NativeVideoModule';
3
- import NativeVideoView from './NativeVideoView';
3
+ import NativeVideoView, { NativeTextureVideoView } from './NativeVideoView';
4
4
  /**
5
5
  * Returns whether the current device supports Picture in Picture (PiP) mode.
6
6
  *
@@ -53,6 +53,9 @@ export class VideoView extends PureComponent {
53
53
  render() {
54
54
  const { player, ...props } = this.props;
55
55
  const playerId = getPlayerId(player);
56
+ if (NativeTextureVideoView && this.props.surfaceType === 'textureView') {
57
+ return <NativeTextureVideoView {...props} player={playerId} ref={this.nativeRef}/>;
58
+ }
56
59
  return <NativeVideoView {...props} player={playerId} ref={this.nativeRef}/>;
57
60
  }
58
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VideoView.js","sourceRoot":"","sources":["../src/VideoView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAIhD;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO,iBAAiB,CAAC,2BAA2B,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,OAAO,SAAU,SAAQ,aAA6B;IAC1D,SAAS,GAAG,SAAS,EAAO,CAAC;IAE7B;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACxD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,qBAAqB;QACzB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,qBAAqB,EAAE,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,oBAAoB;QACxB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QAErC,OAAO,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAG,CAAC;IAC/E,CAAC;CACF;AAED,gFAAgF;AAChF,gEAAgE;AAChE,yEAAyE;AACzE,SAAS,WAAW,CAAC,MAA4B;IAC/C,IAAI,MAAM,YAAY,iBAAiB,CAAC,WAAW,EAAE,CAAC;QACpD,mBAAmB;QACnB,OAAO,MAAM,CAAC,yBAAyB,CAAC;IAC1C,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { ReactNode, PureComponent, createRef } from 'react';\n\nimport NativeVideoModule from './NativeVideoModule';\nimport NativeVideoView from './NativeVideoView';\nimport type { VideoPlayer } from './VideoPlayer.types';\nimport type { VideoViewProps } from './VideoView.types';\n\n/**\n * Returns whether the current device supports Picture in Picture (PiP) mode.\n *\n * > **Note:** All major web browsers support Picture in Picture (PiP) mode except Firefox.\n * > For more information, see [MDN web docs](https://developer.mozilla.org/en-US/docs/Web/API/Picture-in-Picture_API#browser_compatibility).\n * @returns A `boolean` which is `true` if the device supports PiP mode, and `false` otherwise.\n * @platform android\n * @platform ios\n * @platform web\n */\nexport function isPictureInPictureSupported(): boolean {\n return NativeVideoModule.isPictureInPictureSupported();\n}\n\nexport class VideoView extends PureComponent<VideoViewProps> {\n nativeRef = createRef<any>();\n\n /**\n * Enters fullscreen mode.\n */\n async enterFullscreen(): Promise<void> {\n return await this.nativeRef.current?.enterFullscreen();\n }\n\n /**\n * Exits fullscreen mode.\n */\n async exitFullscreen(): Promise<void> {\n return await this.nativeRef.current?.exitFullscreen();\n }\n\n /**\n * Enters Picture in Picture (PiP) mode. Throws an exception if the device does not support PiP.\n * > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.\n *\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n * @platform android\n * @platform ios\n * @platform web\n */\n async startPictureInPicture(): Promise<void> {\n return await this.nativeRef.current?.startPictureInPicture();\n }\n\n /**\n * Exits Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n async stopPictureInPicture(): Promise<void> {\n return await this.nativeRef.current?.stopPictureInPicture();\n }\n\n render(): ReactNode {\n const { player, ...props } = this.props;\n const playerId = getPlayerId(player);\n\n return <NativeVideoView {...props} player={playerId} ref={this.nativeRef} />;\n }\n}\n\n// Temporary solution to pass the shared object ID instead of the player object.\n// We can't really pass it as an object in the old architecture.\n// Technically we can in the new architecture, but it's not possible yet.\nfunction getPlayerId(player: number | VideoPlayer): number | null {\n if (player instanceof NativeVideoModule.VideoPlayer) {\n // @ts-expect-error\n return player.__expo_shared_object_id__;\n }\n if (typeof player === 'number') {\n return player;\n }\n return null;\n}\n"]}
1
+ {"version":3,"file":"VideoView.js","sourceRoot":"","sources":["../src/VideoView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5D,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,eAAe,EAAE,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAI5E;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO,iBAAiB,CAAC,2BAA2B,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,OAAO,SAAU,SAAQ,aAA6B;IAC1D,SAAS,GAAG,SAAS,EAAO,CAAC;IAE7B;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACxD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,qBAAqB;QACzB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,qBAAqB,EAAE,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,oBAAoB;QACxB,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM;QACJ,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACxC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QAErC,IAAI,sBAAsB,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;YACvE,OAAO,CAAC,sBAAsB,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAG,CAAC;QACtF,CAAC;QACD,OAAO,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAG,CAAC;IAC/E,CAAC;CACF;AAED,gFAAgF;AAChF,gEAAgE;AAChE,yEAAyE;AACzE,SAAS,WAAW,CAAC,MAA4B;IAC/C,IAAI,MAAM,YAAY,iBAAiB,CAAC,WAAW,EAAE,CAAC;QACpD,mBAAmB;QACnB,OAAO,MAAM,CAAC,yBAAyB,CAAC;IAC1C,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { ReactNode, PureComponent, createRef } from 'react';\n\nimport NativeVideoModule from './NativeVideoModule';\nimport NativeVideoView, { NativeTextureVideoView } from './NativeVideoView';\nimport type { VideoPlayer } from './VideoPlayer.types';\nimport type { VideoViewProps } from './VideoView.types';\n\n/**\n * Returns whether the current device supports Picture in Picture (PiP) mode.\n *\n * > **Note:** All major web browsers support Picture in Picture (PiP) mode except Firefox.\n * > For more information, see [MDN web docs](https://developer.mozilla.org/en-US/docs/Web/API/Picture-in-Picture_API#browser_compatibility).\n * @returns A `boolean` which is `true` if the device supports PiP mode, and `false` otherwise.\n * @platform android\n * @platform ios\n * @platform web\n */\nexport function isPictureInPictureSupported(): boolean {\n return NativeVideoModule.isPictureInPictureSupported();\n}\n\nexport class VideoView extends PureComponent<VideoViewProps> {\n nativeRef = createRef<any>();\n\n /**\n * Enters fullscreen mode.\n */\n async enterFullscreen(): Promise<void> {\n return await this.nativeRef.current?.enterFullscreen();\n }\n\n /**\n * Exits fullscreen mode.\n */\n async exitFullscreen(): Promise<void> {\n return await this.nativeRef.current?.exitFullscreen();\n }\n\n /**\n * Enters Picture in Picture (PiP) mode. Throws an exception if the device does not support PiP.\n * > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.\n *\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n * @platform android\n * @platform ios\n * @platform web\n */\n async startPictureInPicture(): Promise<void> {\n return await this.nativeRef.current?.startPictureInPicture();\n }\n\n /**\n * Exits Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n async stopPictureInPicture(): Promise<void> {\n return await this.nativeRef.current?.stopPictureInPicture();\n }\n\n render(): ReactNode {\n const { player, ...props } = this.props;\n const playerId = getPlayerId(player);\n\n if (NativeTextureVideoView && this.props.surfaceType === 'textureView') {\n return <NativeTextureVideoView {...props} player={playerId} ref={this.nativeRef} />;\n }\n return <NativeVideoView {...props} player={playerId} ref={this.nativeRef} />;\n }\n}\n\n// Temporary solution to pass the shared object ID instead of the player object.\n// We can't really pass it as an object in the old architecture.\n// Technically we can in the new architecture, but it's not possible yet.\nfunction getPlayerId(player: number | VideoPlayer): number | null {\n if (player instanceof NativeVideoModule.VideoPlayer) {\n // @ts-expect-error\n return player.__expo_shared_object_id__;\n }\n if (typeof player === 'number') {\n return player;\n }\n return null;\n}\n"]}
@@ -7,6 +7,15 @@ import type { VideoPlayer } from './VideoPlayer.types';
7
7
  * - `fill`: The video stretches/squeezes to completely fill the container, potentially causing distortion.
8
8
  */
9
9
  export type VideoContentFit = 'contain' | 'cover' | 'fill';
10
+ /**
11
+ * Describes the type of the surface used to render the video.
12
+ * - `surfaceView`: Uses the `SurfaceView` to render the video. This value should be used in the majority of cases. Provides significantly lower power consumption, better performance, and more features.
13
+ * - `textureView`: Uses the `TextureView` to render the video. Should be used in cases where the SurfaceView is not supported or causes issues (for example, overlapping video views).
14
+ *
15
+ * You can learn more about surface types in the official [ExoPlayer documentation](https://developer.android.com/media/media3/ui/playerview#surfacetype).
16
+ * @platform android
17
+ */
18
+ export type SurfaceType = 'textureView' | 'surfaceView';
10
19
  export interface VideoViewProps extends ViewProps {
11
20
  /**
12
21
  * A video player instance. Use [`useVideoPlayer()`](#usevideoplayersource-setup) hook to create one.
@@ -41,6 +50,13 @@ export interface VideoViewProps extends ViewProps {
41
50
  * @platform ios
42
51
  */
43
52
  requiresLinearPlayback?: boolean;
53
+ /**
54
+ * Determines the type of the surface used to render the video.
55
+ * > This prop should not be changed at runtime.
56
+ * @default 'surfaceView'
57
+ * @platform android
58
+ */
59
+ surfaceType?: SurfaceType;
44
60
  /**
45
61
  * Determines the position offset of the video inside the container.
46
62
  * @default { dx: 0, dy: 0 }
@@ -73,6 +89,11 @@ export interface VideoViewProps extends ViewProps {
73
89
  * @platform web
74
90
  */
75
91
  allowsPictureInPicture?: boolean;
92
+ /**
93
+ * Determines whether a video should be played "inline", that is, within the element's playback area.
94
+ * @platform web
95
+ */
96
+ playsInline?: boolean;
76
97
  /**
77
98
  * Determines whether the player should start Picture in Picture (PiP) automatically when the app is in the background.
78
99
  * > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.
@@ -1 +1 @@
1
- {"version":3,"file":"VideoView.types.d.ts","sourceRoot":"","sources":["../src/VideoView.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAE7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;OAIG;IACH,eAAe,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE/C;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,MAAM,IAAI,CAAC;IAErC;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpC;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;;;;;;OAUG;IACH,mCAAmC,CAAC,EAAE,OAAO,CAAC;IAE9C;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE/B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE9B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEhC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB"}
1
+ {"version":3,"file":"VideoView.types.d.ts","sourceRoot":"","sources":["../src/VideoView.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC;AAExD,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAE7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;;;OAIG;IACH,eAAe,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE/C;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,MAAM,IAAI,CAAC;IAErC;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpC;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;;OAUG;IACH,mCAAmC,CAAC,EAAE,OAAO,CAAC;IAE9C;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE/B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE9B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEhC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"VideoView.types.js","sourceRoot":"","sources":["../src/VideoView.types.ts"],"names":[],"mappings":"","sourcesContent":["import { ViewProps } from 'react-native';\n\nimport type { VideoPlayer } from './VideoPlayer.types';\n\n/**\n * Describes how a video should be scaled to fit in a container.\n * - `contain`: The video maintains its aspect ratio and fits inside the container, with possible letterboxing/pillarboxing.\n * - `cover`: The video maintains its aspect ratio and covers the entire container, potentially cropping some portions.\n * - `fill`: The video stretches/squeezes to completely fill the container, potentially causing distortion.\n */\nexport type VideoContentFit = 'contain' | 'cover' | 'fill';\n\nexport interface VideoViewProps extends ViewProps {\n /**\n * A video player instance. Use [`useVideoPlayer()`](#usevideoplayersource-setup) hook to create one.\n */\n player: VideoPlayer;\n\n /**\n * Determines whether native controls should be displayed or not.\n * @default true\n */\n nativeControls?: boolean;\n\n /**\n * Describes how the video should be scaled to fit in the container.\n * Options are `'contain'`, `'cover'`, and `'fill'`.\n * @default 'contain'\n */\n contentFit?: VideoContentFit;\n\n /**\n * Determines whether fullscreen mode is allowed or not.\n * @default true\n */\n allowsFullscreen?: boolean;\n\n /**\n * Determines whether the timecodes should be displayed or not.\n * @default true\n * @platform ios\n */\n showsTimecodes?: boolean;\n\n /**\n * Determines whether the player allows the user to skip media content.\n * @default false\n * @platform android\n * @platform ios\n */\n requiresLinearPlayback?: boolean;\n\n /**\n * Determines the position offset of the video inside the container.\n * @default { dx: 0, dy: 0 }\n * @platform ios\n */\n contentPosition?: { dx?: number; dy?: number };\n\n /**\n * A callback to call after the video player enters Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n onPictureInPictureStart?: () => void;\n\n /**\n * A callback to call after the video player exits Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n onPictureInPictureStop?: () => void;\n\n /**\n * Determines whether the player allows Picture in Picture (PiP) mode.\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n * @platform android\n * @platform ios\n * @platform web\n */\n allowsPictureInPicture?: boolean;\n\n /**\n * Determines whether the player should start Picture in Picture (PiP) automatically when the app is in the background.\n * > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.\n *\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n *\n * @default false\n * @platform android 12+\n * @platform ios\n */\n startsPictureInPictureAutomatically?: boolean;\n\n /**\n * Specifies whether to perform video frame analysis (Live Text in videos).\n * Check official [Apple documentation](https://developer.apple.com/documentation/avkit/avplayerviewcontroller/allowsvideoframeanalysis) for more details.\n * @default true\n * @platform ios 16.0+\n */\n allowsVideoFrameAnalysis?: boolean;\n\n /**\n * A callback to call after the video player enters fullscreen mode.\n */\n onFullscreenEnter?: () => void;\n\n /**\n * A callback to call after the video player exits fullscreen mode.\n */\n onFullscreenExit?: () => void;\n\n /**\n * A callback to call after the mounted `VideoPlayer` has rendered the first frame into the `VideoView`.\n * This event can be used to hide any cover images that conceal the initial loading of the player.\n * > **Note:** This event may also be called during playback when the current video track changes (for example when the player switches video quality).\n */\n onFirstFrameRender?: () => void;\n\n /**\n * Determines whether the player should use the default ExoPlayer shutter that covers the `VideoView` before the first video frame is rendered.\n * Setting this property to `false` makes the Android behavior the same as iOS.\n *\n * @platform android\n * @default true\n */\n useExoShutter?: boolean;\n}\n"]}
1
+ {"version":3,"file":"VideoView.types.js","sourceRoot":"","sources":["../src/VideoView.types.ts"],"names":[],"mappings":"","sourcesContent":["import { ViewProps } from 'react-native';\n\nimport type { VideoPlayer } from './VideoPlayer.types';\n\n/**\n * Describes how a video should be scaled to fit in a container.\n * - `contain`: The video maintains its aspect ratio and fits inside the container, with possible letterboxing/pillarboxing.\n * - `cover`: The video maintains its aspect ratio and covers the entire container, potentially cropping some portions.\n * - `fill`: The video stretches/squeezes to completely fill the container, potentially causing distortion.\n */\nexport type VideoContentFit = 'contain' | 'cover' | 'fill';\n\n/**\n * Describes the type of the surface used to render the video.\n * - `surfaceView`: Uses the `SurfaceView` to render the video. This value should be used in the majority of cases. Provides significantly lower power consumption, better performance, and more features.\n * - `textureView`: Uses the `TextureView` to render the video. Should be used in cases where the SurfaceView is not supported or causes issues (for example, overlapping video views).\n *\n * You can learn more about surface types in the official [ExoPlayer documentation](https://developer.android.com/media/media3/ui/playerview#surfacetype).\n * @platform android\n */\nexport type SurfaceType = 'textureView' | 'surfaceView';\n\nexport interface VideoViewProps extends ViewProps {\n /**\n * A video player instance. Use [`useVideoPlayer()`](#usevideoplayersource-setup) hook to create one.\n */\n player: VideoPlayer;\n\n /**\n * Determines whether native controls should be displayed or not.\n * @default true\n */\n nativeControls?: boolean;\n\n /**\n * Describes how the video should be scaled to fit in the container.\n * Options are `'contain'`, `'cover'`, and `'fill'`.\n * @default 'contain'\n */\n contentFit?: VideoContentFit;\n\n /**\n * Determines whether fullscreen mode is allowed or not.\n * @default true\n */\n allowsFullscreen?: boolean;\n\n /**\n * Determines whether the timecodes should be displayed or not.\n * @default true\n * @platform ios\n */\n showsTimecodes?: boolean;\n\n /**\n * Determines whether the player allows the user to skip media content.\n * @default false\n * @platform android\n * @platform ios\n */\n requiresLinearPlayback?: boolean;\n\n /**\n * Determines the type of the surface used to render the video.\n * > This prop should not be changed at runtime.\n * @default 'surfaceView'\n * @platform android\n */\n surfaceType?: SurfaceType;\n\n /**\n * Determines the position offset of the video inside the container.\n * @default { dx: 0, dy: 0 }\n * @platform ios\n */\n contentPosition?: { dx?: number; dy?: number };\n\n /**\n * A callback to call after the video player enters Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n onPictureInPictureStart?: () => void;\n\n /**\n * A callback to call after the video player exits Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n onPictureInPictureStop?: () => void;\n\n /**\n * Determines whether the player allows Picture in Picture (PiP) mode.\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n * @platform android\n * @platform ios\n * @platform web\n */\n allowsPictureInPicture?: boolean;\n\n /**\n * Determines whether a video should be played \"inline\", that is, within the element's playback area.\n * @platform web\n */\n playsInline?: boolean;\n\n /**\n * Determines whether the player should start Picture in Picture (PiP) automatically when the app is in the background.\n * > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.\n *\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n *\n * @default false\n * @platform android 12+\n * @platform ios\n */\n startsPictureInPictureAutomatically?: boolean;\n\n /**\n * Specifies whether to perform video frame analysis (Live Text in videos).\n * Check official [Apple documentation](https://developer.apple.com/documentation/avkit/avplayerviewcontroller/allowsvideoframeanalysis) for more details.\n * @default true\n * @platform ios 16.0+\n */\n allowsVideoFrameAnalysis?: boolean;\n\n /**\n * A callback to call after the video player enters fullscreen mode.\n */\n onFullscreenEnter?: () => void;\n\n /**\n * A callback to call after the video player exits fullscreen mode.\n */\n onFullscreenExit?: () => void;\n\n /**\n * A callback to call after the mounted `VideoPlayer` has rendered the first frame into the `VideoView`.\n * This event can be used to hide any cover images that conceal the initial loading of the player.\n * > **Note:** This event may also be called during playback when the current video track changes (for example when the player switches video quality).\n */\n onFirstFrameRender?: () => void;\n\n /**\n * Determines whether the player should use the default ExoPlayer shutter that covers the `VideoView` before the first video frame is rendered.\n * Setting this property to `false` makes the Android behavior the same as iOS.\n *\n * @platform android\n * @default true\n */\n useExoShutter?: boolean;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"VideoView.web.d.ts","sourceRoot":"","sources":["../src/VideoView.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6D,MAAM,OAAO,CAAC;AAGlF,OAAO,WAA6B,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAsBxD,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,eAAO,MAAM,SAAS;aAAiC,WAAW;kDAoLhE,CAAC;AAEH,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"VideoView.web.d.ts","sourceRoot":"","sources":["../src/VideoView.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6D,MAAM,OAAO,CAAC;AAGlF,OAAO,WAA6B,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAsBxD,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,eAAO,MAAM,SAAS;aAAiC,WAAW;kDAqLhE,CAAC;AAEH,eAAe,SAAS,CAAC"}
@@ -173,7 +173,7 @@ export const VideoView = forwardRef((props, ref) => {
173
173
  hasToSetupAudioContext.current = true;
174
174
  maybeSetupAudioContext();
175
175
  }
176
- }} disablePictureInPicture={!props.allowsPictureInPicture} src={getSourceUri(props.player?.src) ?? ''}/>);
176
+ }} disablePictureInPicture={!props.allowsPictureInPicture} playsInline={props.playsInline} src={getSourceUri(props.player?.src) ?? ''}/>);
177
177
  });
178
178
  export default VideoView;
179
179
  //# sourceMappingURL=VideoView.web.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VideoView.web.js","sourceRoot":"","sources":["../src/VideoView.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useRef, forwardRef, useImperativeHandle } from 'react';\nimport { StyleSheet } from 'react-native';\n\nimport VideoPlayer, { getSourceUri } from './VideoPlayer.web';\nimport type { VideoViewProps } from './VideoView.types';\n\nfunction createAudioContext(): AudioContext | null {\n return typeof window !== 'undefined' ? new window.AudioContext() : null;\n}\n\nfunction createZeroGainNode(audioContext: AudioContext | null): GainNode | null {\n const zeroGainNode = audioContext?.createGain() ?? null;\n\n if (audioContext && zeroGainNode) {\n zeroGainNode.gain.value = 0;\n zeroGainNode.connect(audioContext.destination);\n }\n return zeroGainNode;\n}\n\nfunction mapStyles(style: VideoViewProps['style']): React.CSSProperties {\n const flattenedStyles = StyleSheet.flatten(style);\n // Looking through react-native-web source code they also just pass styles directly without further conversions, so it's just a cast.\n return flattenedStyles as React.CSSProperties;\n}\n\nexport function isPictureInPictureSupported(): boolean {\n return typeof document === 'object' && typeof document.exitPictureInPicture === 'function';\n}\n\nexport const VideoView = forwardRef((props: { player?: VideoPlayer } & VideoViewProps, ref) => {\n const videoRef = useRef<null | HTMLVideoElement>(null);\n const mediaNodeRef = useRef<null | MediaElementAudioSourceNode>(null);\n const hasToSetupAudioContext = useRef(false);\n const fullscreenChangeListener = useRef<null | (() => void)>(null);\n const isWaitingForFirstFrame = useRef(false);\n\n /**\n * Audio context is used to mute all but one video when multiple video views are playing from one player simultaneously.\n * Using audio context nodes allows muting videos without displaying the mute icon in the video player.\n * We have to keep the context that called createMediaElementSource(videoRef), as the method can't be called\n * for the second time with another context and there is no way to unbind the video and audio context afterward.\n */\n const audioContextRef = useRef<null | AudioContext>(null);\n const zeroGainNodeRef = useRef<null | GainNode>(null);\n\n useImperativeHandle(ref, () => ({\n enterFullscreen: async () => {\n if (!props.allowsFullscreen) {\n return;\n }\n await videoRef.current?.requestFullscreen();\n },\n exitFullscreen: async () => {\n await document.exitFullscreen();\n },\n startPictureInPicture: async () => {\n await videoRef.current?.requestPictureInPicture();\n },\n stopPictureInPicture: async () => {\n try {\n await document.exitPictureInPicture();\n } catch (e) {\n if (e instanceof DOMException && e.name === 'InvalidStateError') {\n console.warn('The VideoView is not in Picture-in-Picture mode.');\n } else {\n throw e;\n }\n }\n },\n }));\n\n useEffect(() => {\n const onEnter = () => {\n props.onPictureInPictureStart?.();\n };\n const onLeave = () => {\n props.onPictureInPictureStop?.();\n };\n const onLoadStart = () => {\n isWaitingForFirstFrame.current = true;\n };\n const onCanPlay = () => {\n if (isWaitingForFirstFrame.current) {\n props.onFirstFrameRender?.();\n }\n isWaitingForFirstFrame.current = false;\n };\n videoRef.current?.addEventListener('enterpictureinpicture', onEnter);\n videoRef.current?.addEventListener('leavepictureinpicture', onLeave);\n videoRef.current?.addEventListener('loadstart', onLoadStart);\n videoRef.current?.addEventListener('loadeddata', onCanPlay);\n\n return () => {\n videoRef.current?.removeEventListener('enterpictureinpicture', onEnter);\n videoRef.current?.removeEventListener('leavepictureinpicture', onLeave);\n videoRef.current?.removeEventListener('loadstart', onLoadStart);\n videoRef.current?.removeEventListener('loadeddata', onCanPlay);\n };\n }, [videoRef, props.onPictureInPictureStop, props.onPictureInPictureStart]);\n\n // Adds the video view as a candidate for being the audio source for the player (when multiple views play from one\n // player only one will emit audio).\n function attachAudioNodes() {\n const audioContext = audioContextRef.current;\n const zeroGainNode = zeroGainNodeRef.current;\n const mediaNode = mediaNodeRef.current;\n\n if (audioContext && zeroGainNode && mediaNode) {\n props.player.mountAudioNode(audioContext, zeroGainNode, mediaNode);\n } else {\n console.warn(\n \"Couldn't mount audio node, this might affect the audio playback when using multiple video views with the same player.\"\n );\n }\n }\n\n function detachAudioNodes() {\n const audioContext = audioContextRef.current;\n const mediaNode = mediaNodeRef.current;\n if (audioContext && mediaNode && videoRef.current) {\n props.player.unmountAudioNode(videoRef.current, audioContext, mediaNode);\n }\n }\n\n function maybeSetupAudioContext() {\n if (\n !hasToSetupAudioContext.current ||\n !navigator.userActivation.hasBeenActive ||\n !videoRef.current\n ) {\n return;\n }\n const audioContext = createAudioContext();\n\n detachAudioNodes();\n audioContextRef.current = audioContext;\n zeroGainNodeRef.current = createZeroGainNode(audioContextRef.current);\n mediaNodeRef.current = audioContext\n ? audioContext.createMediaElementSource(videoRef.current)\n : null;\n attachAudioNodes();\n hasToSetupAudioContext.current = false;\n }\n\n function fullscreenListener() {\n if (document.fullscreenElement === videoRef.current) {\n props.onFullscreenEnter?.();\n } else {\n props.onFullscreenExit?.();\n }\n }\n\n function setupFullscreenListener() {\n fullscreenChangeListener.current = fullscreenListener;\n videoRef.current?.addEventListener('fullscreenchange', fullscreenChangeListener.current);\n }\n\n function cleanupFullscreenListener() {\n if (fullscreenChangeListener.current) {\n videoRef.current?.removeEventListener('fullscreenchange', fullscreenChangeListener.current);\n fullscreenChangeListener.current = null;\n }\n }\n\n useEffect(() => {\n if (videoRef.current) {\n props.player?.mountVideoView(videoRef.current);\n }\n setupFullscreenListener();\n attachAudioNodes();\n\n return () => {\n if (videoRef.current) {\n props.player?.unmountVideoView(videoRef.current);\n }\n cleanupFullscreenListener();\n detachAudioNodes();\n };\n }, [props.player]);\n\n return (\n <video\n controls={props.nativeControls ?? true}\n controlsList={props.allowsFullscreen ? undefined : 'nofullscreen'}\n crossOrigin=\"anonymous\"\n style={{\n ...mapStyles(props.style),\n objectFit: props.contentFit,\n }}\n onPlay={() => {\n maybeSetupAudioContext();\n }}\n // The player can autoplay when muted, unmuting by a user should create the audio context\n onVolumeChange={() => {\n maybeSetupAudioContext();\n }}\n ref={(newRef) => {\n // This is called with a null value before `player.unmountVideoView` is called,\n // we can't assign null to videoRef if we want to unmount it from the player.\n if (newRef && !newRef.isEqualNode(videoRef.current)) {\n videoRef.current = newRef;\n hasToSetupAudioContext.current = true;\n maybeSetupAudioContext();\n }\n }}\n disablePictureInPicture={!props.allowsPictureInPicture}\n src={getSourceUri(props.player?.src) ?? ''}\n />\n );\n});\n\nexport default VideoView;\n"]}
1
+ {"version":3,"file":"VideoView.web.js","sourceRoot":"","sources":["../src/VideoView.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useRef, forwardRef, useImperativeHandle } from 'react';\nimport { StyleSheet } from 'react-native';\n\nimport VideoPlayer, { getSourceUri } from './VideoPlayer.web';\nimport type { VideoViewProps } from './VideoView.types';\n\nfunction createAudioContext(): AudioContext | null {\n return typeof window !== 'undefined' ? new window.AudioContext() : null;\n}\n\nfunction createZeroGainNode(audioContext: AudioContext | null): GainNode | null {\n const zeroGainNode = audioContext?.createGain() ?? null;\n\n if (audioContext && zeroGainNode) {\n zeroGainNode.gain.value = 0;\n zeroGainNode.connect(audioContext.destination);\n }\n return zeroGainNode;\n}\n\nfunction mapStyles(style: VideoViewProps['style']): React.CSSProperties {\n const flattenedStyles = StyleSheet.flatten(style);\n // Looking through react-native-web source code they also just pass styles directly without further conversions, so it's just a cast.\n return flattenedStyles as React.CSSProperties;\n}\n\nexport function isPictureInPictureSupported(): boolean {\n return typeof document === 'object' && typeof document.exitPictureInPicture === 'function';\n}\n\nexport const VideoView = forwardRef((props: { player?: VideoPlayer } & VideoViewProps, ref) => {\n const videoRef = useRef<null | HTMLVideoElement>(null);\n const mediaNodeRef = useRef<null | MediaElementAudioSourceNode>(null);\n const hasToSetupAudioContext = useRef(false);\n const fullscreenChangeListener = useRef<null | (() => void)>(null);\n const isWaitingForFirstFrame = useRef(false);\n\n /**\n * Audio context is used to mute all but one video when multiple video views are playing from one player simultaneously.\n * Using audio context nodes allows muting videos without displaying the mute icon in the video player.\n * We have to keep the context that called createMediaElementSource(videoRef), as the method can't be called\n * for the second time with another context and there is no way to unbind the video and audio context afterward.\n */\n const audioContextRef = useRef<null | AudioContext>(null);\n const zeroGainNodeRef = useRef<null | GainNode>(null);\n\n useImperativeHandle(ref, () => ({\n enterFullscreen: async () => {\n if (!props.allowsFullscreen) {\n return;\n }\n await videoRef.current?.requestFullscreen();\n },\n exitFullscreen: async () => {\n await document.exitFullscreen();\n },\n startPictureInPicture: async () => {\n await videoRef.current?.requestPictureInPicture();\n },\n stopPictureInPicture: async () => {\n try {\n await document.exitPictureInPicture();\n } catch (e) {\n if (e instanceof DOMException && e.name === 'InvalidStateError') {\n console.warn('The VideoView is not in Picture-in-Picture mode.');\n } else {\n throw e;\n }\n }\n },\n }));\n\n useEffect(() => {\n const onEnter = () => {\n props.onPictureInPictureStart?.();\n };\n const onLeave = () => {\n props.onPictureInPictureStop?.();\n };\n const onLoadStart = () => {\n isWaitingForFirstFrame.current = true;\n };\n const onCanPlay = () => {\n if (isWaitingForFirstFrame.current) {\n props.onFirstFrameRender?.();\n }\n isWaitingForFirstFrame.current = false;\n };\n videoRef.current?.addEventListener('enterpictureinpicture', onEnter);\n videoRef.current?.addEventListener('leavepictureinpicture', onLeave);\n videoRef.current?.addEventListener('loadstart', onLoadStart);\n videoRef.current?.addEventListener('loadeddata', onCanPlay);\n\n return () => {\n videoRef.current?.removeEventListener('enterpictureinpicture', onEnter);\n videoRef.current?.removeEventListener('leavepictureinpicture', onLeave);\n videoRef.current?.removeEventListener('loadstart', onLoadStart);\n videoRef.current?.removeEventListener('loadeddata', onCanPlay);\n };\n }, [videoRef, props.onPictureInPictureStop, props.onPictureInPictureStart]);\n\n // Adds the video view as a candidate for being the audio source for the player (when multiple views play from one\n // player only one will emit audio).\n function attachAudioNodes() {\n const audioContext = audioContextRef.current;\n const zeroGainNode = zeroGainNodeRef.current;\n const mediaNode = mediaNodeRef.current;\n\n if (audioContext && zeroGainNode && mediaNode) {\n props.player.mountAudioNode(audioContext, zeroGainNode, mediaNode);\n } else {\n console.warn(\n \"Couldn't mount audio node, this might affect the audio playback when using multiple video views with the same player.\"\n );\n }\n }\n\n function detachAudioNodes() {\n const audioContext = audioContextRef.current;\n const mediaNode = mediaNodeRef.current;\n if (audioContext && mediaNode && videoRef.current) {\n props.player.unmountAudioNode(videoRef.current, audioContext, mediaNode);\n }\n }\n\n function maybeSetupAudioContext() {\n if (\n !hasToSetupAudioContext.current ||\n !navigator.userActivation.hasBeenActive ||\n !videoRef.current\n ) {\n return;\n }\n const audioContext = createAudioContext();\n\n detachAudioNodes();\n audioContextRef.current = audioContext;\n zeroGainNodeRef.current = createZeroGainNode(audioContextRef.current);\n mediaNodeRef.current = audioContext\n ? audioContext.createMediaElementSource(videoRef.current)\n : null;\n attachAudioNodes();\n hasToSetupAudioContext.current = false;\n }\n\n function fullscreenListener() {\n if (document.fullscreenElement === videoRef.current) {\n props.onFullscreenEnter?.();\n } else {\n props.onFullscreenExit?.();\n }\n }\n\n function setupFullscreenListener() {\n fullscreenChangeListener.current = fullscreenListener;\n videoRef.current?.addEventListener('fullscreenchange', fullscreenChangeListener.current);\n }\n\n function cleanupFullscreenListener() {\n if (fullscreenChangeListener.current) {\n videoRef.current?.removeEventListener('fullscreenchange', fullscreenChangeListener.current);\n fullscreenChangeListener.current = null;\n }\n }\n\n useEffect(() => {\n if (videoRef.current) {\n props.player?.mountVideoView(videoRef.current);\n }\n setupFullscreenListener();\n attachAudioNodes();\n\n return () => {\n if (videoRef.current) {\n props.player?.unmountVideoView(videoRef.current);\n }\n cleanupFullscreenListener();\n detachAudioNodes();\n };\n }, [props.player]);\n\n return (\n <video\n controls={props.nativeControls ?? true}\n controlsList={props.allowsFullscreen ? undefined : 'nofullscreen'}\n crossOrigin=\"anonymous\"\n style={{\n ...mapStyles(props.style),\n objectFit: props.contentFit,\n }}\n onPlay={() => {\n maybeSetupAudioContext();\n }}\n // The player can autoplay when muted, unmuting by a user should create the audio context\n onVolumeChange={() => {\n maybeSetupAudioContext();\n }}\n ref={(newRef) => {\n // This is called with a null value before `player.unmountVideoView` is called,\n // we can't assign null to videoRef if we want to unmount it from the player.\n if (newRef && !newRef.isEqualNode(videoRef.current)) {\n videoRef.current = newRef;\n hasToSetupAudioContext.current = true;\n maybeSetupAudioContext();\n }\n }}\n disablePictureInPicture={!props.allowsPictureInPicture}\n playsInline={props.playsInline}\n src={getSourceUri(props.player?.src) ?? ''}\n />\n );\n});\n\nexport default VideoView;\n"]}
package/build/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { isPictureInPictureSupported, clearVideoCacheAsync, setVideoCacheSizeAsync, getCurrentVideoCacheSize, } from './VideoModule';
2
2
  export { VideoView } from './VideoView';
3
3
  export { useVideoPlayer } from './VideoPlayer';
4
- export { VideoContentFit, VideoViewProps } from './VideoView.types';
4
+ export { VideoContentFit, VideoViewProps, SurfaceType } from './VideoView.types';
5
5
  export { VideoThumbnail } from './VideoThumbnail';
6
6
  export { createVideoPlayer } from './VideoPlayer';
7
7
  export { VideoPlayer, VideoPlayerStatus, VideoSource, PlayerError, VideoMetadata, DRMType, DRMOptions, BufferOptions, AudioMixingMode, VideoThumbnailOptions, VideoSize, SubtitleTrack, VideoTrack, ContentType, } from './VideoPlayer.types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,aAAa,EACb,OAAO,EACP,UAAU,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,aAAa,EACb,OAAO,EACP,UAAU,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,WAAW,GAcZ,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n isPictureInPictureSupported,\n clearVideoCacheAsync,\n setVideoCacheSizeAsync,\n getCurrentVideoCacheSize,\n} from './VideoModule';\nexport { VideoView } from './VideoView';\nexport { useVideoPlayer } from './VideoPlayer';\n\nexport { VideoContentFit, VideoViewProps } from './VideoView.types';\nexport { VideoThumbnail } from './VideoThumbnail';\n\nexport { createVideoPlayer } from './VideoPlayer';\n\nexport {\n VideoPlayer,\n VideoPlayerStatus,\n VideoSource,\n PlayerError,\n VideoMetadata,\n DRMType,\n DRMOptions,\n BufferOptions,\n AudioMixingMode,\n VideoThumbnailOptions,\n VideoSize,\n SubtitleTrack,\n VideoTrack,\n ContentType,\n} from './VideoPlayer.types';\n\nexport {\n VideoPlayerEvents,\n StatusChangeEventPayload,\n PlayingChangeEventPayload,\n PlaybackRateChangeEventPayload,\n VolumeChangeEventPayload,\n MutedChangeEventPayload,\n TimeUpdateEventPayload,\n SourceChangeEventPayload,\n SourceLoadEventPayload,\n} from './VideoPlayerEvents.types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,WAAW,GAcZ,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n isPictureInPictureSupported,\n clearVideoCacheAsync,\n setVideoCacheSizeAsync,\n getCurrentVideoCacheSize,\n} from './VideoModule';\nexport { VideoView } from './VideoView';\nexport { useVideoPlayer } from './VideoPlayer';\n\nexport { VideoContentFit, VideoViewProps, SurfaceType } from './VideoView.types';\nexport { VideoThumbnail } from './VideoThumbnail';\n\nexport { createVideoPlayer } from './VideoPlayer';\n\nexport {\n VideoPlayer,\n VideoPlayerStatus,\n VideoSource,\n PlayerError,\n VideoMetadata,\n DRMType,\n DRMOptions,\n BufferOptions,\n AudioMixingMode,\n VideoThumbnailOptions,\n VideoSize,\n SubtitleTrack,\n VideoTrack,\n ContentType,\n} from './VideoPlayer.types';\n\nexport {\n VideoPlayerEvents,\n StatusChangeEventPayload,\n PlayingChangeEventPayload,\n PlaybackRateChangeEventPayload,\n VolumeChangeEventPayload,\n MutedChangeEventPayload,\n TimeUpdateEventPayload,\n SourceChangeEventPayload,\n SourceLoadEventPayload,\n} from './VideoPlayerEvents.types';\n"]}
@@ -8,7 +8,7 @@
8
8
  "publication": {
9
9
  "groupId": "host.exp.exponent",
10
10
  "artifactId": "expo.modules.video",
11
- "version": "2.1.4",
11
+ "version": "2.1.6",
12
12
  "repository": "local-maven-repo"
13
13
  }
14
14
  }
@@ -0,0 +1 @@
1
+ df355c7abf860408e8bb85a257887c580d471507b98f9539f0656ba86954c790
@@ -0,0 +1 @@
1
+ 7f2784914b0f802f2fbcdc144c5caff33b091f90f25b625222a24cc1ff74a159b5eccb4e23a339bc3accf874f1e58d8d1218740b37b3b1cd02377e0aca567ac4
@@ -0,0 +1 @@
1
+ 5a26209e185ddd659f51e58b7351eca02d348c73
@@ -0,0 +1 @@
1
+ 9fb66bb0bd908425afd670be901cf510f0ef72d58534337761d771758400743e
@@ -0,0 +1 @@
1
+ c220a0b543c6fa5a0933193c22c14b1492931dec950a84c3a2391a98234153781dd5808549257eb19e6544a62d49d1717638e576ec5e6b117091a99191c67fd3
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "host.exp.exponent",
5
5
  "module": "expo.modules.video",
6
- "version": "2.1.4",
6
+ "version": "2.1.6",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
@@ -24,13 +24,13 @@
24
24
  },
25
25
  "files": [
26
26
  {
27
- "name": "expo.modules.video-2.1.4.aar",
28
- "url": "expo.modules.video-2.1.4.aar",
29
- "size": 376103,
30
- "sha512": "7775cae977666dbaa83a2504564237fb275f3ae91edab1751b0773479213f56b4aa8be1a034c845ea8d97e2fe71d80b495a1cf16a4629080c12be9d759949cb7",
31
- "sha256": "595cb598ff7ae7534558ad15beb02c4ba4b83b1a24424280264fec3655268dff",
32
- "sha1": "2f954ac5045eedab842522c022af40ea6580ad39",
33
- "md5": "cd413795b7e5bda001171b8d416709c8"
27
+ "name": "expo.modules.video-2.1.6.aar",
28
+ "url": "expo.modules.video-2.1.6.aar",
29
+ "size": 414962,
30
+ "sha512": "c220a0b543c6fa5a0933193c22c14b1492931dec950a84c3a2391a98234153781dd5808549257eb19e6544a62d49d1717638e576ec5e6b117091a99191c67fd3",
31
+ "sha256": "9fb66bb0bd908425afd670be901cf510f0ef72d58534337761d771758400743e",
32
+ "sha1": "5a26209e185ddd659f51e58b7351eca02d348c73",
33
+ "md5": "0c5f6ddf08add31a7d390039bb1e236d"
34
34
  }
35
35
  ]
36
36
  },
@@ -113,13 +113,13 @@
113
113
  ],
114
114
  "files": [
115
115
  {
116
- "name": "expo.modules.video-2.1.4.aar",
117
- "url": "expo.modules.video-2.1.4.aar",
118
- "size": 376103,
119
- "sha512": "7775cae977666dbaa83a2504564237fb275f3ae91edab1751b0773479213f56b4aa8be1a034c845ea8d97e2fe71d80b495a1cf16a4629080c12be9d759949cb7",
120
- "sha256": "595cb598ff7ae7534558ad15beb02c4ba4b83b1a24424280264fec3655268dff",
121
- "sha1": "2f954ac5045eedab842522c022af40ea6580ad39",
122
- "md5": "cd413795b7e5bda001171b8d416709c8"
116
+ "name": "expo.modules.video-2.1.6.aar",
117
+ "url": "expo.modules.video-2.1.6.aar",
118
+ "size": 414962,
119
+ "sha512": "c220a0b543c6fa5a0933193c22c14b1492931dec950a84c3a2391a98234153781dd5808549257eb19e6544a62d49d1717638e576ec5e6b117091a99191c67fd3",
120
+ "sha256": "9fb66bb0bd908425afd670be901cf510f0ef72d58534337761d771758400743e",
121
+ "sha1": "5a26209e185ddd659f51e58b7351eca02d348c73",
122
+ "md5": "0c5f6ddf08add31a7d390039bb1e236d"
123
123
  }
124
124
  ]
125
125
  },
@@ -133,13 +133,13 @@
133
133
  },
134
134
  "files": [
135
135
  {
136
- "name": "expo.modules.video-2.1.4-sources.jar",
137
- "url": "expo.modules.video-2.1.4-sources.jar",
138
- "size": 50284,
139
- "sha512": "44097ffc761e959398af7069772cdc2b148b5fe7ea322601da4731478e2158169bdcec09c03ce99cbe348d3713d0a4a40196a5529090aa834fd899b4bc188032",
140
- "sha256": "963f16122f1193f3a6a4b1be63a5899ac7a6c8d48363e8fafc5f62b1b4c0a1d4",
141
- "sha1": "d1b03a57d44d692802cba45a20dd88f20a43cb86",
142
- "md5": "db3625c0e2ae8ead78b719b60fba99b9"
136
+ "name": "expo.modules.video-2.1.6-sources.jar",
137
+ "url": "expo.modules.video-2.1.6-sources.jar",
138
+ "size": 50390,
139
+ "sha512": "7f2784914b0f802f2fbcdc144c5caff33b091f90f25b625222a24cc1ff74a159b5eccb4e23a339bc3accf874f1e58d8d1218740b37b3b1cd02377e0aca567ac4",
140
+ "sha256": "df355c7abf860408e8bb85a257887c580d471507b98f9539f0656ba86954c790",
141
+ "sha1": "0055225013c5b4ea5724dd9222278ed92cf359ad",
142
+ "md5": "c3f4e230534616a8e72f1548c28bc480"
143
143
  }
144
144
  ]
145
145
  }
@@ -0,0 +1 @@
1
+ f1ca7f9d998174b5c77840369b456430278496f7607d2be19be5babdff213600
@@ -0,0 +1 @@
1
+ dcb664c3b836c60ac33052e353b6ac2fb30ee77e19049c76de20d681bec23e1b3fc1f140ab36b4ca37725889bf5ba63cfdb9990fbc1b87500c28e53084e0fe9d
@@ -9,7 +9,7 @@
9
9
  <modelVersion>4.0.0</modelVersion>
10
10
  <groupId>host.exp.exponent</groupId>
11
11
  <artifactId>expo.modules.video</artifactId>
12
- <version>2.1.4</version>
12
+ <version>2.1.6</version>
13
13
  <packaging>aar</packaging>
14
14
  <name>expo.modules.video</name>
15
15
  <url>https://github.com/expo/expo</url>
@@ -0,0 +1 @@
1
+ d87e276de292d418a18ad8545990ac450e42de96
@@ -0,0 +1 @@
1
+ af6be3afad53a7295065edf7a36979b89f2905745cc03109882860a8ccf187d2
@@ -0,0 +1 @@
1
+ e287a932715583827a85d1289548a1995a18b049d52ea91bc849ed916f6d534e9236a4a939ba8b95e470e88f113111aecb852f9379ca22851b9317fd4bb0c80c
@@ -3,11 +3,11 @@
3
3
  <groupId>host.exp.exponent</groupId>
4
4
  <artifactId>expo.modules.video</artifactId>
5
5
  <versioning>
6
- <latest>2.1.4</latest>
7
- <release>2.1.4</release>
6
+ <latest>2.1.6</latest>
7
+ <release>2.1.6</release>
8
8
  <versions>
9
- <version>2.1.4</version>
9
+ <version>2.1.6</version>
10
10
  </versions>
11
- <lastUpdated>20250422204947</lastUpdated>
11
+ <lastUpdated>20250425205754</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- 1761eeed42826055aad669a1f67fd82d
1
+ e1809d38b7c62840d6546ac129fa33b3
@@ -1 +1 @@
1
- de23c1cc9cc4866db55457eb10f8496e182fad09
1
+ 943395b6c2eccb56b57c4709d2714989c5228286
@@ -1 +1 @@
1
- 0006e6ccfba1231333c74159a88f2f202789677e82e5052b6bd86af3e6136fcc
1
+ ea2fe1b8089e4a626093a805868d16cd10002b9167379de6f64e5360614399fe
@@ -1 +1 @@
1
- bdcb82765789fca19c9d407a92977c92f9fb9e3052be483fd17c1690ba0b39bf9ac71dd26eafcdf85bc2c03d570eed9b4953a874f2c6de036aaea0319203697a
1
+ f056b6dc94785b35b0a5b747d3056b9c2e1d14cd3d193d7ff60f8749fc2046d5dc91608cdd152a49f2b0fbd9f67c13f2cc375e90a7ae53d45fc70e036fd4faed
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-video",
3
3
  "title": "Expo Video",
4
- "version": "2.1.4",
4
+ "version": "2.1.6",
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",
@@ -31,12 +31,12 @@
31
31
  "license": "MIT",
32
32
  "dependencies": {},
33
33
  "devDependencies": {
34
- "expo-module-scripts": "^4.1.3"
34
+ "expo-module-scripts": "^4.1.5"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "expo": "*",
38
38
  "react": "*",
39
39
  "react-native": "*"
40
40
  },
41
- "gitHead": "f9236bc90dd9a04605c77070a2d06cb151c31c53"
41
+ "gitHead": "4e542b7b761cfea341d554dd7958103aff5f68c6"
42
42
  }
@@ -1,3 +1,8 @@
1
1
  import { requireNativeViewManager } from 'expo-modules-core';
2
+ import { Platform } from 'react-native';
2
3
 
3
- export default requireNativeViewManager('ExpoVideo');
4
+ const defaultViewName = Platform.OS === 'android' ? 'SurfaceVideoView' : 'VideoView';
5
+
6
+ export default requireNativeViewManager('ExpoVideo', defaultViewName);
7
+ export const NativeTextureVideoView =
8
+ Platform.OS === 'android' ? requireNativeViewManager('ExpoVideo', 'TextureVideoView') : null;
package/src/VideoView.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ReactNode, PureComponent, createRef } from 'react';
2
2
 
3
3
  import NativeVideoModule from './NativeVideoModule';
4
- import NativeVideoView from './NativeVideoView';
4
+ import NativeVideoView, { NativeTextureVideoView } from './NativeVideoView';
5
5
  import type { VideoPlayer } from './VideoPlayer.types';
6
6
  import type { VideoViewProps } from './VideoView.types';
7
7
 
@@ -64,6 +64,9 @@ export class VideoView extends PureComponent<VideoViewProps> {
64
64
  const { player, ...props } = this.props;
65
65
  const playerId = getPlayerId(player);
66
66
 
67
+ if (NativeTextureVideoView && this.props.surfaceType === 'textureView') {
68
+ return <NativeTextureVideoView {...props} player={playerId} ref={this.nativeRef} />;
69
+ }
67
70
  return <NativeVideoView {...props} player={playerId} ref={this.nativeRef} />;
68
71
  }
69
72
  }
@@ -10,6 +10,16 @@ import type { VideoPlayer } from './VideoPlayer.types';
10
10
  */
11
11
  export type VideoContentFit = 'contain' | 'cover' | 'fill';
12
12
 
13
+ /**
14
+ * Describes the type of the surface used to render the video.
15
+ * - `surfaceView`: Uses the `SurfaceView` to render the video. This value should be used in the majority of cases. Provides significantly lower power consumption, better performance, and more features.
16
+ * - `textureView`: Uses the `TextureView` to render the video. Should be used in cases where the SurfaceView is not supported or causes issues (for example, overlapping video views).
17
+ *
18
+ * You can learn more about surface types in the official [ExoPlayer documentation](https://developer.android.com/media/media3/ui/playerview#surfacetype).
19
+ * @platform android
20
+ */
21
+ export type SurfaceType = 'textureView' | 'surfaceView';
22
+
13
23
  export interface VideoViewProps extends ViewProps {
14
24
  /**
15
25
  * A video player instance. Use [`useVideoPlayer()`](#usevideoplayersource-setup) hook to create one.
@@ -50,6 +60,14 @@ export interface VideoViewProps extends ViewProps {
50
60
  */
51
61
  requiresLinearPlayback?: boolean;
52
62
 
63
+ /**
64
+ * Determines the type of the surface used to render the video.
65
+ * > This prop should not be changed at runtime.
66
+ * @default 'surfaceView'
67
+ * @platform android
68
+ */
69
+ surfaceType?: SurfaceType;
70
+
53
71
  /**
54
72
  * Determines the position offset of the video inside the container.
55
73
  * @default { dx: 0, dy: 0 }
@@ -83,6 +101,12 @@ export interface VideoViewProps extends ViewProps {
83
101
  */
84
102
  allowsPictureInPicture?: boolean;
85
103
 
104
+ /**
105
+ * Determines whether a video should be played "inline", that is, within the element's playback area.
106
+ * @platform web
107
+ */
108
+ playsInline?: boolean;
109
+
86
110
  /**
87
111
  * Determines whether the player should start Picture in Picture (PiP) automatically when the app is in the background.
88
112
  * > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.
@@ -205,6 +205,7 @@ export const VideoView = forwardRef((props: { player?: VideoPlayer } & VideoView
205
205
  }
206
206
  }}
207
207
  disablePictureInPicture={!props.allowsPictureInPicture}
208
+ playsInline={props.playsInline}
208
209
  src={getSourceUri(props.player?.src) ?? ''}
209
210
  />
210
211
  );
package/src/index.ts CHANGED
@@ -7,7 +7,7 @@ export {
7
7
  export { VideoView } from './VideoView';
8
8
  export { useVideoPlayer } from './VideoPlayer';
9
9
 
10
- export { VideoContentFit, VideoViewProps } from './VideoView.types';
10
+ export { VideoContentFit, VideoViewProps, SurfaceType } from './VideoView.types';
11
11
  export { VideoThumbnail } from './VideoThumbnail';
12
12
 
13
13
  export { createVideoPlayer } from './VideoPlayer';
@@ -1 +0,0 @@
1
- 963f16122f1193f3a6a4b1be63a5899ac7a6c8d48363e8fafc5f62b1b4c0a1d4
@@ -1 +0,0 @@
1
- 44097ffc761e959398af7069772cdc2b148b5fe7ea322601da4731478e2158169bdcec09c03ce99cbe348d3713d0a4a40196a5529090aa834fd899b4bc188032
@@ -1 +0,0 @@
1
- 2f954ac5045eedab842522c022af40ea6580ad39
@@ -1 +0,0 @@
1
- 595cb598ff7ae7534558ad15beb02c4ba4b83b1a24424280264fec3655268dff
@@ -1 +0,0 @@
1
- 7775cae977666dbaa83a2504564237fb275f3ae91edab1751b0773479213f56b4aa8be1a034c845ea8d97e2fe71d80b495a1cf16a4629080c12be9d759949cb7
@@ -1 +0,0 @@
1
- 1f71c00b6e7df20ea32e6410617ecaf82a175a0a
@@ -1 +0,0 @@
1
- cecbd86ebf6bb4a10e1a10d4c3859fa316346e294a25ff7fc22f3c8437bce59f
@@ -1 +0,0 @@
1
- ae1af8fb047a25be0d75cae271145ef209592284fbd2b365c699aa830f809b2b332bcf68ed99f6d3e16895bd57761b57c340b94b1080934c4f79535c43730570
@@ -1 +0,0 @@
1
- c051b6b7f99bfce92525c642a323c990d6bf07f7
@@ -1 +0,0 @@
1
- 78d2fed35fd926c0bcecfa72f632b7114650c4c1d52516e7ef069a74e3426573
@@ -1 +0,0 @@
1
- 748ec5f3dfc817b0f983b14ef88e13b869ab1bf62eac6c09ce228c05190efa533023b0de2666a4528ea8bdf0762c90b6ac5f1590803b581a965ef2eb5aa56dfe