expo-video 55.0.4 → 55.0.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 (84) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/video/FullscreenPlayerActivity.kt +6 -3
  4. package/android/src/main/java/expo/modules/video/PlayerViewExtension.kt +51 -0
  5. package/android/src/main/java/expo/modules/video/VideoCache.kt +5 -1
  6. package/android/src/main/java/expo/modules/video/VideoModule.kt +8 -5
  7. package/android/src/main/java/expo/modules/video/VideoView.kt +26 -4
  8. package/android/src/main/java/expo/modules/video/managers/VideoManager.kt +5 -3
  9. package/android/src/main/java/expo/modules/video/player/FirstFrameEventGenerator.kt +5 -7
  10. package/android/src/main/java/expo/modules/video/player/VideoPlayer.kt +31 -9
  11. package/android/src/main/java/expo/modules/video/records/ButtonOptions.kt +15 -0
  12. package/android/src/main/java/expo/modules/video/records/PlayerBuilderOptions.kt +13 -0
  13. package/build/VideoPlayer.d.ts +6 -4
  14. package/build/VideoPlayer.d.ts.map +1 -1
  15. package/build/VideoPlayer.js +9 -6
  16. package/build/VideoPlayer.js.map +1 -1
  17. package/build/VideoPlayer.types.d.ts +20 -1
  18. package/build/VideoPlayer.types.d.ts.map +1 -1
  19. package/build/VideoPlayer.types.js.map +1 -1
  20. package/build/VideoView.types.d.ts +61 -0
  21. package/build/VideoView.types.d.ts.map +1 -1
  22. package/build/VideoView.types.js.map +1 -1
  23. package/build/index.d.ts +1 -1
  24. package/build/index.d.ts.map +1 -1
  25. package/build/index.js.map +1 -1
  26. package/expo-module.config.json +1 -1
  27. package/ios/Cache/CachedResource.swift +74 -7
  28. package/ios/Cache/CachingHelpers.swift +24 -9
  29. package/ios/Cache/MediaFileHandle.swift +54 -9
  30. package/ios/Cache/MediaInfo.swift +65 -22
  31. package/ios/Cache/ResourceLoaderDelegate.swift +38 -6
  32. package/ios/Cache/VideoCacheManager.swift +1 -1
  33. package/ios/NowPlayingManager.swift +2 -2
  34. package/ios/VideoAsset.swift +7 -7
  35. package/ios/VideoManager.swift +2 -2
  36. package/ios/VideoModule.swift +1 -1
  37. package/ios/VideoPlayerItem.swift +2 -2
  38. package/local-maven-repo/host/exp/exponent/expo.modules.video/{55.0.4/expo.modules.video-55.0.4-sources.jar → 55.0.6/expo.modules.video-55.0.6-sources.jar} +0 -0
  39. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6-sources.jar.md5 +1 -0
  40. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6-sources.jar.sha1 +1 -0
  41. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6-sources.jar.sha256 +1 -0
  42. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6-sources.jar.sha512 +1 -0
  43. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.aar +0 -0
  44. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.aar.md5 +1 -0
  45. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.aar.sha1 +1 -0
  46. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.aar.sha256 +1 -0
  47. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.aar.sha512 +1 -0
  48. package/local-maven-repo/host/exp/exponent/expo.modules.video/{55.0.4/expo.modules.video-55.0.4.module → 55.0.6/expo.modules.video-55.0.6.module} +22 -22
  49. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.module.md5 +1 -0
  50. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.module.sha1 +1 -0
  51. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.module.sha256 +1 -0
  52. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.module.sha512 +1 -0
  53. package/local-maven-repo/host/exp/exponent/expo.modules.video/{55.0.4/expo.modules.video-55.0.4.pom → 55.0.6/expo.modules.video-55.0.6.pom} +1 -1
  54. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.pom.md5 +1 -0
  55. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.pom.sha1 +1 -0
  56. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.pom.sha256 +1 -0
  57. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.6/expo.modules.video-55.0.6.pom.sha512 +1 -0
  58. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml +4 -4
  59. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.md5 +1 -1
  60. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha1 +1 -1
  61. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha256 +1 -1
  62. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha512 +1 -1
  63. package/package.json +2 -2
  64. package/src/VideoPlayer.tsx +14 -7
  65. package/src/VideoPlayer.types.ts +26 -1
  66. package/src/VideoView.types.ts +63 -0
  67. package/src/index.ts +6 -1
  68. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4-sources.jar.md5 +0 -1
  69. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4-sources.jar.sha1 +0 -1
  70. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4-sources.jar.sha256 +0 -1
  71. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4-sources.jar.sha512 +0 -1
  72. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.aar +0 -0
  73. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.aar.md5 +0 -1
  74. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.aar.sha1 +0 -1
  75. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.aar.sha256 +0 -1
  76. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.aar.sha512 +0 -1
  77. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.module.md5 +0 -1
  78. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.module.sha1 +0 -1
  79. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.module.sha256 +0 -1
  80. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.module.sha512 +0 -1
  81. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.pom.md5 +0 -1
  82. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.pom.sha1 +0 -1
  83. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.pom.sha256 +0 -1
  84. package/local-maven-repo/host/exp/exponent/expo.modules.video/55.0.4/expo.modules.video-55.0.4.pom.sha512 +0 -1
package/CHANGELOG.md CHANGED
@@ -10,6 +10,29 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.0.6 — 2026-02-16
14
+
15
+ ### 🛠 Breaking changes
16
+
17
+ - [Android] The next and previous buttons are now hidden by default in the native `VideoView` controls. ([#42875](https://github.com/expo/expo/pull/42875) by [@behenate](https://github.com/behenate))
18
+
19
+ ### 🎉 New features
20
+
21
+ - [Android] Add `buttonConfiguration` prop to `VideoView`. ([#42875](https://github.com/expo/expo/pull/42875) by [@behenate](https://github.com/behenate))
22
+ - [Android] Add `PlayerBuilderOptions` parameter to `useVideoPlayer` hook to configure seek backward/forward increments. ([#43043](https://github.com/expo/expo/pull/43043) by [@behenate](https://github.com/behenate))
23
+
24
+ ### 🐛 Bug fixes
25
+
26
+ - [Android] Fix only one player getting released when reloading with multiple players present. ([#42780](https://github.com/expo/expo/pull/42780) by [@behenate](https://github.com/behenate))
27
+ - [iOS] Fix data getting corrupted when caching is enabled. ([#42621](https://github.com/expo/expo/pull/42621) by [@behenate](https://github.com/behenate))
28
+
29
+ ## 55.0.5 — 2026-02-08
30
+
31
+ ### 🐛 Bug fixes
32
+
33
+ - [iOS] Prevents blocking main thread when loading asset tracks for non-HSL tracks ([#42037](https://github.com/expo/expo/pull/42037) by [@santitopo](https://github.com/santitopo))
34
+ - [Android] Fix crash due to `SimpleCache` directory lock conflicts. ([#42723](https://github.com/expo/expo/pull/42723) by [@santitopo](https://github.com/santitopo))
35
+
13
36
  ## 55.0.4 — 2026-02-03
14
37
 
15
38
  ### 🐛 Bug fixes
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '55.0.4'
7
+ version = '55.0.6'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.video"
11
11
  defaultConfig {
12
12
  versionCode 1
13
- versionName '55.0.4'
13
+ versionName '55.0.6'
14
14
  }
15
15
  }
16
16
 
@@ -94,13 +94,16 @@ class FullscreenPlayerActivity : Activity() {
94
94
  super.onPostCreate(savedInstanceState)
95
95
  hideStatusBar()
96
96
  setupFullscreenButton()
97
- playerView.applyRequiresLinearPlayback(videoPlayer?.requiresLinearPlayback ?: false)
97
+ val requiresLinearPlayback = videoPlayer?.requiresLinearPlayback ?: false
98
+ val buttonConfig = videoView.buttonOptions.copy(showBottomBar = true) // Always show bottom bar in fullscreen mode so user can exit
99
+ playerView.applyButtonOptions(buttonConfig, requiresLinearPlayback)
100
+ playerView.setTimeBarInteractive(requiresLinearPlayback)
98
101
  playerView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
99
102
  // On every re-layout ExoPlayer makes the timeBar interactive.
100
103
  // We need to disable it to keep scrubbing off.
101
- playerView.setTimeBarInteractive(videoPlayer?.requiresLinearPlayback ?: true)
104
+ playerView.setTimeBarInteractive(requiresLinearPlayback)
102
105
  }
103
- playerView.setShowSubtitleButton(videoView.showsSubtitlesButton)
106
+ playerView.setShowSubtitleButton(videoView.buttonOptions.showSubtitles ?: videoView.currentTrackHasSubtitles)
104
107
 
105
108
  // Configure subtitle view to fix sizing issues with embedded styles (same as VideoView)
106
109
  SubtitleUtils.configureSubtitleView(playerView, this)
@@ -34,3 +34,54 @@ internal fun PlayerView.setFullscreenButtonVisibility(visible: Boolean) {
34
34
  android.view.View.GONE
35
35
  }
36
36
  }
37
+
38
+ @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
39
+ internal fun PlayerView.setSettingsButtonVisibility(visible: Boolean) {
40
+ val settingsButton = findViewById<android.widget.ImageButton>(androidx.media3.ui.R.id.exo_settings)
41
+ settingsButton?.visibility = if (visible) {
42
+ android.view.View.VISIBLE
43
+ } else {
44
+ android.view.View.GONE
45
+ }
46
+ }
47
+
48
+ @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
49
+ internal fun PlayerView.setPlayPauseButtonVisibility(visible: Boolean) {
50
+ val playPauseButton = findViewById<android.widget.ImageButton>(androidx.media3.ui.R.id.exo_play_pause)
51
+ playPauseButton?.visibility = if (visible) {
52
+ android.view.View.VISIBLE
53
+ } else {
54
+ android.view.View.GONE
55
+ }
56
+ }
57
+
58
+ @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
59
+ internal fun PlayerView.setBottomBarVisibility(visible: Boolean) {
60
+ val bottomBar = findViewById<android.view.ViewGroup>(androidx.media3.ui.R.id.exo_bottom_bar)
61
+ bottomBar?.visibility = if (visible) {
62
+ android.view.View.VISIBLE
63
+ } else {
64
+ android.view.View.GONE
65
+ }
66
+
67
+ val progressBar = findViewById<DefaultTimeBar>(androidx.media3.ui.R.id.exo_progress)
68
+ progressBar?.visibility = if (visible) {
69
+ android.view.View.VISIBLE
70
+ } else {
71
+ android.view.View.GONE
72
+ }
73
+ }
74
+
75
+ @androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
76
+ internal fun PlayerView.applyButtonOptions(
77
+ config: expo.modules.video.records.ButtonOptions,
78
+ requiresLinearPlayback: Boolean = false
79
+ ) {
80
+ setShowFastForwardButton(!requiresLinearPlayback && config.showSeekForward)
81
+ setShowRewindButton(!requiresLinearPlayback && config.showSeekBackward)
82
+ setShowPreviousButton(!requiresLinearPlayback && config.showPrevious)
83
+ setShowNextButton(!requiresLinearPlayback && config.showNext)
84
+ setSettingsButtonVisibility(config.showSettings)
85
+ setPlayPauseButtonVisibility(config.showPlayPause)
86
+ setBottomBarVisibility(config.showBottomBar)
87
+ }
@@ -38,6 +38,10 @@ class VideoCache(context: Context) {
38
38
  return sharedPreferences.getLong(CACHE_SIZE_KEY, DEFAULT_CACHE_SIZE)
39
39
  }
40
40
 
41
+ fun release() {
42
+ instance.release()
43
+ }
44
+
41
45
  fun setMaxCacheSize(size: Long) {
42
46
  assertModificationReleaseConditions()
43
47
  instance.release()
@@ -55,7 +59,7 @@ class VideoCache(context: Context) {
55
59
  // Weird structure, because kotlin marks the result of `getString` as nullable
56
60
  val videoCacheDirName = sharedPreferences.getString(VIDEO_CACHE_DIR_KEY, null) ?: run {
57
61
  val newCacheDirName = generateCacheDirName()
58
- sharedPreferences.edit().putString(VIDEO_CACHE_DIR_KEY, newCacheDirName).apply()
62
+ sharedPreferences.edit().putString(VIDEO_CACHE_DIR_KEY, newCacheDirName).commit()
59
63
  newCacheDirName
60
64
  }
61
65
  val cacheParentDir = File(context.cacheDir, VIDEO_CACHE_PARENT_DIR)
@@ -19,6 +19,8 @@ import expo.modules.video.enums.AudioMixingMode
19
19
  import expo.modules.video.enums.ContentFit
20
20
  import expo.modules.video.player.VideoPlayer
21
21
  import expo.modules.video.records.BufferOptions
22
+ import expo.modules.video.records.PlayerBuilderOptions
23
+ import expo.modules.video.records.ButtonOptions
22
24
  import expo.modules.video.records.FullscreenOptions
23
25
  import expo.modules.video.records.SubtitleTrack
24
26
  import expo.modules.video.records.AudioTrack
@@ -72,8 +74,8 @@ class VideoModule : Module() {
72
74
  }
73
75
 
74
76
  Class(VideoPlayer::class) {
75
- Constructor { source: VideoSource? ->
76
- val player = VideoPlayer(appContext.throwingActivity.applicationContext, appContext, source)
77
+ Constructor { source: VideoSource?, /* useSynchronousReplace - iOS-only */ _: Boolean?, playerBuilderOptions: PlayerBuilderOptions? ->
78
+ val player = VideoPlayer(appContext.throwingActivity.applicationContext, appContext, source, playerBuilderOptions)
77
79
  appContext.mainQueue.launch {
78
80
  player.prepare()
79
81
  }
@@ -410,9 +412,10 @@ private inline fun <reified T : VideoView> ViewDefinitionBuilder<T>.VideoViewCom
410
412
  }
411
413
  }
412
414
  Prop("requiresLinearPlayback") { view: T, requiresLinearPlayback: Boolean? ->
413
- val linearPlayback = requiresLinearPlayback ?: false
414
- view.playerView.applyRequiresLinearPlayback(linearPlayback)
415
- view.videoPlayer?.requiresLinearPlayback = linearPlayback
415
+ view.requiresLinearPlayback = requiresLinearPlayback ?: false
416
+ }
417
+ Prop("buttonOptions") { view: T, buttonOptions: ButtonOptions? ->
418
+ view.buttonOptions = buttonOptions ?: ButtonOptions()
416
419
  }
417
420
  Prop("useExoShutter") { view: T, useExoShutter: Boolean? ->
418
421
  view.useExoShutter = useExoShutter
@@ -26,6 +26,7 @@ import expo.modules.video.player.VideoPlayer
26
26
  import expo.modules.video.listeners.VideoPlayerListener
27
27
  import expo.modules.video.listeners.VideoViewListener
28
28
  import expo.modules.video.records.AudioTrack
29
+ import expo.modules.video.records.ButtonOptions
29
30
  import expo.modules.video.records.SubtitleTrack
30
31
  import expo.modules.video.records.VideoSource
31
32
  import expo.modules.video.records.VideoTrack
@@ -57,11 +58,25 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
57
58
  var wasAutoPaused: Boolean = false
58
59
  var isInFullscreen: Boolean = false
59
60
  private set
60
- var showsSubtitlesButton = false
61
+ var currentTrackHasSubtitles = false
61
62
  private set
62
63
  var showsAudioTracksButton = false
63
64
  private set
64
65
 
66
+ var requiresLinearPlayback: Boolean = false
67
+ set(value) {
68
+ field = value
69
+ videoPlayer?.requiresLinearPlayback = value
70
+ playerView.applyRequiresLinearPlayback(value)
71
+ applyButtonSettings()
72
+ }
73
+
74
+ var buttonOptions: ButtonOptions = ButtonOptions()
75
+ set(value) {
76
+ field = value
77
+ applyButtonSettings()
78
+ }
79
+
65
80
  private var listeners = mutableListOf<WeakReference<VideoViewListener>>()
66
81
  private val currentActivity = appContext.throwingActivity
67
82
  private val decorView = currentActivity.window.decorView
@@ -131,8 +146,9 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
131
146
 
132
147
  var useNativeControls: Boolean = true
133
148
  set(value) {
149
+ val shouldShowSubtitle = value && (buttonOptions.showSubtitles ?: currentTrackHasSubtitles)
134
150
  playerView.useController = value
135
- playerView.setShowSubtitleButton(value)
151
+ playerView.setShowSubtitleButton(shouldShowSubtitle)
136
152
  field = value
137
153
  }
138
154
 
@@ -291,9 +307,9 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
291
307
  }
292
308
 
293
309
  override fun onTracksChanged(player: VideoPlayer, tracks: Tracks) {
294
- showsSubtitlesButton = player.subtitles.availableSubtitleTracks.isNotEmpty()
310
+ currentTrackHasSubtitles = player.subtitles.availableSubtitleTracks.isNotEmpty()
295
311
  showsAudioTracksButton = player.audioTracks.availableAudioTracks.size > 1
296
- playerView.setShowSubtitleButton(showsSubtitlesButton)
312
+ playerView.setShowSubtitleButton(buttonOptions.showSubtitles ?: currentTrackHasSubtitles)
297
313
  super.onTracksChanged(player, tracks)
298
314
  }
299
315
 
@@ -407,6 +423,12 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
407
423
  }
408
424
  }
409
425
 
426
+ private fun applyButtonSettings() {
427
+ val shouldShowSubtitle = buttonOptions.showSubtitles ?: currentTrackHasSubtitles
428
+ playerView.applyButtonOptions(buttonOptions, requiresLinearPlayback)
429
+ playerView.setShowSubtitleButton(shouldShowSubtitle)
430
+ }
431
+
410
432
  companion object {
411
433
  fun isPictureInPictureSupported(currentActivity: Activity): Boolean {
412
434
  return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && currentActivity.packageManager.hasSystemFeature(
@@ -34,18 +34,20 @@ object VideoManager {
34
34
 
35
35
  private var listeners = mutableListOf<WeakReference<VideoManagerListener>>()
36
36
 
37
- fun onModuleCreated(appContext: AppContext) {
37
+ fun onModuleCreated(appContext: AppContext) = synchronized(this) {
38
38
  val context = appContext.reactContext ?: throw Exceptions.ReactContextLost()
39
- this.appContext = WeakReference(appContext)
40
39
 
41
40
  this.pictureInPicture = PictureInPictureManager(appContext)
42
-
43
41
  if (!this::audioFocusManager.isInitialized) {
44
42
  audioFocusManager = AudioFocusManager(appContext)
45
43
  }
46
44
  if (!this::cache.isInitialized) {
47
45
  cache = VideoCache(context)
46
+ } else if (this.appContext.get()?.reactContext != appContext.reactContext) {
47
+ cache.release()
48
+ cache = VideoCache(context)
48
49
  }
50
+ this.appContext = WeakReference(appContext)
49
51
  }
50
52
 
51
53
  fun onModuleDestroyed(appContext: AppContext) {
@@ -28,10 +28,9 @@ internal class FirstFrameEventGenerator(
28
28
  appContext: AppContext,
29
29
  videoPlayer: VideoPlayer,
30
30
  private val currentViewReference: MutableWeakReference<VideoView?>,
31
- private val onFirstFrameRendered: () -> Unit
31
+ private var onFirstFrameRendered: (() -> Unit)?
32
32
  ) : Player.Listener, VideoPlayerListener {
33
33
  private val videoPlayerReference = WeakReference(videoPlayer)
34
- private val weakAppContext = WeakReference(appContext)
35
34
  private var hasPendingOnFirstFrame = false
36
35
  internal var hasSentFirstFrameForCurrentMediaItem = false
37
36
  private set
@@ -45,12 +44,11 @@ internal class FirstFrameEventGenerator(
45
44
  }
46
45
  }
47
46
 
47
+ @MainThread
48
48
  fun release() {
49
49
  videoPlayerReference.get()?.removeListener(this)
50
-
51
- weakAppContext.get()?.mainQueue?.launch {
52
- videoPlayerReference.get()?.player?.removeListener(this@FirstFrameEventGenerator)
53
- }
50
+ videoPlayerReference.get()?.player?.removeListener(this)
51
+ onFirstFrameRendered = null
54
52
  }
55
53
 
56
54
  override fun onRenderedFirstFrame() {
@@ -80,7 +78,7 @@ internal class FirstFrameEventGenerator(
80
78
  // We want to match the behavior across platforms, so we limit the number of event emissions.
81
79
  private fun maybeCallOnFirstFrameRendered() {
82
80
  if (!hasSentFirstFrameForCurrentMediaItem || !hasSentFirstFrameForCurrentVideoView) {
83
- onFirstFrameRendered()
81
+ onFirstFrameRendered?.invoke()
84
82
  }
85
83
  hasPendingOnFirstFrame = false
86
84
  hasSentFirstFrameForCurrentMediaItem = true
@@ -47,13 +47,17 @@ import expo.modules.video.records.VideoSource
47
47
  import expo.modules.video.utils.MutableWeakReference
48
48
  import expo.modules.video.records.VideoTrack
49
49
  import expo.modules.video.utils.buildBasicMediaSession
50
+ import kotlinx.coroutines.DelicateCoroutinesApi
51
+ import kotlinx.coroutines.Dispatchers
52
+ import kotlinx.coroutines.GlobalScope
50
53
  import kotlinx.coroutines.launch
51
54
  import java.io.FileInputStream
52
55
  import java.lang.ref.WeakReference
56
+ import kotlin.time.DurationUnit
53
57
 
54
58
  // https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide#improvements_in_media3
55
59
  @UnstableApi
56
- class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSource?) : AutoCloseable, SharedObject(appContext), IntervalUpdateEmitter {
60
+ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSource?, playerBuilderOptions: expo.modules.video.records.PlayerBuilderOptions? = null) : AutoCloseable, SharedObject(appContext), IntervalUpdateEmitter {
57
61
  // This improves the performance of playing DRM-protected content
58
62
  private var renderersFactory = DefaultRenderersFactory(context)
59
63
  .forceEnableMediaCodecAsynchronousQueueing()
@@ -70,9 +74,16 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
70
74
 
71
75
  val player = ExoPlayer
72
76
  .Builder(context, renderersFactory)
73
- .setLooper(context.mainLooper)
74
- .setLoadControl(loadControl)
75
- .build()
77
+ .apply {
78
+ setLooper(context.mainLooper)
79
+ setLoadControl(loadControl)
80
+ playerBuilderOptions?.seekBackwardIncrement?.let {
81
+ setSeekBackIncrementMs((it).toLong(DurationUnit.MILLISECONDS).coerceIn(1, 999_000))
82
+ }
83
+ playerBuilderOptions?.seekForwardIncrement?.let {
84
+ setSeekForwardIncrementMs((it).toLong(DurationUnit.MILLISECONDS).coerceIn(1, 999_000))
85
+ }
86
+ }.build()
76
87
 
77
88
  internal val firstFrameEventGenerator: FirstFrameEventGenerator
78
89
  val serviceConnection = PlaybackServiceConnection(WeakReference(this), appContext)
@@ -346,7 +357,17 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
346
357
  }
347
358
  }
348
359
 
360
+ @kotlin.OptIn(DelicateCoroutinesApi::class)
349
361
  override fun close() {
362
+ // Releases the listeners from VideoPlayerKeepAwake
363
+ keepScreenOnWhilePlaying = false
364
+
365
+ intervalUpdateClock.interval = 0L
366
+
367
+ synchronized(listeners) {
368
+ listeners.clear()
369
+ }
370
+
350
371
  if (serviceConnection.isConnected) {
351
372
  appContext?.reactContext?.unbindService(serviceConnection)
352
373
  }
@@ -355,19 +376,20 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
355
376
 
356
377
  VideoManager.unregisterVideoPlayer(this@VideoPlayer)
357
378
 
358
- appContext?.mainQueue?.launch {
379
+ // Run on global scope (not appContext.mainQueue) so that reloading doesn't cancel the release process
380
+ // https://github.com/expo/expo/blob/cdf592a7fea56fc01b0149e9b2e5dbd294bcdc4c/packages/expo-modules-core/android/src/main/java/expo/modules/kotlin/AppContext.kt#L277-L279
381
+ GlobalScope.launch(Dispatchers.Main) {
359
382
  firstFrameEventGenerator.release()
360
383
  player.removeListener(playerListener)
384
+ player.removeAnalyticsListener(analyticsListener)
361
385
  player.release()
362
386
  }
363
387
  uncommittedSource = null
364
388
  commitedSource = null
365
- // Releases the listeners from VideoPlayerKeepAwake
366
- keepScreenOnWhilePlaying = false
367
389
  }
368
390
 
369
- override fun deallocate() {
370
- super.deallocate()
391
+ override fun sharedObjectDidRelease() {
392
+ super.sharedObjectDidRelease()
371
393
  close()
372
394
  }
373
395
 
@@ -0,0 +1,15 @@
1
+ package expo.modules.video.records
2
+
3
+ import expo.modules.kotlin.records.Field
4
+ import expo.modules.kotlin.records.Record
5
+
6
+ data class ButtonOptions(
7
+ @Field val showNext: Boolean = false,
8
+ @Field val showPrevious: Boolean = false,
9
+ @Field val showSeekForward: Boolean = true,
10
+ @Field val showSeekBackward: Boolean = true,
11
+ @Field val showSubtitles: Boolean? = null,
12
+ @Field val showSettings: Boolean = true,
13
+ @Field val showPlayPause: Boolean = true,
14
+ @Field val showBottomBar: Boolean = true
15
+ ) : Record
@@ -0,0 +1,13 @@
1
+ package expo.modules.video.records
2
+
3
+ import androidx.media3.common.util.UnstableApi
4
+ import expo.modules.kotlin.records.Field
5
+ import expo.modules.kotlin.records.Record
6
+ import java.io.Serializable
7
+ import kotlin.time.Duration
8
+
9
+ @UnstableApi
10
+ class PlayerBuilderOptions(
11
+ @Field var seekBackwardIncrement: Duration? = null,
12
+ @Field var seekForwardIncrement: Duration? = null
13
+ ) : Record, Serializable
@@ -1,15 +1,17 @@
1
- import { VideoSource, VideoPlayer } from './VideoPlayer.types';
1
+ import { VideoSource, VideoPlayer, PlayerBuilderOptions } from './VideoPlayer.types';
2
2
  /**
3
3
  * Creates a direct instance of `VideoPlayer` that doesn't release automatically.
4
4
  *
5
5
  * > **info** For most use cases you should use the [`useVideoPlayer`](#usevideoplayer) hook instead. See the [Using the VideoPlayer Directly](#using-the-videoplayer-directly) section for more details.
6
- * @param source
6
+ * @param source - A video source that is used to initialize the player.
7
+ * @param playerBuilderOptions - Options to apply to the Android player builder before the native constructor is invoked.
7
8
  */
8
- export declare function createVideoPlayer(source: VideoSource): VideoPlayer;
9
+ export declare function createVideoPlayer(source: VideoSource, playerBuilderOptions?: PlayerBuilderOptions): VideoPlayer;
9
10
  /**
10
11
  * Creates a `VideoPlayer`, which will be automatically cleaned up when the component is unmounted.
11
12
  * @param source - A video source that is used to initialize the player.
12
13
  * @param setup - A function that allows setting up the player. It will run after the player is created.
14
+ * @param playerBuilderOptions - Options to apply to the Android player builder before the native constructor is invoked.
13
15
  */
14
- export declare function useVideoPlayer(source: VideoSource, setup?: (player: VideoPlayer) => void): VideoPlayer;
16
+ export declare function useVideoPlayer(source: VideoSource, setup?: (player: VideoPlayer) => void, playerBuilderOptions?: PlayerBuilderOptions): VideoPlayer;
15
17
  //# sourceMappingURL=VideoPlayer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VideoPlayer.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAsB/D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAElE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACpC,WAAW,CAQb"}
1
+ {"version":3,"file":"VideoPlayer.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAsBrF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,oBAAoB,CAAC,EAAE,oBAAoB,GAC1C,WAAW,CAGb;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,EACrC,oBAAoB,CAAC,EAAE,oBAAoB,GAC1C,WAAW,CAQb"}
@@ -17,23 +17,26 @@ NativeVideoModule.VideoPlayer.prototype.replaceAsync = function (source) {
17
17
  * Creates a direct instance of `VideoPlayer` that doesn't release automatically.
18
18
  *
19
19
  * > **info** For most use cases you should use the [`useVideoPlayer`](#usevideoplayer) hook instead. See the [Using the VideoPlayer Directly](#using-the-videoplayer-directly) section for more details.
20
- * @param source
20
+ * @param source - A video source that is used to initialize the player.
21
+ * @param playerBuilderOptions - Options to apply to the Android player builder before the native constructor is invoked.
21
22
  */
22
- export function createVideoPlayer(source) {
23
- return new NativeVideoModule.VideoPlayer(parseSource(source));
23
+ export function createVideoPlayer(source, playerBuilderOptions) {
24
+ const parsedSource = parseSource(source);
25
+ return new NativeVideoModule.VideoPlayer(parsedSource, false, playerBuilderOptions);
24
26
  }
25
27
  /**
26
28
  * Creates a `VideoPlayer`, which will be automatically cleaned up when the component is unmounted.
27
29
  * @param source - A video source that is used to initialize the player.
28
30
  * @param setup - A function that allows setting up the player. It will run after the player is created.
31
+ * @param playerBuilderOptions - Options to apply to the Android player builder before the native constructor is invoked.
29
32
  */
30
- export function useVideoPlayer(source, setup) {
33
+ export function useVideoPlayer(source, setup, playerBuilderOptions) {
31
34
  const parsedSource = parseSource(source);
32
35
  return useReleasingSharedObject(() => {
33
- const player = new NativeVideoModule.VideoPlayer(parsedSource);
36
+ const player = new NativeVideoModule.VideoPlayer(parsedSource, false, playerBuilderOptions);
34
37
  setup?.(player);
35
38
  return player;
36
- }, [JSON.stringify(parsedSource)]);
39
+ }, [JSON.stringify(parsedSource), JSON.stringify(playerBuilderOptions)]);
37
40
  }
38
41
  function parseSource(source) {
39
42
  if (typeof source === 'number') {
@@ -1 +1 @@
1
- {"version":3,"file":"VideoPlayer.js","sourceRoot":"","sources":["../src/VideoPlayer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AAEpD,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAEtD,4HAA4H;AAC5H,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC;AAChE,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,GAAG,UAChD,MAAmB,EACnB,iBAA0B,KAAK;IAE/B,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CACV,mNAAmN,CACpN,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC;AAC1E,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,GAAG,UAAU,MAAmB;IAClF,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC;AACF;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,OAAO,IAAI,iBAAiB,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAmB,EACnB,KAAqC;IAErC,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAEzC,OAAO,wBAAwB,CAAC,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QAC/D,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,MAAmB;IACtC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,4EAA4E;QAC5E,OAAO,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,CAAE,CAAC,GAAG,EAAE,CAAC;IAClD,CAAC;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,OAAO,MAAM,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACvD,4EAA4E;QAC5E,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAE,CAAC,GAAG,EAAE,CAAC;IACrE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { useReleasingSharedObject } from 'expo-modules-core';\n\nimport NativeVideoModule from './NativeVideoModule';\nimport { VideoSource, VideoPlayer } from './VideoPlayer.types';\nimport resolveAssetSource from './resolveAssetSource';\n\n// TODO: Temporary solution until we develop a way of overriding prototypes that won't break the lazy loading of the module.\nconst replace = NativeVideoModule.VideoPlayer.prototype.replace;\nNativeVideoModule.VideoPlayer.prototype.replace = function (\n source: VideoSource,\n disableWarning: boolean = false\n) {\n if (!disableWarning) {\n console.warn(\n 'On iOS `VideoPlayer.replace` loads the asset data synchronously on the main thread, which can lead to UI freezes and will be deprecated in a future release. Switch to `replaceAsync` for better user experience.'\n );\n }\n\n return replace.call(this, parseSource(source));\n};\n\nconst replaceAsync = NativeVideoModule.VideoPlayer.prototype.replaceAsync;\nNativeVideoModule.VideoPlayer.prototype.replaceAsync = function (source: VideoSource) {\n return replaceAsync.call(this, parseSource(source));\n};\n/**\n * Creates a direct instance of `VideoPlayer` that doesn't release automatically.\n *\n * > **info** For most use cases you should use the [`useVideoPlayer`](#usevideoplayer) hook instead. See the [Using the VideoPlayer Directly](#using-the-videoplayer-directly) section for more details.\n * @param source\n */\nexport function createVideoPlayer(source: VideoSource): VideoPlayer {\n return new NativeVideoModule.VideoPlayer(parseSource(source));\n}\n\n/**\n * Creates a `VideoPlayer`, which will be automatically cleaned up when the component is unmounted.\n * @param source - A video source that is used to initialize the player.\n * @param setup - A function that allows setting up the player. It will run after the player is created.\n */\nexport function useVideoPlayer(\n source: VideoSource,\n setup?: (player: VideoPlayer) => void\n): VideoPlayer {\n const parsedSource = parseSource(source);\n\n return useReleasingSharedObject(() => {\n const player = new NativeVideoModule.VideoPlayer(parsedSource);\n setup?.(player);\n return player;\n }, [JSON.stringify(parsedSource)]);\n}\n\nfunction parseSource(source: VideoSource): VideoSource {\n if (typeof source === 'number') {\n // TODO(@kitten): This seems to not handle the `null` case. Is this correct?\n return { uri: resolveAssetSource(source)!.uri };\n } else if (typeof source === 'string') {\n return { uri: source };\n }\n\n if (typeof source?.assetId === 'number' && !source.uri) {\n // TODO(@kitten): This seems to not handle the `null` case. Is this correct?\n return { ...source, uri: resolveAssetSource(source.assetId)!.uri };\n }\n return source;\n}\n"]}
1
+ {"version":3,"file":"VideoPlayer.js","sourceRoot":"","sources":["../src/VideoPlayer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AAEpD,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAEtD,4HAA4H;AAC5H,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC;AAChE,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,GAAG,UAChD,MAAmB,EACnB,iBAA0B,KAAK;IAE/B,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CACV,mNAAmN,CACpN,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC;AAC1E,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,YAAY,GAAG,UAAU,MAAmB;IAClF,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACtD,CAAC,CAAC;AACF;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAmB,EACnB,oBAA2C;IAE3C,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,IAAI,iBAAiB,CAAC,WAAW,CAAC,YAAY,EAAE,KAAK,EAAE,oBAAoB,CAAC,CAAC;AACtF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAmB,EACnB,KAAqC,EACrC,oBAA2C;IAE3C,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAEzC,OAAO,wBAAwB,CAAC,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,WAAW,CAAC,YAAY,EAAE,KAAK,EAAE,oBAAoB,CAAC,CAAC;QAC5F,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,WAAW,CAAC,MAAmB;IACtC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,4EAA4E;QAC5E,OAAO,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,CAAE,CAAC,GAAG,EAAE,CAAC;IAClD,CAAC;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,OAAO,MAAM,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACvD,4EAA4E;QAC5E,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAE,CAAC,GAAG,EAAE,CAAC;IACrE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { useReleasingSharedObject } from 'expo-modules-core';\n\nimport NativeVideoModule from './NativeVideoModule';\nimport { VideoSource, VideoPlayer, PlayerBuilderOptions } from './VideoPlayer.types';\nimport resolveAssetSource from './resolveAssetSource';\n\n// TODO: Temporary solution until we develop a way of overriding prototypes that won't break the lazy loading of the module.\nconst replace = NativeVideoModule.VideoPlayer.prototype.replace;\nNativeVideoModule.VideoPlayer.prototype.replace = function (\n source: VideoSource,\n disableWarning: boolean = false\n) {\n if (!disableWarning) {\n console.warn(\n 'On iOS `VideoPlayer.replace` loads the asset data synchronously on the main thread, which can lead to UI freezes and will be deprecated in a future release. Switch to `replaceAsync` for better user experience.'\n );\n }\n\n return replace.call(this, parseSource(source));\n};\n\nconst replaceAsync = NativeVideoModule.VideoPlayer.prototype.replaceAsync;\nNativeVideoModule.VideoPlayer.prototype.replaceAsync = function (source: VideoSource) {\n return replaceAsync.call(this, parseSource(source));\n};\n/**\n * Creates a direct instance of `VideoPlayer` that doesn't release automatically.\n *\n * > **info** For most use cases you should use the [`useVideoPlayer`](#usevideoplayer) hook instead. See the [Using the VideoPlayer Directly](#using-the-videoplayer-directly) section for more details.\n * @param source - A video source that is used to initialize the player.\n * @param playerBuilderOptions - Options to apply to the Android player builder before the native constructor is invoked.\n */\nexport function createVideoPlayer(\n source: VideoSource,\n playerBuilderOptions?: PlayerBuilderOptions\n): VideoPlayer {\n const parsedSource = parseSource(source);\n return new NativeVideoModule.VideoPlayer(parsedSource, false, playerBuilderOptions);\n}\n\n/**\n * Creates a `VideoPlayer`, which will be automatically cleaned up when the component is unmounted.\n * @param source - A video source that is used to initialize the player.\n * @param setup - A function that allows setting up the player. It will run after the player is created.\n * @param playerBuilderOptions - Options to apply to the Android player builder before the native constructor is invoked.\n */\nexport function useVideoPlayer(\n source: VideoSource,\n setup?: (player: VideoPlayer) => void,\n playerBuilderOptions?: PlayerBuilderOptions\n): VideoPlayer {\n const parsedSource = parseSource(source);\n\n return useReleasingSharedObject(() => {\n const player = new NativeVideoModule.VideoPlayer(parsedSource, false, playerBuilderOptions);\n setup?.(player);\n return player;\n }, [JSON.stringify(parsedSource), JSON.stringify(playerBuilderOptions)]);\n}\n\nfunction parseSource(source: VideoSource): VideoSource {\n if (typeof source === 'number') {\n // TODO(@kitten): This seems to not handle the `null` case. Is this correct?\n return { uri: resolveAssetSource(source)!.uri };\n } else if (typeof source === 'string') {\n return { uri: source };\n }\n\n if (typeof source?.assetId === 'number' && !source.uri) {\n // TODO(@kitten): This seems to not handle the `null` case. Is this correct?\n return { ...source, uri: resolveAssetSource(source.assetId)!.uri };\n }\n return source;\n}\n"]}
@@ -223,9 +223,10 @@ export declare class VideoPlayer extends SharedObject<VideoPlayerEvents> {
223
223
  *
224
224
  * @param source The source of the video to be played.
225
225
  * @param useSynchronousReplace Optional parameter, when `true` `source` from the first parameter will be loaded on the main thread.
226
+ * @param playerBuilderOptions Options to apply to the player builder before the native constructor is invoked.
226
227
  * @hidden
227
228
  */
228
- constructor(source: VideoSource, useSynchronousReplace?: boolean);
229
+ constructor(source: VideoSource, useSynchronousReplace?: boolean, playerBuilderOptions?: PlayerBuilderOptions);
229
230
  /**
230
231
  * Resumes the player.
231
232
  */
@@ -656,4 +657,22 @@ export type ScrubbingModeOptions = {
656
657
  */
657
658
  allowSkippingMediaCodecFlush?: boolean;
658
659
  };
660
+ /**
661
+ * Options to apply to the player builder before the native constructor is invoked
662
+ * @platform android
663
+ */
664
+ export type PlayerBuilderOptions = {
665
+ /**
666
+ * Seek backward increment in seconds.
667
+ * Values will be clamped between 0.001 and 999 seconds.
668
+ * @platform android
669
+ */
670
+ seekBackwardIncrement?: number;
671
+ /**
672
+ * Seek forward increment in seconds.
673
+ * Values will be clamped between 0.001 and 999 seconds.
674
+ * @platform android
675
+ */
676
+ seekForwardIncrement?: number;
677
+ };
659
678
  //# sourceMappingURL=VideoPlayer.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VideoPlayer.types.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IACtE;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;;;OAIG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAEhC;;;;;;OAMG;IACH,eAAe,EAAE,eAAe,CAAC;IAEjC;;;;OAIG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;;;;;;;OAQG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7C;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9C;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;IAExB;;;;;OAKG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;;;;;;OAQG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAEnC;;;;;;;;OAQG;IACH,0BAA0B,EAAE,OAAO,CAAC;IAEpC;;;;;;;;OAQG;IACH,uBAAuB,EAAE,OAAO,CAAC;IAEjC;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAElC;;;;;;OAMG;IACH,aAAa,EAAE,aAAa,CAAC;IAE7B;;;;;;;;OAQG;IACH,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAEpC;;;;;;OAMG;IACH,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAE9B;;;;;OAKG;IACH,QAAQ,CAAC,oBAAoB,EAAE,UAAU,EAAE,CAAC;IAE5C;;;;;OAKG;IACH,QAAQ,CAAC,uBAAuB,EAAE,aAAa,EAAE,CAAC;IAElD;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAEvC;;;;;;;OAOG;IACH,QAAQ,CAAC,oBAAoB,EAAE,UAAU,EAAE,CAAC;IAE5C;;;;OAIG;IACH,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC;IAE3C;;;;;;;;OAQG;IACH,aAAa,EAAE,aAAa,CAAC;IAE7B;;;;;OAKG;IACH,oBAAoB,EAAE,oBAAoB,CAAC;IAE3C;;;;;;OAMG;gBACS,MAAM,EAAE,WAAW,EAAE,qBAAqB,CAAC,EAAE,OAAO;IAEhE;;OAEG;IACH,IAAI,IAAI,IAAI;IAEZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAEb;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,IAAI;IAE5D;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAEhD;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAE7B;;OAEG;IACH,MAAM,IAAI,IAAI;IAEd;;;;;OAKG;IACH,uBAAuB,CACrB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EACxB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,cAAc,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC;AAE7E,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,iBAAiB,CAAC;AAErE,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,GAAG,CAAC,EAAE,UAAU,CAAC;IAEjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEzB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;;;;;OASG;IACH,QAAQ,CAAC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IAEjD;;;;;;OAMG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAE3C;;;;;;OAMG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAEvC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC;;;;;OAKG;IACH,QAAQ,CAAC,+BAA+B,CAAC,EAAE,OAAO,CAAC;CACpD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,iBAAiB,CAAC;AAEtF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;AAEnF,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,SAAS,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB;;;OAGG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;;;;;;;;;;;;;OAgBG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAC;IAErC;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;OAMG;IACH,4BAA4B,CAAC,EAAE,OAAO,CAAC;CACxC,CAAC"}
1
+ {"version":3,"file":"VideoPlayer.types.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.types.ts"],"names":[],"mappings":"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"}