expo-video 3.0.14 → 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 +8 -13
- package/android/build.gradle +3 -3
- package/android/src/main/java/expo/modules/video/FullscreenPlayerActivity.kt +5 -1
- package/android/src/main/java/expo/modules/video/VideoModule.kt +19 -3
- package/android/src/main/java/expo/modules/video/VideoView.kt +10 -6
- 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 +33 -12
- package/android/src/main/java/expo/modules/video/player/VideoPlayerListener.kt +2 -0
- package/android/src/main/java/expo/modules/video/records/ScrubbingModeOptions.kt +31 -0
- package/android/src/main/java/expo/modules/video/records/SeekTolerance.kt +28 -0
- package/android/src/main/java/expo/modules/video/utils/MutableWeakReference.kt +13 -2
- package/build/VideoPlayer.types.d.ts +94 -2
- package/build/VideoPlayer.types.d.ts.map +1 -1
- package/build/VideoPlayer.types.js.map +1 -1
- package/build/VideoPlayer.web.d.ts +4 -2
- package/build/VideoPlayer.web.d.ts.map +1 -1
- package/build/VideoPlayer.web.js +2 -0
- 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/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/Records/ScrubbingModeOptions.swift +7 -0
- package/ios/Records/SeekTolerance.swift +20 -0
- package/ios/VideoModule.swift +16 -2
- package/ios/VideoPlayer.swift +19 -22
- package/ios/VideoPlayerAudioTracks.swift +26 -9
- package/ios/VideoPlayerObserver.swift +68 -12
- package/ios/VideoPlayerSeeker.swift +77 -0
- package/ios/VideoPlayerSubtitles.swift +26 -9
- package/local-maven-repo/host/exp/exponent/expo.modules.video/{3.0.14/expo.modules.video-3.0.14-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.0.14/expo.modules.video-3.0.14.module → 3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.module} +25 -25
- 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.0.14/expo.modules.video-3.0.14.pom → 3.1.0-canary-20251118-4ca99d5/expo.modules.video-3.1.0-canary-20251118-4ca99d5.pom} +3 -3
- 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 +4 -5
- package/src/VideoPlayer.types.ts +102 -2
- package/src/VideoPlayer.web.tsx +5 -1
- package/src/VideoView.tsx +1 -1
- package/src/VideoView.types.ts +1 -1
- package/src/VideoView.web.tsx +14 -3
- package/src/index.ts +1 -17
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14-sources.jar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14-sources.jar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14-sources.jar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14-sources.jar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.aar.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.aar.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.aar.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.aar.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.module.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.module.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.module.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.module.sha512 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.pom.md5 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.pom.sha1 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.pom.sha256 +0 -1
- package/local-maven-repo/host/exp/exponent/expo.modules.video/3.0.14/expo.modules.video-3.0.14.pom.sha512 +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,19 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
### 🎉 New features
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
### 💡 Others
|
|
12
|
-
|
|
13
|
-
## 3.0.14 — 2025-11-05
|
|
14
|
-
|
|
15
|
-
_This version does not introduce any user-facing changes._
|
|
16
|
-
|
|
17
|
-
## 3.0.13 — 2025-11-03
|
|
18
|
-
|
|
19
|
-
_This version does not introduce any user-facing changes._
|
|
20
|
-
|
|
21
|
-
## 3.0.12 — 2025-10-28
|
|
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))
|
|
22
11
|
|
|
23
12
|
### 🐛 Bug fixes
|
|
24
13
|
|
|
@@ -26,6 +15,12 @@ _This version does not introduce any user-facing changes._
|
|
|
26
15
|
- [iOS] Fix crashes when rapidly replacing HLS sources. ([#40265](https://github.com/expo/expo/pull/40265) by [@behenate](https://github.com/behenate))
|
|
27
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))
|
|
28
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))
|
|
19
|
+
|
|
20
|
+
### 💡 Others
|
|
21
|
+
|
|
22
|
+
- [Android] Remove @UnstableReactNativeAPI annotations. ([#39921](https://github.com/expo/expo/pull/39921) by [@jakex7](https://github.com/jakex7))
|
|
23
|
+
- [iOS] Load track information for events in asynchronous context. ([#40355](https://github.com/expo/expo/pull/40355) by [@behenate](https://github.com/behenate))
|
|
29
24
|
|
|
30
25
|
## 3.0.11 — 2025-09-10
|
|
31
26
|
|
package/android/build.gradle
CHANGED
|
@@ -4,13 +4,13 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'host.exp.exponent'
|
|
7
|
-
version = '3.0
|
|
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.0
|
|
13
|
+
versionName '3.1.0-canary-20251118-4ca99d5'
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -26,7 +26,7 @@ dependencies {
|
|
|
26
26
|
implementation "androidx.media3:media3-ui:${androidxMedia3Version}"
|
|
27
27
|
implementation "androidx.media3:media3-datasource-okhttp:${androidxMedia3Version}"
|
|
28
28
|
|
|
29
|
-
def fragment_version = "1.
|
|
29
|
+
def fragment_version = "1.8.9"
|
|
30
30
|
implementation "androidx.fragment:fragment:$fragment_version"
|
|
31
31
|
implementation "androidx.fragment:fragment-ktx:$fragment_version"
|
|
32
32
|
}
|
|
@@ -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)
|
|
@@ -7,7 +7,6 @@ import androidx.media3.common.PlaybackParameters
|
|
|
7
7
|
import androidx.media3.common.Player.REPEAT_MODE_OFF
|
|
8
8
|
import androidx.media3.common.Player.REPEAT_MODE_ONE
|
|
9
9
|
import androidx.media3.common.util.UnstableApi
|
|
10
|
-
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
|
11
10
|
import expo.modules.kotlin.Promise
|
|
12
11
|
import expo.modules.kotlin.apifeatures.EitherType
|
|
13
12
|
import expo.modules.kotlin.functions.Coroutine
|
|
@@ -23,6 +22,8 @@ import expo.modules.video.records.BufferOptions
|
|
|
23
22
|
import expo.modules.video.records.FullscreenOptions
|
|
24
23
|
import expo.modules.video.records.SubtitleTrack
|
|
25
24
|
import expo.modules.video.records.AudioTrack
|
|
25
|
+
import expo.modules.video.records.ScrubbingModeOptions
|
|
26
|
+
import expo.modules.video.records.SeekTolerance
|
|
26
27
|
import expo.modules.video.records.VideoSource
|
|
27
28
|
import expo.modules.video.records.VideoThumbnailOptions
|
|
28
29
|
import expo.modules.video.utils.runWithPiPMisconfigurationSoftHandling
|
|
@@ -33,7 +34,6 @@ import kotlinx.coroutines.runBlocking
|
|
|
33
34
|
import kotlin.time.Duration
|
|
34
35
|
|
|
35
36
|
// https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide#improvements_in_media3
|
|
36
|
-
@UnstableReactNativeAPI
|
|
37
37
|
@androidx.annotation.OptIn(UnstableApi::class)
|
|
38
38
|
class VideoModule : Module() {
|
|
39
39
|
override fun definition() = ModuleDefinition {
|
|
@@ -300,6 +300,22 @@ class VideoModule : Module() {
|
|
|
300
300
|
ref.keepScreenOnWhilePlaying = value ?: true
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
Property("seekTolerance")
|
|
304
|
+
.get { ref: VideoPlayer ->
|
|
305
|
+
ref.seekTolerance
|
|
306
|
+
}
|
|
307
|
+
.set { ref: VideoPlayer, tolerance: SeekTolerance? ->
|
|
308
|
+
ref.seekTolerance = tolerance ?: SeekTolerance()
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
Property("scrubbingModeOptions")
|
|
312
|
+
.get { ref: VideoPlayer ->
|
|
313
|
+
ref.scrubbingModeOptions
|
|
314
|
+
}
|
|
315
|
+
.set { ref: VideoPlayer, options: ScrubbingModeOptions? ->
|
|
316
|
+
ref.scrubbingModeOptions = options ?: ScrubbingModeOptions()
|
|
317
|
+
}
|
|
318
|
+
|
|
303
319
|
Function("replace") { ref: VideoPlayer, source: Either<Uri, VideoSource>? ->
|
|
304
320
|
replaceImpl(ref, source)
|
|
305
321
|
}
|
|
@@ -383,7 +399,7 @@ private inline fun <reified T : VideoView> ViewDefinitionBuilder<T>.VideoViewCom
|
|
|
383
399
|
"onFullscreenExit",
|
|
384
400
|
"onFirstFrameRender"
|
|
385
401
|
)
|
|
386
|
-
Prop("player") { view: T, player: VideoPlayer ->
|
|
402
|
+
Prop("player") { view: T, player: VideoPlayer? ->
|
|
387
403
|
view.videoPlayer = player
|
|
388
404
|
}
|
|
389
405
|
Prop("nativeControls") { view: T, useNativeControls: Boolean ->
|
|
@@ -114,17 +114,19 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
|
|
|
114
114
|
VideoManager.onVideoPlayerDetachedFromView(it, this)
|
|
115
115
|
}
|
|
116
116
|
val oldPlayer = videoPlayer
|
|
117
|
+
val hasEmittedFirstFrame = newPlayer?.firstFrameEventGenerator?.hasSentFirstFrameForCurrentMediaItem
|
|
118
|
+
?: false
|
|
117
119
|
oldPlayer?.removeListener(this)
|
|
118
120
|
newPlayer?.addListener(this)
|
|
119
121
|
field = newPlayer
|
|
120
|
-
shouldHideSurfaceView = !
|
|
122
|
+
shouldHideSurfaceView = !hasEmittedFirstFrame
|
|
121
123
|
applySurfaceViewVisibility()
|
|
122
124
|
attachPlayer()
|
|
123
125
|
newPlayer?.let {
|
|
124
126
|
VideoManager.onVideoPlayerAttachedToView(it, this)
|
|
125
127
|
}
|
|
126
128
|
if (oldPlayer != newPlayer) {
|
|
127
|
-
oldPlayer?.
|
|
129
|
+
oldPlayer?.hasBeenDisconnectedFromVideoView()
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
|
|
@@ -219,7 +221,7 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
|
|
|
219
221
|
}
|
|
220
222
|
|
|
221
223
|
fun attachPlayer() {
|
|
222
|
-
videoPlayer?.
|
|
224
|
+
videoPlayer?.changeVideoView(this)
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
fun exitFullscreen() {
|
|
@@ -306,9 +308,11 @@ open class VideoView(context: Context, appContext: AppContext, useTextureView: B
|
|
|
306
308
|
}
|
|
307
309
|
|
|
308
310
|
override fun onRenderedFirstFrame(player: VideoPlayer) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
311
|
+
if (player.currentVideoView == this) {
|
|
312
|
+
shouldHideSurfaceView = false
|
|
313
|
+
applySurfaceViewVisibility()
|
|
314
|
+
onFirstFrameRender(Unit)
|
|
315
|
+
}
|
|
312
316
|
}
|
|
313
317
|
|
|
314
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
|
|
@@ -37,6 +38,8 @@ import expo.modules.video.playbackService.ExpoVideoPlaybackService
|
|
|
37
38
|
import expo.modules.video.playbackService.PlaybackServiceConnection
|
|
38
39
|
import expo.modules.video.records.BufferOptions
|
|
39
40
|
import expo.modules.video.records.PlaybackError
|
|
41
|
+
import expo.modules.video.records.ScrubbingModeOptions
|
|
42
|
+
import expo.modules.video.records.SeekTolerance
|
|
40
43
|
import expo.modules.video.records.TimeUpdate
|
|
41
44
|
import expo.modules.video.records.VideoSource
|
|
42
45
|
import expo.modules.video.utils.MutableWeakReference
|
|
@@ -53,7 +56,10 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
53
56
|
.forceEnableMediaCodecAsynchronousQueueing()
|
|
54
57
|
.setEnableDecoderFallback(true)
|
|
55
58
|
private var listeners: MutableList<WeakReference<VideoPlayerListener>> = mutableListOf()
|
|
56
|
-
private
|
|
59
|
+
private val currentVideoViewRef = MutableWeakReference<VideoView?>(null) { new, old ->
|
|
60
|
+
sendEvent(PlayerEvent.TargetViewChanged(new, old))
|
|
61
|
+
}
|
|
62
|
+
var currentVideoView by currentVideoViewRef
|
|
57
63
|
val loadControl: VideoPlayerLoadControl = VideoPlayerLoadControl()
|
|
58
64
|
val subtitles: VideoPlayerSubtitles = VideoPlayerSubtitles(this)
|
|
59
65
|
val audioTracks: VideoPlayerAudioTracks = VideoPlayerAudioTracks(this)
|
|
@@ -65,11 +71,10 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
65
71
|
.setLoadControl(loadControl)
|
|
66
72
|
.build()
|
|
67
73
|
|
|
68
|
-
|
|
74
|
+
internal lateinit var firstFrameEventGenerator: FirstFrameEventGenerator
|
|
69
75
|
val serviceConnection = PlaybackServiceConnection(WeakReference(this), appContext)
|
|
70
76
|
val intervalUpdateClock = IntervalUpdateClock(this)
|
|
71
77
|
|
|
72
|
-
var hasRenderedAFrameOfVideoSource = false
|
|
73
78
|
var playing by IgnoreSameSet(false) { new, old ->
|
|
74
79
|
sendEvent(PlayerEvent.IsPlayingChanged(new, old))
|
|
75
80
|
}
|
|
@@ -180,6 +185,22 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
180
185
|
sendEvent(PlayerEvent.VideoTrackChanged(value, old))
|
|
181
186
|
}
|
|
182
187
|
|
|
188
|
+
var seekTolerance: SeekTolerance = SeekTolerance()
|
|
189
|
+
set(value) {
|
|
190
|
+
field = value
|
|
191
|
+
appContext?.mainQueue?.launch {
|
|
192
|
+
seekTolerance.applyToPlayer(this@VideoPlayer)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
var scrubbingModeOptions: ScrubbingModeOptions = ScrubbingModeOptions()
|
|
197
|
+
set(value) {
|
|
198
|
+
field = value
|
|
199
|
+
appContext?.mainQueue?.launch {
|
|
200
|
+
scrubbingModeOptions.applyToPlayer(this@VideoPlayer)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
183
204
|
var availableVideoTracks: List<VideoTrack> = emptyList()
|
|
184
205
|
private set
|
|
185
206
|
|
|
@@ -255,7 +276,6 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
255
276
|
resetPlaybackInfo()
|
|
256
277
|
}
|
|
257
278
|
subtitles.setSubtitlesEnabled(false)
|
|
258
|
-
hasRenderedAFrameOfVideoSource = false
|
|
259
279
|
super.onMediaItemTransition(mediaItem, reason)
|
|
260
280
|
}
|
|
261
281
|
|
|
@@ -307,6 +327,7 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
307
327
|
|
|
308
328
|
// ExoPlayer will enable subtitles automatically at the start, we want them disabled by default
|
|
309
329
|
appContext.mainQueue.launch {
|
|
330
|
+
firstFrameEventGenerator = createFirstFrameEventGenerator()
|
|
310
331
|
subtitles.setSubtitlesEnabled(false)
|
|
311
332
|
}
|
|
312
333
|
}
|
|
@@ -319,6 +340,7 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
319
340
|
VideoManager.unregisterVideoPlayer(this@VideoPlayer)
|
|
320
341
|
|
|
321
342
|
appContext?.mainQueue?.launch {
|
|
343
|
+
firstFrameEventGenerator.release()
|
|
322
344
|
player.removeListener(playerListener)
|
|
323
345
|
player.release()
|
|
324
346
|
}
|
|
@@ -336,16 +358,16 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
336
358
|
/**
|
|
337
359
|
* Used to notify the player that is has been disconnected from the player view by another player.
|
|
338
360
|
*/
|
|
339
|
-
fun
|
|
340
|
-
if (
|
|
361
|
+
fun hasBeenDisconnectedFromVideoView() {
|
|
362
|
+
if (currentVideoView?.playerView?.player == this.player) {
|
|
341
363
|
throw IllegalStateException("The player has been notified of disconnection from the player view, even though it's still connected.")
|
|
342
364
|
}
|
|
343
|
-
|
|
365
|
+
currentVideoView = null
|
|
344
366
|
}
|
|
345
367
|
|
|
346
|
-
fun
|
|
347
|
-
PlayerView.switchTargetView(player,
|
|
348
|
-
|
|
368
|
+
fun changeVideoView(videoView: VideoView?) {
|
|
369
|
+
PlayerView.switchTargetView(player, currentVideoView?.playerView, videoView?.playerView)
|
|
370
|
+
currentVideoView = videoView
|
|
349
371
|
}
|
|
350
372
|
|
|
351
373
|
fun prepare() {
|
|
@@ -465,8 +487,7 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou
|
|
|
465
487
|
}
|
|
466
488
|
|
|
467
489
|
private fun createFirstFrameEventGenerator(): FirstFrameEventGenerator {
|
|
468
|
-
return FirstFrameEventGenerator(
|
|
469
|
-
hasRenderedAFrameOfVideoSource = true
|
|
490
|
+
return FirstFrameEventGenerator(this, currentVideoViewRef) {
|
|
470
491
|
sendEvent(PlayerEvent.RenderedFirstFrame())
|
|
471
492
|
}
|
|
472
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
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
package expo.modules.video.records
|
|
2
|
+
|
|
3
|
+
import androidx.media3.common.util.UnstableApi
|
|
4
|
+
import androidx.media3.exoplayer.ScrubbingModeParameters
|
|
5
|
+
import expo.modules.kotlin.records.Record
|
|
6
|
+
import expo.modules.kotlin.records.Field
|
|
7
|
+
import expo.modules.video.player.VideoPlayer
|
|
8
|
+
import java.io.Serializable
|
|
9
|
+
|
|
10
|
+
@UnstableApi
|
|
11
|
+
class ScrubbingModeOptions(
|
|
12
|
+
@Field var scrubbingModeEnabled: Boolean = false,
|
|
13
|
+
@Field var increaseCodecOperatingRate: Boolean = true,
|
|
14
|
+
@Field var enableDynamicScheduling: Boolean = true,
|
|
15
|
+
@Field var useDecodeOnlyFlag: Boolean = true,
|
|
16
|
+
@Field var allowSkippingMediaCodecFlush: Boolean = true
|
|
17
|
+
) : Record, Serializable {
|
|
18
|
+
fun applyToPlayer(videoPlayer: VideoPlayer) {
|
|
19
|
+
videoPlayer.player.isScrubbingModeEnabled = scrubbingModeEnabled
|
|
20
|
+
videoPlayer.player.scrubbingModeParameters = toScrubbingModeParameters()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private fun toScrubbingModeParameters(): ScrubbingModeParameters {
|
|
24
|
+
return ScrubbingModeParameters.Builder()
|
|
25
|
+
.setUseDecodeOnlyFlag(useDecodeOnlyFlag)
|
|
26
|
+
.setAllowSkippingMediaCodecFlush(allowSkippingMediaCodecFlush)
|
|
27
|
+
.setShouldIncreaseCodecOperatingRate(increaseCodecOperatingRate)
|
|
28
|
+
.setShouldEnableDynamicScheduling(enableDynamicScheduling)
|
|
29
|
+
.build()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package expo.modules.video.records
|
|
2
|
+
|
|
3
|
+
import androidx.media3.common.util.UnstableApi
|
|
4
|
+
import androidx.media3.common.util.Util
|
|
5
|
+
import androidx.media3.exoplayer.SeekParameters
|
|
6
|
+
import expo.modules.kotlin.records.Field
|
|
7
|
+
import expo.modules.kotlin.records.Record
|
|
8
|
+
import expo.modules.video.player.VideoPlayer
|
|
9
|
+
import java.io.Serializable
|
|
10
|
+
|
|
11
|
+
@UnstableApi
|
|
12
|
+
class SeekTolerance(
|
|
13
|
+
@Field var toleranceBefore: Double = 0.0,
|
|
14
|
+
@Field var toleranceAfter: Double = 0.0
|
|
15
|
+
) : Record, Serializable {
|
|
16
|
+
fun applyToPlayer(videoPlayer: VideoPlayer) {
|
|
17
|
+
videoPlayer.player.setSeekParameters(toSeekParameters())
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
private fun toSeekParameters(): SeekParameters {
|
|
21
|
+
val toleranceBeforeMs = (toleranceBefore * 1000).toLong()
|
|
22
|
+
val toleranceAfterMs = (toleranceAfter * 1000).toLong()
|
|
23
|
+
return SeekParameters(
|
|
24
|
+
Util.msToUs(toleranceBeforeMs),
|
|
25
|
+
Util.msToUs(toleranceAfterMs)
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -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
|
}
|
|
@@ -42,8 +42,7 @@ export declare class VideoPlayer extends SharedObject<VideoPlayerEvents> {
|
|
|
42
42
|
* at which playback will begin once the `play()` method is called.
|
|
43
43
|
*
|
|
44
44
|
* Setting `currentTime` to a new value seeks the player to the given time.
|
|
45
|
-
*
|
|
46
|
-
* Consider using the [`seekBy`](#seekbyseconds) function if the time does not have to be set precisely.
|
|
45
|
+
* Check out the [`seekTolerance`](#seektolerance) property to configure the seeking precision.
|
|
47
46
|
*/
|
|
48
47
|
currentTime: number;
|
|
49
48
|
/**
|
|
@@ -202,6 +201,23 @@ export declare class VideoPlayer extends SharedObject<VideoPlayerEvents> {
|
|
|
202
201
|
* @platform ios
|
|
203
202
|
*/
|
|
204
203
|
readonly isExternalPlaybackActive: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Determines the time that the actual position seeked to may precede or exceed the requested seek position.
|
|
206
|
+
*
|
|
207
|
+
* This property affects the precision of setting the [`currentTime`](#currenttime) property and the [`seekBy`](#seekbyseconds) method, and on Android, it also affects the accuracy of the scrubber from the default native controls.
|
|
208
|
+
*
|
|
209
|
+
* By default, the player seeks to the exact requested time.
|
|
210
|
+
*
|
|
211
|
+
* > If you are trying to optimize for scrubbing (many frequent seeks), also see [`ScrubbingModeOptions`](#scrubbingmodeoptions-1).
|
|
212
|
+
*/
|
|
213
|
+
seekTolerance: SeekTolerance;
|
|
214
|
+
/**
|
|
215
|
+
* Determines whether the scrubbing mode is enabled and what scrubbing optimizations should be enabled.
|
|
216
|
+
*
|
|
217
|
+
* > See [`SeekTolerance`](#seektolerance) to set the seeking tolerance, which can also affect the scrubbing performance.
|
|
218
|
+
*
|
|
219
|
+
*/
|
|
220
|
+
scrubbingModeOptions: ScrubbingModeOptions;
|
|
205
221
|
/**
|
|
206
222
|
* Initializes a new video player instance with the given source.
|
|
207
223
|
*
|
|
@@ -552,4 +568,80 @@ export type AudioTrack = {
|
|
|
552
568
|
*/
|
|
553
569
|
label: string;
|
|
554
570
|
};
|
|
571
|
+
/**
|
|
572
|
+
* Determines the time that the actual position seeked to may precede or exceed the requested seek position.
|
|
573
|
+
* Larger tolerance will usually result in faster seeking.
|
|
574
|
+
* This property affects the precision of setting the [`currentTime`](#currenttime) property and the [`seekBy`](#seekbyseconds) method, and on Android, it also affects the accuracy of the scrubber from the default native controls.
|
|
575
|
+
*
|
|
576
|
+
* > If you are trying to optimize for scrubbing (many frequent seeks), also see [`ScrubbingModeOptions`](#scrubbingmodeoptions-1).
|
|
577
|
+
*
|
|
578
|
+
* @platform android
|
|
579
|
+
* @platform ios
|
|
580
|
+
*/
|
|
581
|
+
export type SeekTolerance = {
|
|
582
|
+
/**
|
|
583
|
+
* The maximum time that the actual position seeked to may precede the requested seek position, in seconds. Must be non-negative.
|
|
584
|
+
* @default 0
|
|
585
|
+
*/
|
|
586
|
+
toleranceBefore?: number;
|
|
587
|
+
/**
|
|
588
|
+
* The maximum time that the actual position seeked to may exceed the requested seek position, in seconds. Must be non-negative.
|
|
589
|
+
* @default 0
|
|
590
|
+
*/
|
|
591
|
+
toleranceAfter?: number;
|
|
592
|
+
};
|
|
593
|
+
/**
|
|
594
|
+
* Defines scrubbing mode options used by a [`VideoPlayer`](#videoplayer).
|
|
595
|
+
*/
|
|
596
|
+
export type ScrubbingModeOptions = {
|
|
597
|
+
/**
|
|
598
|
+
* Whether the codec operating rate should be increased in scrubbing mode.
|
|
599
|
+
*
|
|
600
|
+
* You should only enable this when the player is receiving a large number of seeks in a short period of time. For less frequent seeks, fine-tuning the [`SeekTolerance`](#seektolerance-1) may be sufficient.
|
|
601
|
+
*
|
|
602
|
+
* On Android, the player may consume more resources in this mode, so it should only be used for short periods of time in response to user interaction (for example, dragging on a progress bar UI element).
|
|
603
|
+
*
|
|
604
|
+
* On Android, when `scrubbingModeEnabled` is `true`, the playback is suppressed. You should set this property back to `false` when the user interaction ends to allow the playback to resume.
|
|
605
|
+
* For best results, on iOS you should pause the playback when scrubbing.
|
|
606
|
+
*
|
|
607
|
+
* > For best scrubbing performance, consider also increasing the seeking tolerance using the [`SeekTolerance`](#seektolerance-1) property.
|
|
608
|
+
*
|
|
609
|
+
* > Other scrubbing mode options will have no effect when this is `false`.
|
|
610
|
+
* @default false
|
|
611
|
+
* @platform android
|
|
612
|
+
* @platform ios
|
|
613
|
+
*/
|
|
614
|
+
scrubbingModeEnabled?: boolean;
|
|
615
|
+
/**
|
|
616
|
+
* Whether the codec operating rate should be increased in scrubbing mode.
|
|
617
|
+
*
|
|
618
|
+
* @platform android
|
|
619
|
+
* @default true
|
|
620
|
+
*/
|
|
621
|
+
increaseCodecOperatingRate?: boolean;
|
|
622
|
+
/**
|
|
623
|
+
* Sets whether ExoPlayer's dynamic scheduling should be enabled in scrubbing mode.
|
|
624
|
+
* This can result in available output buffers being handled more quickly when seeking.
|
|
625
|
+
*
|
|
626
|
+
* @platform android
|
|
627
|
+
* @default true
|
|
628
|
+
*/
|
|
629
|
+
enableDynamicScheduling?: boolean;
|
|
630
|
+
/**
|
|
631
|
+
* Sets whether to use `MediaCodec.BUFFER_FLAG_DECODE_ONLY` in scrubbing mode.
|
|
632
|
+
* When playback is using MediaCodec on API 34+, this flag can speed up seeking by signalling that the decoded output of buffers between the previous keyframe and the target frame is not needed by the player.
|
|
633
|
+
*
|
|
634
|
+
* @platform android
|
|
635
|
+
* @default true
|
|
636
|
+
*/
|
|
637
|
+
useDecodeOnlyFlag?: boolean;
|
|
638
|
+
/**
|
|
639
|
+
* Sets whether to avoid flushing the decoder (where possible) in scrubbing mode.
|
|
640
|
+
* When `true`, avoids flushing the decoder when a new seek starts decoding from a key-frame in compatible content.
|
|
641
|
+
*
|
|
642
|
+
* @platform android
|
|
643
|
+
* @default true
|
|
644
|
+
*/
|
|
645
|
+
allowSkippingMediaCodecFlush?: boolean;
|
|
646
|
+
};
|
|
555
647
|
//# 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
|
|
1
|
+
{"version":3,"file":"VideoPlayer.types.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.types.ts"],"names":[],"mappings":"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"}
|