expo-video 3.1.0-canary-20251031-b135dff → 3.1.0-canary-20251118-4ca99d5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/video/FullscreenPlayerActivity.kt +5 -1
- package/android/src/main/java/expo/modules/video/VideoModule.kt +1 -1
- package/android/src/main/java/expo/modules/video/VideoView.kt +15 -7
- package/android/src/main/java/expo/modules/video/player/FirstFrameEventGenerator.kt +26 -11
- package/android/src/main/java/expo/modules/video/player/PlayerEvent.kt +7 -0
- package/android/src/main/java/expo/modules/video/player/VideoPlayer.kt +22 -6
- package/android/src/main/java/expo/modules/video/player/VideoPlayerListener.kt +2 -0
- package/android/src/main/java/expo/modules/video/utils/MutableWeakReference.kt +13 -2
- package/build/VideoPlayer.web.d.ts +1 -1
- package/build/VideoPlayer.web.d.ts.map +1 -1
- package/build/VideoPlayer.web.js.map +1 -1
- package/build/VideoView.js +1 -1
- package/build/VideoView.js.map +1 -1
- package/build/VideoView.types.d.ts +1 -1
- package/build/VideoView.types.d.ts.map +1 -1
- package/build/VideoView.types.js.map +1 -1
- package/build/VideoView.web.d.ts.map +1 -1
- package/build/VideoView.web.js +11 -3
- package/build/VideoView.web.js.map +1 -1
- package/expo-module.config.json +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/{3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff-sources.jar → 3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5-sources.jar} +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/{3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.module → 3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.module} +22 -22
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/{3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.pom → 3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.pom} +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml +4 -4
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha512 +1 -1
- package/package.json +3 -3
- package/src/VideoPlayer.web.tsx +1 -1
- package/src/VideoView.tsx +1 -1
- package/src/VideoView.types.ts +1 -1
- package/src/VideoView.web.tsx +14 -3
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.1.0-canary-20251031-b135dff/expo.modules.video-3.1.0-canary-20251031-b135dff.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,12 +7,15 @@
|
|
|
7
7
|
### 🎉 New features
|
|
8
8
|
|
|
9
9
|
- [Android][iOS] Add `seek tolerance` and `scrubbingModeOptions` properties to the player. ([#40203](https://github.com/expo/expo/pull/40203) by [@behenate](https://github.com/behenate))
|
|
10
|
+
- Allow assigning `null` value to the `player` prop of the `VideoView` ([#40860](https://github.com/expo/expo/pull/40860) by [@behenate](https://github.com/behenate))
|
|
10
11
|
|
|
11
12
|
### 🐛 Bug fixes
|
|
12
13
|
|
|
13
14
|
- Fix `FOREGROUND_SERVICE_MEDIA_PLAYBACK` being always present in the manifest. ([#40074](https://github.com/expo/expo/pull/40074) by [@behenate](https://github.com/behenate))
|
|
14
15
|
- [iOS] Fix crashes when rapidly replacing HLS sources. ([#40265](https://github.com/expo/expo/pull/40265) by [@behenate](https://github.com/behenate))
|
|
15
16
|
- [Android] Fix the `player` prop of the `VideoView` not working when a player is re-assigned after being replaced by a different player earlier. ([#40709](https://github.com/expo/expo/pull/40709) by [@behenate](https://github.com/behenate))
|
|
17
|
+
- [Android] Fix surface view not showing when changing the `player` prop. ([#40817](https://github.com/expo/expo/pull/40817) by [@behenate](https://github.com/behenate))
|
|
18
|
+
- [Android] Emit `onFirstFrameRender` when player is moved to a new `VideoView` and renders a frame. ([#40854](https://github.com/expo/expo/pull/40854) by [@behenate](https://github.com/behenate))
|
|
16
19
|
|
|
17
20
|
### 💡 Others
|
|
18
21
|
|
package/android/build.gradle
CHANGED
|
@@ -4,13 +4,13 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'host.exp.exponent'
|
|
7
|
-
version = '3.1.0-canary-
|
|
7
|
+
version = '3.1.0-canary-20251118-4ca99d5'
|
|
8
8
|
|
|
9
9
|
android {
|
|
10
10
|
namespace "expo.modules.video"
|
|
11
11
|
defaultConfig {
|
|
12
12
|
versionCode 1
|
|
13
|
-
versionName '3.1.0-canary-
|
|
13
|
+
versionName '3.1.0-canary-20251118-4ca99d5'
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -77,7 +77,11 @@ class FullscreenPlayerActivity : Activity() {
|
|
|
77
77
|
requestedOrientation = options.orientation.toActivityOrientation()
|
|
78
78
|
|
|
79
79
|
videoPlayer = videoView.videoPlayer
|
|
80
|
-
videoPlayer?.
|
|
80
|
+
videoPlayer?.player?.let {
|
|
81
|
+
PlayerView.switchTargetView(it, videoView.playerView, playerView)
|
|
82
|
+
videoPlayer?.hasBeenDisconnectedFromVideoView() // The video player is disconnected. We are only using the ExoPlayer it contained
|
|
83
|
+
}
|
|
84
|
+
|
|
81
85
|
VideoManager.registerFullscreenPlayerActivity(hashCode().toString(), this)
|
|
82
86
|
playerView.player?.let {
|
|
83
87
|
val aspectRatio = calculatePiPAspectRatio(it.videoSize, playerView.width, playerView.height, videoView.contentFit)
|
|
@@ -399,7 +399,7 @@ private inline fun <reified T : VideoView> ViewDefinitionBuilder<T>.VideoViewCom
|
|
|
399
399
|
"onFullscreenExit",
|
|
400
400
|
"onFirstFrameRender"
|
|
401
401
|
)
|
|
402
|
-
Prop("player") { view: T, player: VideoPlayer ->
|
|
402
|
+
Prop("player") { view: T, player: VideoPlayer? ->
|
|
403
403
|
view.videoPlayer = player
|
|
404
404
|
}
|
|
405
405
|
Prop("nativeControls") { view: T, useNativeControls: Boolean ->
|
|
@@ -113,15 +113,21 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
|
|
|
113
113
|
field?.let {
|
|
114
114
|
VideoManager.onVideoPlayerDetachedFromView(it, this)
|
|
115
115
|
}
|
|
116
|
-
videoPlayer
|
|
117
|
-
|
|
116
|
+
val oldPlayer = videoPlayer
|
|
117
|
+
val hasEmittedFirstFrame = newPlayer?.firstFrameEventGenerator?.hasSentFirstFrameForCurrentMediaItem
|
|
118
|
+
?: false
|
|
119
|
+
oldPlayer?.removeListener(this)
|
|
118
120
|
newPlayer?.addListener(this)
|
|
119
121
|
field = newPlayer
|
|
120
|
-
shouldHideSurfaceView =
|
|
122
|
+
shouldHideSurfaceView = !hasEmittedFirstFrame
|
|
123
|
+
applySurfaceViewVisibility()
|
|
121
124
|
attachPlayer()
|
|
122
125
|
newPlayer?.let {
|
|
123
126
|
VideoManager.onVideoPlayerAttachedToView(it, this)
|
|
124
127
|
}
|
|
128
|
+
if (oldPlayer != newPlayer) {
|
|
129
|
+
oldPlayer?.hasBeenDisconnectedFromVideoView()
|
|
130
|
+
}
|
|
125
131
|
}
|
|
126
132
|
|
|
127
133
|
var useNativeControls: Boolean = true
|
|
@@ -215,7 +221,7 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
|
|
|
215
221
|
}
|
|
216
222
|
|
|
217
223
|
fun attachPlayer() {
|
|
218
|
-
videoPlayer?.
|
|
224
|
+
videoPlayer?.changeVideoView(this)
|
|
219
225
|
}
|
|
220
226
|
|
|
221
227
|
fun exitFullscreen() {
|
|
@@ -302,9 +308,11 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
|
|
|
302
308
|
}
|
|
303
309
|
|
|
304
310
|
override fun onRenderedFirstFrame(player: VideoPlayer) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
311
|
+
if (player.currentVideoView == this) {
|
|
312
|
+
shouldHideSurfaceView = false
|
|
313
|
+
applySurfaceViewVisibility()
|
|
314
|
+
onFirstFrameRender(Unit)
|
|
315
|
+
}
|
|
308
316
|
}
|
|
309
317
|
|
|
310
318
|
override fun requestLayout() {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
package expo.modules.video.player
|
|
2
2
|
|
|
3
|
+
import androidx.annotation.MainThread
|
|
3
4
|
import androidx.annotation.OptIn
|
|
4
5
|
import androidx.media3.common.MediaItem
|
|
5
6
|
import androidx.media3.common.Player
|
|
6
7
|
import androidx.media3.common.util.UnstableApi
|
|
7
|
-
import
|
|
8
|
-
import androidx.media3.ui.PlayerView
|
|
8
|
+
import expo.modules.video.VideoView
|
|
9
9
|
import expo.modules.video.enums.ContentFit
|
|
10
10
|
import expo.modules.video.utils.MutableWeakReference
|
|
11
11
|
import java.lang.ref.WeakReference
|
|
@@ -20,17 +20,27 @@ import kotlin.math.abs
|
|
|
20
20
|
* https://github.com/google/ExoPlayer/issues/5222
|
|
21
21
|
*/
|
|
22
22
|
@OptIn(UnstableApi::class)
|
|
23
|
+
@MainThread
|
|
23
24
|
internal class FirstFrameEventGenerator(
|
|
24
|
-
|
|
25
|
-
private val currentViewReference: MutableWeakReference<
|
|
25
|
+
videoPlayer: VideoPlayer,
|
|
26
|
+
private val currentViewReference: MutableWeakReference<VideoView?>,
|
|
26
27
|
private val onFirstFrameRendered: () -> Unit
|
|
27
|
-
) : Player.Listener {
|
|
28
|
-
val
|
|
28
|
+
) : Player.Listener, VideoPlayerListener {
|
|
29
|
+
private val videoPlayerReference = WeakReference(videoPlayer)
|
|
29
30
|
private var hasPendingOnFirstFrame = false
|
|
30
|
-
|
|
31
|
+
internal var hasSentFirstFrameForCurrentMediaItem = false
|
|
32
|
+
private set
|
|
33
|
+
internal var hasSentFirstFrameForCurrentVideoView = false
|
|
34
|
+
private set
|
|
31
35
|
|
|
32
36
|
init {
|
|
33
|
-
player.addListener(this)
|
|
37
|
+
videoPlayer.player.addListener(this)
|
|
38
|
+
videoPlayer.addListener(this)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fun release() {
|
|
42
|
+
videoPlayerReference.get()?.removeListener(this)
|
|
43
|
+
videoPlayerReference.get()?.player?.removeListener(this)
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
override fun onRenderedFirstFrame() {
|
|
@@ -52,20 +62,25 @@ internal class FirstFrameEventGenerator(
|
|
|
52
62
|
}
|
|
53
63
|
}
|
|
54
64
|
|
|
65
|
+
override fun onTargetViewChanged(player: VideoPlayer, newTargetView: VideoView?, oldTargetView: VideoView?) {
|
|
66
|
+
hasSentFirstFrameForCurrentVideoView = false
|
|
67
|
+
}
|
|
68
|
+
|
|
55
69
|
// Unlike iOS, android calls `onRenderedFirstFrame` multiple times for the same media item (after seeking).
|
|
56
70
|
// We want to match the behavior across platforms, so we limit the number of event emissions.
|
|
57
71
|
private fun maybeCallOnFirstFrameRendered() {
|
|
58
|
-
if (!hasSentFirstFrameForCurrentMediaItem) {
|
|
72
|
+
if (!hasSentFirstFrameForCurrentMediaItem || !hasSentFirstFrameForCurrentVideoView) {
|
|
59
73
|
onFirstFrameRendered()
|
|
60
74
|
}
|
|
61
75
|
hasPendingOnFirstFrame = false
|
|
62
76
|
hasSentFirstFrameForCurrentMediaItem = true
|
|
77
|
+
hasSentFirstFrameForCurrentVideoView = true
|
|
63
78
|
}
|
|
64
79
|
|
|
65
80
|
private fun isPlayerSurfaceLayoutValid(): Boolean {
|
|
66
81
|
// Sometimes the video size announced by the track will is 1px off the render size.
|
|
67
82
|
val epsilon = 0.05
|
|
68
|
-
val player =
|
|
83
|
+
val player = videoPlayerReference.get()?.player ?: run {
|
|
69
84
|
return false
|
|
70
85
|
}
|
|
71
86
|
val currentPlayerView = currentViewReference.get() ?: run {
|
|
@@ -85,7 +100,7 @@ internal class FirstFrameEventGenerator(
|
|
|
85
100
|
val trackAspectRatio = sourceWidth.toFloat() / sourceHeight * sourcePixelWidthHeightRatio
|
|
86
101
|
|
|
87
102
|
val videoSizeIsUnknown = sourceWidth == 0 || sourceHeight == 0
|
|
88
|
-
val hasFillContentFit = currentPlayerView.resizeMode == ContentFit.FILL.toResizeMode()
|
|
103
|
+
val hasFillContentFit = currentPlayerView.playerView.resizeMode == ContentFit.FILL.toResizeMode()
|
|
89
104
|
val hasCorrectRatio = abs(trackAspectRatio - surfaceAspectRatio) < epsilon
|
|
90
105
|
|
|
91
106
|
return (hasCorrectRatio || hasFillContentFit || videoSizeIsUnknown)
|
|
@@ -4,6 +4,7 @@ import androidx.annotation.OptIn
|
|
|
4
4
|
import androidx.media3.common.TrackSelectionParameters
|
|
5
5
|
import androidx.media3.common.Tracks
|
|
6
6
|
import androidx.media3.common.util.UnstableApi
|
|
7
|
+
import expo.modules.video.VideoView
|
|
7
8
|
import expo.modules.video.enums.AudioMixingMode
|
|
8
9
|
import expo.modules.video.enums.PlayerStatus
|
|
9
10
|
import expo.modules.video.records.AudioTrack
|
|
@@ -141,6 +142,11 @@ sealed class PlayerEvent {
|
|
|
141
142
|
override val name = "playToEnd"
|
|
142
143
|
}
|
|
143
144
|
|
|
145
|
+
data class TargetViewChanged(val newTargetView: VideoView?, val oldTargetView: VideoView?) : PlayerEvent() {
|
|
146
|
+
override val name = "targetViewChange"
|
|
147
|
+
override val emitToJS = false
|
|
148
|
+
}
|
|
149
|
+
|
|
144
150
|
fun emit(player: VideoPlayer, listeners: List<VideoPlayerListener>) {
|
|
145
151
|
when (this) {
|
|
146
152
|
is StatusChanged -> listeners.forEach { it.onStatusChanged(player, status, oldStatus, error) }
|
|
@@ -157,6 +163,7 @@ sealed class PlayerEvent {
|
|
|
157
163
|
is VideoTrackChanged -> listeners.forEach { it.onVideoTrackChanged(player, videoTrack, oldVideoTrack) }
|
|
158
164
|
is RenderedFirstFrame -> listeners.forEach { it.onRenderedFirstFrame(player) }
|
|
159
165
|
is VideoSourceLoaded -> listeners.forEach { it.onVideoSourceLoaded(player, videoSource, duration, availableVideoTracks, availableSubtitleTracks, availableAudioTracks) }
|
|
166
|
+
is TargetViewChanged -> listeners.forEach { it.onTargetViewChanged(player, newTargetView, oldTargetView) }
|
|
160
167
|
// JS-only events - SubtitleTrackChanged - In the native events the TracksChanged can be used instead
|
|
161
168
|
else -> Unit
|
|
162
169
|
}
|
|
@@ -28,6 +28,7 @@ import expo.modules.kotlin.sharedobjects.SharedObject
|
|
|
28
28
|
import expo.modules.video.IntervalUpdateClock
|
|
29
29
|
import expo.modules.video.IntervalUpdateEmitter
|
|
30
30
|
import expo.modules.video.VideoManager
|
|
31
|
+
import expo.modules.video.VideoView
|
|
31
32
|
import expo.modules.video.delegates.IgnoreSameSet
|
|
32
33
|
import expo.modules.video.enums.AudioMixingMode
|
|
33
34
|
import expo.modules.video.enums.PlayerStatus
|
|
@@ -55,7 +56,10 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
55
56
|
.forceEnableMediaCodecAsynchronousQueueing()
|
|
56
57
|
.setEnableDecoderFallback(true)
|
|
57
58
|
private var listeners: MutableList<WeakReference<VideoPlayerListener>> = mutableListOf()
|
|
58
|
-
private
|
|
59
|
+
private val currentVideoViewRef = MutableWeakReference<VideoView?>(null) { new, old ->
|
|
60
|
+
sendEvent(PlayerEvent.TargetViewChanged(new, old))
|
|
61
|
+
}
|
|
62
|
+
var currentVideoView by currentVideoViewRef
|
|
59
63
|
val loadControl: VideoPlayerLoadControl = VideoPlayerLoadControl()
|
|
60
64
|
val subtitles: VideoPlayerSubtitles = VideoPlayerSubtitles(this)
|
|
61
65
|
val audioTracks: VideoPlayerAudioTracks = VideoPlayerAudioTracks(this)
|
|
@@ -67,7 +71,7 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
67
71
|
.setLoadControl(loadControl)
|
|
68
72
|
.build()
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
internal lateinit var firstFrameEventGenerator: FirstFrameEventGenerator
|
|
71
75
|
val serviceConnection = PlaybackServiceConnection(WeakReference(this), appContext)
|
|
72
76
|
val intervalUpdateClock = IntervalUpdateClock(this)
|
|
73
77
|
|
|
@@ -323,6 +327,7 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
323
327
|
|
|
324
328
|
// ExoPlayer will enable subtitles automatically at the start, we want them disabled by default
|
|
325
329
|
appContext.mainQueue.launch {
|
|
330
|
+
firstFrameEventGenerator = createFirstFrameEventGenerator()
|
|
326
331
|
subtitles.setSubtitlesEnabled(false)
|
|
327
332
|
}
|
|
328
333
|
}
|
|
@@ -335,6 +340,7 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
335
340
|
VideoManager.unregisterVideoPlayer(this@VideoPlayer)
|
|
336
341
|
|
|
337
342
|
appContext?.mainQueue?.launch {
|
|
343
|
+
firstFrameEventGenerator.release()
|
|
338
344
|
player.removeListener(playerListener)
|
|
339
345
|
player.release()
|
|
340
346
|
}
|
|
@@ -349,9 +355,19 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
349
355
|
close()
|
|
350
356
|
}
|
|
351
357
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
358
|
+
/**
|
|
359
|
+
* Used to notify the player that is has been disconnected from the player view by another player.
|
|
360
|
+
*/
|
|
361
|
+
fun hasBeenDisconnectedFromVideoView() {
|
|
362
|
+
if (currentVideoView?.playerView?.player == this.player) {
|
|
363
|
+
throw IllegalStateException("The player has been notified of disconnection from the player view, even though it's still connected.")
|
|
364
|
+
}
|
|
365
|
+
currentVideoView = null
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
fun changeVideoView(videoView: VideoView?) {
|
|
369
|
+
PlayerView.switchTargetView(player, currentVideoView?.playerView, videoView?.playerView)
|
|
370
|
+
currentVideoView = videoView
|
|
355
371
|
}
|
|
356
372
|
|
|
357
373
|
fun prepare() {
|
|
@@ -471,7 +487,7 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
471
487
|
}
|
|
472
488
|
|
|
473
489
|
private fun createFirstFrameEventGenerator(): FirstFrameEventGenerator {
|
|
474
|
-
return FirstFrameEventGenerator(
|
|
490
|
+
return FirstFrameEventGenerator(this, currentVideoViewRef) {
|
|
475
491
|
sendEvent(PlayerEvent.RenderedFirstFrame())
|
|
476
492
|
}
|
|
477
493
|
}
|
|
@@ -4,6 +4,7 @@ import androidx.annotation.OptIn
|
|
|
4
4
|
import androidx.media3.common.TrackSelectionParameters
|
|
5
5
|
import androidx.media3.common.Tracks
|
|
6
6
|
import androidx.media3.common.util.UnstableApi
|
|
7
|
+
import expo.modules.video.VideoView
|
|
7
8
|
import expo.modules.video.enums.AudioMixingMode
|
|
8
9
|
import expo.modules.video.enums.PlayerStatus
|
|
9
10
|
import expo.modules.video.records.AudioTrack
|
|
@@ -28,5 +29,6 @@ interface VideoPlayerListener {
|
|
|
28
29
|
fun onAudioMixingModeChanged(player: VideoPlayer, audioMixingMode: AudioMixingMode, oldAudioMixingMode: AudioMixingMode?) {}
|
|
29
30
|
fun onVideoTrackChanged(player: VideoPlayer, videoTrack: VideoTrack?, oldVideoTrack: VideoTrack?) {}
|
|
30
31
|
fun onVideoSourceLoaded(player: VideoPlayer, videoSource: VideoSource?, duration: Double?, availableVideoTracks: List<VideoTrack>, availableSubtitleTracks: List<SubtitleTrack>, availableAudioTracks: List<AudioTrack>) {}
|
|
32
|
+
fun onTargetViewChanged(player: VideoPlayer, newTargetView: VideoView?, oldTargetView: VideoView?) {}
|
|
31
33
|
fun onRenderedFirstFrame(player: VideoPlayer) {}
|
|
32
34
|
}
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
package expo.modules.video.utils
|
|
2
2
|
|
|
3
3
|
import java.lang.ref.WeakReference
|
|
4
|
+
import kotlin.reflect.KProperty
|
|
4
5
|
|
|
5
|
-
internal class MutableWeakReference<T
|
|
6
|
-
private var ref: WeakReference<T> = WeakReference(
|
|
6
|
+
internal class MutableWeakReference<T : Any?>(initialValue: T, val didSet: ((new: T?, old: T?) -> Unit)? = null) {
|
|
7
|
+
private var ref: WeakReference<T> = WeakReference(initialValue)
|
|
8
|
+
|
|
9
|
+
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? {
|
|
10
|
+
return get()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
|
14
|
+
set(value)
|
|
15
|
+
}
|
|
7
16
|
|
|
8
17
|
fun get(): T? {
|
|
9
18
|
return ref.get()
|
|
10
19
|
}
|
|
11
20
|
|
|
12
21
|
fun set(value: T) {
|
|
22
|
+
val oldValue = ref.get()
|
|
13
23
|
ref = WeakReference(value)
|
|
24
|
+
didSet?.invoke(oldValue, value)
|
|
14
25
|
}
|
|
15
26
|
}
|
|
@@ -2,7 +2,7 @@ import type { BufferOptions, PlayerError, VideoPlayerStatus, VideoSource, VideoP
|
|
|
2
2
|
import type { VideoPlayerEvents } from './VideoPlayerEvents.types';
|
|
3
3
|
import { VideoThumbnail } from './VideoThumbnail';
|
|
4
4
|
export declare function useVideoPlayer(source: VideoSource, setup?: (player: VideoPlayer) => void): VideoPlayer;
|
|
5
|
-
export declare function getSourceUri(source
|
|
5
|
+
export declare function getSourceUri(source?: VideoSource): string | null;
|
|
6
6
|
export declare function createVideoPlayer(source: VideoSource): VideoPlayer;
|
|
7
7
|
export default class VideoPlayerWeb extends globalThis.expo.SharedObject<VideoPlayerEvents> implements VideoPlayer {
|
|
8
8
|
constructor(source: VideoSource);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoPlayer.web.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.web.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACpC,WAAW,CAQb;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"VideoPlayer.web.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.web.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EACnB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GACpC,WAAW,CAQb;AAED,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAYhE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAIlE;AAED,MAAM,CAAC,OAAO,OAAO,cACnB,SAAQ,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,iBAAiB,CACtD,YAAW,WAAW;gBAEV,MAAM,EAAE,WAAW;IAK/B,GAAG,EAAE,WAAW,CAAQ;IACxB,WAAW,EAAE,WAAW,CAAQ;IAChC,cAAc,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAa;IAClD,WAAW,EAAE,GAAG,CAAC,2BAA2B,CAAC,CAAa;IAC1D,OAAO,EAAE,OAAO,CAAS;IACzB,MAAM,EAAE,OAAO,CAAS;IACxB,OAAO,EAAE,MAAM,CAAK;IACpB,KAAK,EAAE,OAAO,CAAS;IACvB,aAAa,EAAE,MAAM,CAAO;IAC5B,eAAe,EAAE,OAAO,CAAQ;IAChC,OAAO,EAAE,iBAAiB,CAAU;IACpC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAQ;IAClC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC,wBAAwB,EAAE,MAAM,CAAK;IACrC,eAAe,EAAE,eAAe,CAAU;IAC1C,sBAAsB,EAAE,OAAO,CAAS;IACxC,uBAAuB,EAAE,OAAO,CAAS;IACzC,0BAA0B,EAAE,OAAO,CAAS;IAC5C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3C,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC5C,oBAAoB,EAAE,MAAM,CAAK;IACjC,aAAa,EAAE,aAAa,CAAuB;IACnD,aAAa,EAAE,aAAa,GAAG,IAAI,CAAQ;IAC3C,uBAAuB,EAAE,aAAa,EAAE,CAAM;IAC9C,UAAU,EAAE,UAAU,GAAG,IAAI,CAAQ;IACrC,oBAAoB,EAAE,UAAU,EAAE,CAAM;IACxC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAQ;IACrC,oBAAoB,EAAE,UAAU,EAAE,CAAM;IACxC,wBAAwB,EAAE,OAAO,CAAS;IAC1C,wBAAwB,EAAE,OAAO,CAAS;IAC1C,aAAa,EAAE,aAAa,CAAuB;IACnD,oBAAoB,EAAE,oBAAoB,CAA8B;IAExE,IAAI,KAAK,CAAC,KAAK,EAAE,OAAO,EAKvB;IAED,IAAI,KAAK,IAAI,OAAO,CAEnB;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAK7B;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,EAKvB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,EAKtB;IAED,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,IAAI,WAAW,IAAI,MAAM,CAGxB;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,MAAM,EAI5B;IAED,IAAI,QAAQ,IAAI,MAAM,CAGrB;IAED,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,IAAI,cAAc,CAAC,KAAK,EAAE,OAAO,EAKhC;IAED,IAAI,uBAAuB,IAAI,MAAM,CAEpC;IACD,IAAI,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAuBxC;IAED,IAAI,MAAM,IAAI,iBAAiB,CAE9B;IAED,IAAI,gBAAgB,IAAI,MAAM,CAW7B;IAED,OAAO,KAAK,MAAM,QAiBjB;IAED,cAAc,CAAC,KAAK,EAAE,gBAAgB;IActC,gBAAgB,CAAC,KAAK,EAAE,gBAAgB;IAIxC,cAAc,CACZ,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,QAAQ,EACtB,eAAe,EAAE,2BAA2B,GAC3C,IAAI;IAYP,gBAAgB,CACd,KAAK,EAAE,gBAAgB,EACvB,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,2BAA2B;IAe9C,IAAI,IAAI,IAAI;IAMZ,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAqB5B,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM7B,MAAM,IAAI,IAAI;IAQd,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAI5E,0BAA0B,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAezD;;;OAGG;IACH,SAAS,CAAC,SAAS,SAAS,MAAM,iBAAiB,EACjD,WAAW,EAAE,gBAAgB,EAC7B,SAAS,EAAE,SAAS,EACpB,GAAG,IAAI,EAAE,UAAU,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,GAChD,IAAI;IAOP,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;CAsF7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoPlayer.web.js","sourceRoot":"","sources":["../src/VideoPlayer.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\n\nimport type {\n BufferOptions,\n PlayerError,\n VideoPlayerStatus,\n VideoSource,\n VideoPlayer,\n SubtitleTrack,\n AudioMixingMode,\n VideoTrack,\n AudioTrack,\n ScrubbingModeOptions,\n SeekTolerance,\n} from './VideoPlayer.types';\nimport type { VideoPlayerEvents } from './VideoPlayerEvents.types';\nimport { VideoThumbnail } from './VideoThumbnail';\nimport resolveAssetSource from './resolveAssetSource';\n\nexport function useVideoPlayer(\n source: VideoSource,\n setup?: (player: VideoPlayer) => void\n): VideoPlayer {\n const parsedSource = typeof source === 'string' ? { uri: source } : source;\n\n return useMemo(() => {\n const player = new VideoPlayerWeb(parsedSource);\n setup?.(player);\n return player;\n }, [JSON.stringify(source)]);\n}\n\nexport function getSourceUri(source: VideoSource): string | null {\n if (typeof source === 'string') {\n return source;\n }\n if (typeof source === 'number') {\n return resolveAssetSource(source)?.uri ?? null;\n }\n if (typeof source?.assetId === 'number' && !source?.uri) {\n return resolveAssetSource(source.assetId)?.uri ?? null;\n }\n\n return source?.uri ?? null;\n}\n\nexport function createVideoPlayer(source: VideoSource): VideoPlayer {\n const parsedSource = typeof source === 'string' ? { uri: source } : source;\n\n return new VideoPlayerWeb(parsedSource);\n}\n\nexport default class VideoPlayerWeb\n extends globalThis.expo.SharedObject<VideoPlayerEvents>\n implements VideoPlayer\n{\n constructor(source: VideoSource) {\n super();\n this.src = source;\n }\n\n src: VideoSource = null;\n previousSrc: VideoSource = null;\n _mountedVideos: Set<HTMLVideoElement> = new Set();\n _audioNodes: Set<MediaElementAudioSourceNode> = new Set();\n playing: boolean = false;\n _muted: boolean = false;\n _volume: number = 1;\n _loop: boolean = false;\n _playbackRate: number = 1.0;\n _preservesPitch: boolean = true;\n _status: VideoPlayerStatus = 'idle';\n _error: PlayerError | null = null;\n _timeUpdateLoop: number | null = null;\n _timeUpdateEventInterval: number = 0;\n audioMixingMode: AudioMixingMode = 'auto'; // Not supported on web. Dummy to match the interface.\n allowsExternalPlayback: boolean = false; // Not supported on web. Dummy to match the interface.\n staysActiveInBackground: boolean = false; // Not supported on web. Dummy to match the interface.\n showNowPlayingNotification: boolean = false; // Not supported on web. Dummy to match the interface.\n currentLiveTimestamp: number | null = null; // Not supported on web. Dummy to match the interface.\n currentOffsetFromLive: number | null = null; // Not supported on web. Dummy to match the interface.\n targetOffsetFromLive: number = 0; // Not supported on web. Dummy to match the interface.\n bufferOptions: BufferOptions = {} as BufferOptions; // Not supported on web. Dummy to match the interface.\n subtitleTrack: SubtitleTrack | null = null; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.\n availableSubtitleTracks: SubtitleTrack[] = []; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.\n audioTrack: AudioTrack | null = null; // Not supported on web. Dummy to match the interface.\n availableAudioTracks: AudioTrack[] = []; // Not supported on web. Dummy to match the interface.\n videoTrack: VideoTrack | null = null; // Not supported on web. Dummy to match the interface.\n availableVideoTracks: VideoTrack[] = []; // Not supported on web. Dummy to match the interface.\n isExternalPlaybackActive: boolean = false; // Not supported on web. Dummy to match the interface.\n keepScreenOnWhilePlaying: boolean = false; // Not supported on web. Dummy to match the interface\n seekTolerance: SeekTolerance = {} as SeekTolerance; // Not supported on web. Dummy to match the interface.\n scrubbingModeOptions: ScrubbingModeOptions = {} as ScrubbingModeOptions; // Not supported on web. Dummy to match the interface.\n\n set muted(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.muted = value;\n });\n this._muted = value;\n }\n\n get muted(): boolean {\n return this._muted;\n }\n\n set playbackRate(value: number) {\n this._mountedVideos.forEach((video) => {\n video.playbackRate = value;\n });\n this._playbackRate = value;\n }\n\n get playbackRate(): number {\n return this._playbackRate;\n }\n\n get isLive(): boolean {\n return [...this._mountedVideos][0]?.duration === Infinity;\n }\n\n set volume(value: number) {\n this._mountedVideos.forEach((video) => {\n video.volume = value;\n });\n this._volume = value;\n }\n\n get volume(): number {\n return this._volume;\n }\n\n set loop(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.loop = value;\n });\n this._loop = value;\n }\n\n get loop(): boolean {\n return this._loop;\n }\n\n get currentTime(): number {\n // All videos should be synchronized, so we return the position of the first video.\n return [...this._mountedVideos][0]?.currentTime ?? 0;\n }\n\n set currentTime(value: number) {\n this._mountedVideos.forEach((video) => {\n video.currentTime = value;\n });\n }\n\n get duration(): number {\n // All videos should have the same duration, so we return the duration of the first video.\n return [...this._mountedVideos][0]?.duration ?? 0;\n }\n\n get preservesPitch(): boolean {\n return this._preservesPitch;\n }\n\n set preservesPitch(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.preservesPitch = value;\n });\n this._preservesPitch = value;\n }\n\n get timeUpdateEventInterval(): number {\n return this._timeUpdateEventInterval;\n }\n set timeUpdateEventInterval(value: number) {\n this._timeUpdateEventInterval = value;\n if (this._timeUpdateLoop) {\n clearInterval(this._timeUpdateLoop);\n }\n if (value > 0) {\n // Emit the first event immediately like on other platforms\n this.emit('timeUpdate', {\n currentTime: this.currentTime,\n currentLiveTimestamp: null,\n currentOffsetFromLive: null,\n bufferedPosition: this.bufferedPosition,\n });\n\n this._timeUpdateLoop = setInterval(() => {\n this.emit('timeUpdate', {\n currentTime: this.currentTime,\n currentLiveTimestamp: null,\n currentOffsetFromLive: null,\n bufferedPosition: this.bufferedPosition,\n });\n }, value * 1000);\n }\n }\n\n get status(): VideoPlayerStatus {\n return this._status;\n }\n\n get bufferedPosition(): number {\n if (this._mountedVideos.size === 0 || this.status === 'error') {\n return -1;\n }\n const buffered = [...this._mountedVideos][0]?.buffered;\n for (let i = 0; i < buffered.length; i++) {\n if (buffered.start(i) <= this.currentTime && buffered.end(i) >= this.currentTime) {\n return buffered.end(i);\n }\n }\n return 0;\n }\n\n private set status(value: VideoPlayerStatus) {\n if (this._status === value) return;\n\n if (value === 'error' && this._error) {\n this.emit('statusChange', {\n status: value,\n oldStatus: this._status,\n error: this._error,\n });\n } else {\n this.emit('statusChange', {\n status: value,\n oldStatus: this._status,\n });\n this._error = null;\n }\n this._status = value;\n }\n\n mountVideoView(video: HTMLVideoElement) {\n // The video will be the first video, it should inherit the properties set in the setup() function\n if (this._mountedVideos.size === 0) {\n video.preservesPitch = this._preservesPitch;\n video.loop = this._loop;\n video.volume = this._volume;\n video.muted = this._muted;\n video.playbackRate = this._playbackRate;\n }\n this._mountedVideos.add(video);\n this._addListeners(video);\n this._synchronizeWithFirstVideo(video);\n }\n\n unmountVideoView(video: HTMLVideoElement) {\n this._mountedVideos.delete(video);\n }\n\n mountAudioNode(\n audioContext: AudioContext,\n zeroGainNode: GainNode,\n audioSourceNode: MediaElementAudioSourceNode\n ): void {\n if (!audioContext || !zeroGainNode) return;\n\n this._audioNodes.add(audioSourceNode);\n // First mounted video should be connected to the audio context. All other videos have to be muted.\n if (this._audioNodes.size === 1) {\n audioSourceNode.connect(audioContext.destination);\n } else {\n audioSourceNode.connect(zeroGainNode);\n }\n }\n\n unmountAudioNode(\n video: HTMLVideoElement,\n audioContext: AudioContext,\n audioSourceNode: MediaElementAudioSourceNode\n ) {\n const mountedVideos = [...this._mountedVideos];\n const videoPlayingAudio = mountedVideos[0];\n this._audioNodes.delete(audioSourceNode);\n audioSourceNode.disconnect();\n\n // If video playing audio has been removed, select a new video to be the audio player by disconnecting it from the mute node.\n if (videoPlayingAudio === video && this._audioNodes.size > 0 && audioContext) {\n const newMainAudioSource = [...this._audioNodes][0];\n newMainAudioSource.disconnect();\n newMainAudioSource.connect(audioContext.destination);\n }\n }\n\n play(): void {\n this._mountedVideos.forEach((video) => {\n video.play();\n });\n }\n\n pause(): void {\n this._mountedVideos.forEach((video) => {\n video.pause();\n });\n }\n\n replace(source: VideoSource): void {\n this._mountedVideos.forEach((video) => {\n const uri = getSourceUri(source);\n video.pause();\n if (uri) {\n video.setAttribute('src', uri);\n video.load();\n video.play();\n } else {\n video.removeAttribute('src');\n video.load();\n }\n });\n // TODO @behenate: this won't work when we add support for playlists\n this.previousSrc = this.src;\n this.src = source;\n this.playing = true;\n }\n\n // The HTML5 player already offloads loading of the asset onto a different thread so we can keep the same\n // implementation until `replace` is deprecated and removed.\n async replaceAsync(source: VideoSource): Promise<void> {\n return this.replace(source);\n }\n\n seekBy(seconds: number): void {\n this._mountedVideos.forEach((video) => {\n video.currentTime += seconds;\n });\n }\n\n replay(): void {\n this._mountedVideos.forEach((video) => {\n video.currentTime = 0;\n video.play();\n });\n this.playing = true;\n }\n\n generateThumbnailsAsync(times: number | number[]): Promise<VideoThumbnail[]> {\n throw new Error('Generating video thumbnails is not supported on Web yet');\n }\n\n _synchronizeWithFirstVideo(video: HTMLVideoElement): void {\n const firstVideo = [...this._mountedVideos][0];\n if (!firstVideo) return;\n\n if (firstVideo.paused) {\n video.pause();\n } else {\n video.play();\n }\n video.currentTime = firstVideo.currentTime;\n video.volume = firstVideo.volume;\n video.muted = firstVideo.muted;\n video.playbackRate = firstVideo.playbackRate;\n }\n\n /**\n * If there are multiple mounted videos, all of them will emit an event, as they are synchronised.\n * We want to avoid this, so we only emit the event if it came from the first video.\n */\n _emitOnce<EventName extends keyof VideoPlayerEvents>(\n eventSource: HTMLVideoElement,\n eventName: EventName,\n ...args: Parameters<VideoPlayerEvents[EventName]>\n ): void {\n const mountedVideos = [...this._mountedVideos];\n if (mountedVideos[0] === eventSource) {\n this.emit(eventName, ...args);\n }\n }\n\n _addListeners(video: HTMLVideoElement): void {\n video.onplay = () => {\n this._emitOnce(video, 'playingChange', {\n isPlaying: true,\n oldIsPlaying: this.playing,\n });\n this.playing = true;\n this._mountedVideos.forEach((mountedVideo) => {\n mountedVideo.play();\n });\n };\n\n video.onpause = () => {\n this._emitOnce(video, 'playingChange', {\n isPlaying: false,\n oldIsPlaying: this.playing,\n });\n this.playing = false;\n this._mountedVideos.forEach((mountedVideo) => {\n mountedVideo.pause();\n });\n };\n\n video.onvolumechange = () => {\n this._emitOnce(video, 'volumeChange', { volume: video.volume, oldVolume: this.volume });\n this._emitOnce(video, 'mutedChange', { muted: video.muted, oldMuted: this.muted });\n this.volume = video.volume;\n this.muted = video.muted;\n };\n\n video.onseeking = () => {\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo === video || mountedVideo.currentTime === video.currentTime) return;\n mountedVideo.currentTime = video.currentTime;\n });\n };\n\n video.onseeked = () => {\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo === video || mountedVideo.currentTime === video.currentTime) return;\n mountedVideo.currentTime = video.currentTime;\n });\n };\n\n video.onratechange = () => {\n this._emitOnce(video, 'playbackRateChange', {\n playbackRate: video.playbackRate,\n oldPlaybackRate: this.playbackRate,\n });\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo.playbackRate === video.playbackRate) return;\n this._playbackRate = video.playbackRate;\n mountedVideo.playbackRate = video.playbackRate;\n });\n this._playbackRate = video.playbackRate;\n };\n\n video.onerror = () => {\n this._error = {\n message: video.error?.message ?? 'Unknown player error',\n };\n this.status = 'error';\n };\n\n video.oncanplay = () => {\n const allCanPlay = [...this._mountedVideos].reduce((previousValue, video) => {\n return previousValue && video.readyState >= 3;\n }, true);\n if (!allCanPlay) return;\n\n this.status = 'readyToPlay';\n };\n\n video.onwaiting = () => {\n if (this._status === 'loading') return;\n this.status = 'loading';\n };\n\n video.onended = () => {\n this._emitOnce(video, 'playToEnd');\n };\n\n video.onloadstart = () => {\n this._emitOnce(video, 'sourceChange', { source: this.src, oldSource: this.previousSrc });\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"VideoPlayer.web.js","sourceRoot":"","sources":["../src/VideoPlayer.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\n\nimport type {\n BufferOptions,\n PlayerError,\n VideoPlayerStatus,\n VideoSource,\n VideoPlayer,\n SubtitleTrack,\n AudioMixingMode,\n VideoTrack,\n AudioTrack,\n ScrubbingModeOptions,\n SeekTolerance,\n} from './VideoPlayer.types';\nimport type { VideoPlayerEvents } from './VideoPlayerEvents.types';\nimport { VideoThumbnail } from './VideoThumbnail';\nimport resolveAssetSource from './resolveAssetSource';\n\nexport function useVideoPlayer(\n source: VideoSource,\n setup?: (player: VideoPlayer) => void\n): VideoPlayer {\n const parsedSource = typeof source === 'string' ? { uri: source } : source;\n\n return useMemo(() => {\n const player = new VideoPlayerWeb(parsedSource);\n setup?.(player);\n return player;\n }, [JSON.stringify(source)]);\n}\n\nexport function getSourceUri(source?: VideoSource): string | null {\n if (typeof source === 'string') {\n return source;\n }\n if (typeof source === 'number') {\n return resolveAssetSource(source)?.uri ?? null;\n }\n if (typeof source?.assetId === 'number' && !source?.uri) {\n return resolveAssetSource(source.assetId)?.uri ?? null;\n }\n\n return source?.uri ?? null;\n}\n\nexport function createVideoPlayer(source: VideoSource): VideoPlayer {\n const parsedSource = typeof source === 'string' ? { uri: source } : source;\n\n return new VideoPlayerWeb(parsedSource);\n}\n\nexport default class VideoPlayerWeb\n extends globalThis.expo.SharedObject<VideoPlayerEvents>\n implements VideoPlayer\n{\n constructor(source: VideoSource) {\n super();\n this.src = source;\n }\n\n src: VideoSource = null;\n previousSrc: VideoSource = null;\n _mountedVideos: Set<HTMLVideoElement> = new Set();\n _audioNodes: Set<MediaElementAudioSourceNode> = new Set();\n playing: boolean = false;\n _muted: boolean = false;\n _volume: number = 1;\n _loop: boolean = false;\n _playbackRate: number = 1.0;\n _preservesPitch: boolean = true;\n _status: VideoPlayerStatus = 'idle';\n _error: PlayerError | null = null;\n _timeUpdateLoop: number | null = null;\n _timeUpdateEventInterval: number = 0;\n audioMixingMode: AudioMixingMode = 'auto'; // Not supported on web. Dummy to match the interface.\n allowsExternalPlayback: boolean = false; // Not supported on web. Dummy to match the interface.\n staysActiveInBackground: boolean = false; // Not supported on web. Dummy to match the interface.\n showNowPlayingNotification: boolean = false; // Not supported on web. Dummy to match the interface.\n currentLiveTimestamp: number | null = null; // Not supported on web. Dummy to match the interface.\n currentOffsetFromLive: number | null = null; // Not supported on web. Dummy to match the interface.\n targetOffsetFromLive: number = 0; // Not supported on web. Dummy to match the interface.\n bufferOptions: BufferOptions = {} as BufferOptions; // Not supported on web. Dummy to match the interface.\n subtitleTrack: SubtitleTrack | null = null; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.\n availableSubtitleTracks: SubtitleTrack[] = []; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.\n audioTrack: AudioTrack | null = null; // Not supported on web. Dummy to match the interface.\n availableAudioTracks: AudioTrack[] = []; // Not supported on web. Dummy to match the interface.\n videoTrack: VideoTrack | null = null; // Not supported on web. Dummy to match the interface.\n availableVideoTracks: VideoTrack[] = []; // Not supported on web. Dummy to match the interface.\n isExternalPlaybackActive: boolean = false; // Not supported on web. Dummy to match the interface.\n keepScreenOnWhilePlaying: boolean = false; // Not supported on web. Dummy to match the interface\n seekTolerance: SeekTolerance = {} as SeekTolerance; // Not supported on web. Dummy to match the interface.\n scrubbingModeOptions: ScrubbingModeOptions = {} as ScrubbingModeOptions; // Not supported on web. Dummy to match the interface.\n\n set muted(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.muted = value;\n });\n this._muted = value;\n }\n\n get muted(): boolean {\n return this._muted;\n }\n\n set playbackRate(value: number) {\n this._mountedVideos.forEach((video) => {\n video.playbackRate = value;\n });\n this._playbackRate = value;\n }\n\n get playbackRate(): number {\n return this._playbackRate;\n }\n\n get isLive(): boolean {\n return [...this._mountedVideos][0]?.duration === Infinity;\n }\n\n set volume(value: number) {\n this._mountedVideos.forEach((video) => {\n video.volume = value;\n });\n this._volume = value;\n }\n\n get volume(): number {\n return this._volume;\n }\n\n set loop(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.loop = value;\n });\n this._loop = value;\n }\n\n get loop(): boolean {\n return this._loop;\n }\n\n get currentTime(): number {\n // All videos should be synchronized, so we return the position of the first video.\n return [...this._mountedVideos][0]?.currentTime ?? 0;\n }\n\n set currentTime(value: number) {\n this._mountedVideos.forEach((video) => {\n video.currentTime = value;\n });\n }\n\n get duration(): number {\n // All videos should have the same duration, so we return the duration of the first video.\n return [...this._mountedVideos][0]?.duration ?? 0;\n }\n\n get preservesPitch(): boolean {\n return this._preservesPitch;\n }\n\n set preservesPitch(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.preservesPitch = value;\n });\n this._preservesPitch = value;\n }\n\n get timeUpdateEventInterval(): number {\n return this._timeUpdateEventInterval;\n }\n set timeUpdateEventInterval(value: number) {\n this._timeUpdateEventInterval = value;\n if (this._timeUpdateLoop) {\n clearInterval(this._timeUpdateLoop);\n }\n if (value > 0) {\n // Emit the first event immediately like on other platforms\n this.emit('timeUpdate', {\n currentTime: this.currentTime,\n currentLiveTimestamp: null,\n currentOffsetFromLive: null,\n bufferedPosition: this.bufferedPosition,\n });\n\n this._timeUpdateLoop = setInterval(() => {\n this.emit('timeUpdate', {\n currentTime: this.currentTime,\n currentLiveTimestamp: null,\n currentOffsetFromLive: null,\n bufferedPosition: this.bufferedPosition,\n });\n }, value * 1000);\n }\n }\n\n get status(): VideoPlayerStatus {\n return this._status;\n }\n\n get bufferedPosition(): number {\n if (this._mountedVideos.size === 0 || this.status === 'error') {\n return -1;\n }\n const buffered = [...this._mountedVideos][0]?.buffered;\n for (let i = 0; i < buffered.length; i++) {\n if (buffered.start(i) <= this.currentTime && buffered.end(i) >= this.currentTime) {\n return buffered.end(i);\n }\n }\n return 0;\n }\n\n private set status(value: VideoPlayerStatus) {\n if (this._status === value) return;\n\n if (value === 'error' && this._error) {\n this.emit('statusChange', {\n status: value,\n oldStatus: this._status,\n error: this._error,\n });\n } else {\n this.emit('statusChange', {\n status: value,\n oldStatus: this._status,\n });\n this._error = null;\n }\n this._status = value;\n }\n\n mountVideoView(video: HTMLVideoElement) {\n // The video will be the first video, it should inherit the properties set in the setup() function\n if (this._mountedVideos.size === 0) {\n video.preservesPitch = this._preservesPitch;\n video.loop = this._loop;\n video.volume = this._volume;\n video.muted = this._muted;\n video.playbackRate = this._playbackRate;\n }\n this._mountedVideos.add(video);\n this._addListeners(video);\n this._synchronizeWithFirstVideo(video);\n }\n\n unmountVideoView(video: HTMLVideoElement) {\n this._mountedVideos.delete(video);\n }\n\n mountAudioNode(\n audioContext: AudioContext,\n zeroGainNode: GainNode,\n audioSourceNode: MediaElementAudioSourceNode\n ): void {\n if (!audioContext || !zeroGainNode) return;\n\n this._audioNodes.add(audioSourceNode);\n // First mounted video should be connected to the audio context. All other videos have to be muted.\n if (this._audioNodes.size === 1) {\n audioSourceNode.connect(audioContext.destination);\n } else {\n audioSourceNode.connect(zeroGainNode);\n }\n }\n\n unmountAudioNode(\n video: HTMLVideoElement,\n audioContext: AudioContext,\n audioSourceNode: MediaElementAudioSourceNode\n ) {\n const mountedVideos = [...this._mountedVideos];\n const videoPlayingAudio = mountedVideos[0];\n this._audioNodes.delete(audioSourceNode);\n audioSourceNode.disconnect();\n\n // If video playing audio has been removed, select a new video to be the audio player by disconnecting it from the mute node.\n if (videoPlayingAudio === video && this._audioNodes.size > 0 && audioContext) {\n const newMainAudioSource = [...this._audioNodes][0];\n newMainAudioSource.disconnect();\n newMainAudioSource.connect(audioContext.destination);\n }\n }\n\n play(): void {\n this._mountedVideos.forEach((video) => {\n video.play();\n });\n }\n\n pause(): void {\n this._mountedVideos.forEach((video) => {\n video.pause();\n });\n }\n\n replace(source: VideoSource): void {\n this._mountedVideos.forEach((video) => {\n const uri = getSourceUri(source);\n video.pause();\n if (uri) {\n video.setAttribute('src', uri);\n video.load();\n video.play();\n } else {\n video.removeAttribute('src');\n video.load();\n }\n });\n // TODO @behenate: this won't work when we add support for playlists\n this.previousSrc = this.src;\n this.src = source;\n this.playing = true;\n }\n\n // The HTML5 player already offloads loading of the asset onto a different thread so we can keep the same\n // implementation until `replace` is deprecated and removed.\n async replaceAsync(source: VideoSource): Promise<void> {\n return this.replace(source);\n }\n\n seekBy(seconds: number): void {\n this._mountedVideos.forEach((video) => {\n video.currentTime += seconds;\n });\n }\n\n replay(): void {\n this._mountedVideos.forEach((video) => {\n video.currentTime = 0;\n video.play();\n });\n this.playing = true;\n }\n\n generateThumbnailsAsync(times: number | number[]): Promise<VideoThumbnail[]> {\n throw new Error('Generating video thumbnails is not supported on Web yet');\n }\n\n _synchronizeWithFirstVideo(video: HTMLVideoElement): void {\n const firstVideo = [...this._mountedVideos][0];\n if (!firstVideo) return;\n\n if (firstVideo.paused) {\n video.pause();\n } else {\n video.play();\n }\n video.currentTime = firstVideo.currentTime;\n video.volume = firstVideo.volume;\n video.muted = firstVideo.muted;\n video.playbackRate = firstVideo.playbackRate;\n }\n\n /**\n * If there are multiple mounted videos, all of them will emit an event, as they are synchronised.\n * We want to avoid this, so we only emit the event if it came from the first video.\n */\n _emitOnce<EventName extends keyof VideoPlayerEvents>(\n eventSource: HTMLVideoElement,\n eventName: EventName,\n ...args: Parameters<VideoPlayerEvents[EventName]>\n ): void {\n const mountedVideos = [...this._mountedVideos];\n if (mountedVideos[0] === eventSource) {\n this.emit(eventName, ...args);\n }\n }\n\n _addListeners(video: HTMLVideoElement): void {\n video.onplay = () => {\n this._emitOnce(video, 'playingChange', {\n isPlaying: true,\n oldIsPlaying: this.playing,\n });\n this.playing = true;\n this._mountedVideos.forEach((mountedVideo) => {\n mountedVideo.play();\n });\n };\n\n video.onpause = () => {\n this._emitOnce(video, 'playingChange', {\n isPlaying: false,\n oldIsPlaying: this.playing,\n });\n this.playing = false;\n this._mountedVideos.forEach((mountedVideo) => {\n mountedVideo.pause();\n });\n };\n\n video.onvolumechange = () => {\n this._emitOnce(video, 'volumeChange', { volume: video.volume, oldVolume: this.volume });\n this._emitOnce(video, 'mutedChange', { muted: video.muted, oldMuted: this.muted });\n this.volume = video.volume;\n this.muted = video.muted;\n };\n\n video.onseeking = () => {\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo === video || mountedVideo.currentTime === video.currentTime) return;\n mountedVideo.currentTime = video.currentTime;\n });\n };\n\n video.onseeked = () => {\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo === video || mountedVideo.currentTime === video.currentTime) return;\n mountedVideo.currentTime = video.currentTime;\n });\n };\n\n video.onratechange = () => {\n this._emitOnce(video, 'playbackRateChange', {\n playbackRate: video.playbackRate,\n oldPlaybackRate: this.playbackRate,\n });\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo.playbackRate === video.playbackRate) return;\n this._playbackRate = video.playbackRate;\n mountedVideo.playbackRate = video.playbackRate;\n });\n this._playbackRate = video.playbackRate;\n };\n\n video.onerror = () => {\n this._error = {\n message: video.error?.message ?? 'Unknown player error',\n };\n this.status = 'error';\n };\n\n video.oncanplay = () => {\n const allCanPlay = [...this._mountedVideos].reduce((previousValue, video) => {\n return previousValue && video.readyState >= 3;\n }, true);\n if (!allCanPlay) return;\n\n this.status = 'readyToPlay';\n };\n\n video.onwaiting = () => {\n if (this._status === 'loading') return;\n this.status = 'loading';\n };\n\n video.onended = () => {\n this._emitOnce(video, 'playToEnd');\n };\n\n video.onloadstart = () => {\n this._emitOnce(video, 'sourceChange', { source: this.src, oldSource: this.previousSrc });\n };\n }\n}\n"]}
|
package/build/VideoView.js
CHANGED
|
@@ -55,7 +55,7 @@ export class VideoView extends PureComponent {
|
|
|
55
55
|
}
|
|
56
56
|
render() {
|
|
57
57
|
const { player, ...props } = this.props;
|
|
58
|
-
const playerId = getPlayerId(player);
|
|
58
|
+
const playerId = player ? getPlayerId(player) : null;
|
|
59
59
|
if (props.allowsFullscreen !== undefined) {
|
|
60
60
|
console.warn('The `allowsFullscreen` prop is deprecated and will be removed in a future release. Use `fullscreenOptions` prop instead.');
|
|
61
61
|
}
|
package/build/VideoView.js.map
CHANGED
|
@@ -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,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;;OAEG;IACH,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;
|
|
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;;OAEG;IACH,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,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAErD,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YACzC,OAAO,CAAC,IAAI,CACV,0HAA0H,CAC3H,CAAC;QACJ,CAAC;QAED,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 /**\n * A reference to the underlying native view. On web it is a reference to the HTMLVideoElement.\n */\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 = player ? getPlayerId(player) : null;\n\n if (props.allowsFullscreen !== undefined) {\n console.warn(\n 'The `allowsFullscreen` prop is deprecated and will be removed in a future release. Use `fullscreenOptions` prop instead.'\n );\n }\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"]}
|
|
@@ -20,7 +20,7 @@ export interface VideoViewProps extends ViewProps {
|
|
|
20
20
|
/**
|
|
21
21
|
* A video player instance. Use [`useVideoPlayer()`](#usevideoplayersource-setup) hook to create one.
|
|
22
22
|
*/
|
|
23
|
-
player
|
|
23
|
+
player?: VideoPlayer | null;
|
|
24
24
|
/**
|
|
25
25
|
* Determines whether native controls should be displayed or not.
|
|
26
26
|
*
|
|
@@ -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;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC;AAExD,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;
|
|
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,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAE5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAE7B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAEtC;;;;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;IAExB;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;IAE9C;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,UAAU,GACV,YAAY,GACZ,cAAc,GACd,WAAW,GACX,eAAe,GACf,gBAAgB,CAAC;AAErB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC"}
|
|
@@ -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\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
|
|
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 | null;\n\n /**\n * Determines whether native controls should be displayed or not.\n *\n * > **Note**: Due to platform limitations, the native controls are always enabled in fullscreen mode.\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 *\n * > Note: This option has been deprecated in favor of the `fullscreenOptions` prop and will be disabled in the future.\n * @default true\n */\n allowsFullscreen?: boolean;\n\n /**\n * Determines the fullscreen mode options.\n */\n fullscreenOptions?: FullscreenOptions;\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 false\n */\n useExoShutter?: boolean;\n\n /**\n * Determines the [cross origin policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/crossorigin) used by the underlying native view on web.\n * If `undefined` (default), does not use CORS at all. If set to `'anonymous'`, the video will be loaded with CORS enabled.\n * Note that some videos may not play if CORS is enabled, depending on the CDN settings.\n * If you encounter issues, consider adjusting the `crossOrigin` property.\n *\n *\n * @platform web\n * @default undefined\n */\n crossOrigin?: 'anonymous' | 'use-credentials';\n\n /**\n * Use Audio Nodes for sound playback. When the same player is playing in multiple video views the audio won't increase in volume\n * as the number of players increases.\n *\n * > **Note**: This property is experimental, when enabled it is known to break audio for some sources. Do not change this property at runtime.\n *\n * @experimental\n * @default false\n * @platform web\n */\n useAudioNodePlayback?: boolean;\n}\n\n/**\n * Describes the orientation of the video in fullscreen mode. Available values are:\n * - `default`: The video is displayed in any of the available device rotations.\n * - `portrait`: The video is displayed in one of two available portrait orientations and rotates between them.\n * - `portraitUp`: The video is displayed in the portrait orientation - the notch of the phone points upwards.\n * - `portraitDown`: The video is displayed in the portrait orientation - the notch of the phone points downwards.\n * - `landscape`: The video is displayed in one of two available landscape orientations and rotates between them.\n * - `landscapeLeft`: The video is displayed in the left landscape orientation - the notch of the phone is in the left palm of the user.\n * - `landscapeRight`: The video is displayed in the right landscape orientation - the notch of the phone is in the right palm of the user.\n */\nexport type FullscreenOrientation =\n | 'default'\n | 'portrait'\n | 'portraitUp'\n | 'portraitDown'\n | 'landscape'\n | 'landscapeLeft'\n | 'landscapeRight';\n\n/**\n * Describes the options for fullscreen video mode.\n */\nexport type FullscreenOptions = {\n /**\n * Specifies whether the fullscreen mode should be available to the user. When `false`, the fullscreen button will be hidden in the player.\n * Equivalent to the `allowsFullscreen` prop.\n * @default true\n */\n enable: boolean;\n /**\n * Specifies the orientation of the video in fullscreen mode.\n * @default 'default'\n * @platform android\n * @platform ios\n */\n orientation?: FullscreenOrientation;\n /**\n * Specifies whether the app should exit fullscreen mode when the device is rotated to a different orientation than the one specified in the `orientation` prop.\n * For example, if the `orientation` prop is set to `landscape` and the device is rotated to `portrait`, the app will exit fullscreen mode.\n *\n * > This prop will have no effect if the `orientation` prop is set to `default`.\n * > The `VideoView` will never auto-exit fullscreen when the device auto-rotate feature has been disabled in settings.\n *\n * @default false\n * @platform android\n * @platform ios\n */\n autoExitOnRotate?: 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;AA6BxD,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,eAAO,MAAM,SAAS;aAAiC,WAAW;
|
|
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;AA6BxD,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED,eAAO,MAAM,SAAS;aAAiC,WAAW;kDA0PhE,CAAC;AAEH,eAAe,SAAS,CAAC"}
|