react-native-theoplayer 2.7.0 → 2.8.0
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 +27 -0
- package/android/build.gradle +1 -1
- package/android/local/com/theoplayer/android-connector/mediasession/5.2.0-local/mediasession-5.2.0-local.aar +0 -0
- package/android/local/com/theoplayer/android-connector/mediasession/{4.12.0-local/mediasession-4.12.0-local.pom → 5.2.0-local/mediasession-5.2.0-local.pom} +1 -1
- package/android/local/com/theoplayer/android-connector/mediasession/maven-metadata-local.xml +4 -4
- package/android/src/main/AndroidManifest.xml +2 -2
- package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +1 -1
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerContext.kt +36 -20
- package/android/src/main/java/com/theoplayer/media/CustomMediaButtonReceiver.kt +25 -0
- package/android/src/main/java/com/theoplayer/{audio → media}/MediaNotificationBuilder.kt +1 -1
- package/android/src/main/java/com/theoplayer/{audio → media}/MediaPlaybackService.kt +8 -3
- package/android/src/main/java/com/theoplayer/source/SourceAdapter.kt +12 -0
- package/android/src/main/java/com/theoplayer/track/TrackListAdapter.kt +17 -13
- package/lib/commonjs/api/source/dash/DashPlaybackConfiguration.js.map +1 -1
- package/lib/commonjs/api/track/TextTrack.js.map +1 -1
- package/lib/commonjs/internal/adapter/THEOplayerAdapter.js +17 -0
- package/lib/commonjs/internal/adapter/THEOplayerAdapter.js.map +1 -1
- package/lib/commonjs/internal/adapter/web/FullscreenAPI.js +41 -0
- package/lib/commonjs/internal/adapter/web/FullscreenAPI.js.map +1 -0
- package/lib/commonjs/internal/adapter/web/WebPresentationModeManager.js +45 -39
- package/lib/commonjs/internal/adapter/web/WebPresentationModeManager.js.map +1 -1
- package/lib/commonjs/internal/utils/CommonUtils.js +10 -0
- package/lib/commonjs/internal/utils/CommonUtils.js.map +1 -0
- package/lib/commonjs/ui/components/seekbar/thumbnail/Urlpolyfill.web.js +4 -11
- package/lib/commonjs/ui/components/seekbar/thumbnail/Urlpolyfill.web.js.map +1 -1
- package/lib/module/api/source/dash/DashPlaybackConfiguration.js.map +1 -1
- package/lib/module/api/track/TextTrack.js.map +1 -1
- package/lib/module/internal/adapter/THEOplayerAdapter.js +18 -1
- package/lib/module/internal/adapter/THEOplayerAdapter.js.map +1 -1
- package/lib/module/internal/adapter/web/FullscreenAPI.js +34 -0
- package/lib/module/internal/adapter/web/FullscreenAPI.js.map +1 -0
- package/lib/module/internal/adapter/web/WebPresentationModeManager.js +45 -39
- package/lib/module/internal/adapter/web/WebPresentationModeManager.js.map +1 -1
- package/lib/module/internal/utils/CommonUtils.js +4 -0
- package/lib/module/internal/utils/CommonUtils.js.map +1 -0
- package/lib/module/ui/components/seekbar/thumbnail/Urlpolyfill.web.js +3 -2
- package/lib/module/ui/components/seekbar/thumbnail/Urlpolyfill.web.js.map +1 -1
- package/lib/typescript/api/source/dash/DashPlaybackConfiguration.d.ts +52 -0
- package/lib/typescript/api/track/TextTrack.d.ts +2 -2
- package/lib/typescript/internal/adapter/THEOplayerAdapter.d.ts +1 -0
- package/lib/typescript/internal/adapter/web/FullscreenAPI.d.ts +9 -0
- package/lib/typescript/internal/utils/CommonUtils.d.ts +1 -0
- package/lib/typescript/ui/components/seekbar/thumbnail/Urlpolyfill.web.d.ts +8 -1
- package/package.json +1 -1
- package/src/api/source/dash/DashPlaybackConfiguration.ts +56 -0
- package/src/api/track/TextTrack.ts +2 -2
- package/src/internal/adapter/THEOplayerAdapter.ts +19 -0
- package/src/internal/adapter/web/FullscreenAPI.ts +59 -0
- package/src/internal/adapter/web/WebPresentationModeManager.ts +29 -22
- package/src/internal/utils/CommonUtils.ts +3 -0
- package/src/ui/components/seekbar/thumbnail/Urlpolyfill.web.ts +3 -2
- package/android/local/com/theoplayer/android-connector/mediasession/4.12.0-local/mediasession-4.12.0-local.aar +0 -0
- package/lib/commonjs/web/platform/BrowserDetection.js +0 -34
- package/lib/commonjs/web/platform/BrowserDetection.js.map +0 -1
- package/lib/module/web/platform/BrowserDetection.js +0 -27
- package/lib/module/web/platform/BrowserDetection.js.map +0 -1
- package/lib/typescript/web/platform/BrowserDetection.d.ts +0 -23
- package/src/web/platform/BrowserDetection.ts +0 -38
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.8.0] - 23-06-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added `ignoreAvailabilityWindow` property to `SourceDescription.dash` for Android and Web.
|
|
13
|
+
- Added `needsTimescaleShifting`, `desiredTimescale` and `forceSeekToSynchronize` properties to `SourceDescription.dash` for Web.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixed an issue where text track cue changes were not applied to the TextTrack's `cue` property.
|
|
18
|
+
- Fixed an issue on Android where play-out of an MP4 stream would sometimes crash the player.
|
|
19
|
+
- Fixed an issue on Android where a `pause` event would not be dispatched while pausing during play-out of an ad.
|
|
20
|
+
- Fixed an issue on Android where hardware buttons, such as `play` and `pause`, were not handled anymore after toggling background audio support.
|
|
21
|
+
- Fixed an issue on Android where the app would crash when toggling background playback while multiple `MediaBrowserServiceCompat` instances are registered.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Improved fullscreen support to use non-native fullscreen on Safari for iPad and Mac.
|
|
26
|
+
- Limited the set of available media session actions on Android when an ad or live stream is playing.
|
|
27
|
+
- Removed pausing the stream when disabling background playback on Android.
|
|
28
|
+
|
|
8
29
|
## [2.7.0] - 23-05-15
|
|
9
30
|
|
|
10
31
|
### Changed
|
|
@@ -14,6 +35,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
14
35
|
### Fixed
|
|
15
36
|
|
|
16
37
|
- Fixed an issue on Android where if an invalid view tag is passed to the native bridge, it would crash the player.
|
|
38
|
+
- Fixed an issue on Web where preview thumbnails would fail to load.
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- Updated UI documentation with necessary dependencies.
|
|
43
|
+
- Added improved debug logging on iOS.
|
|
17
44
|
|
|
18
45
|
## [2.6.0] - 23-05-05
|
|
19
46
|
|
package/android/build.gradle
CHANGED
|
@@ -109,7 +109,7 @@ dependencies {
|
|
|
109
109
|
def theoplayer_sdk_version = safeExtGet('THEOplayer_sdk', '[5.0.1,)')
|
|
110
110
|
|
|
111
111
|
// def theoplayer_mediasession_version = safeExtGet('THEOplayer_mediasession', theoplayer_sdk_version)
|
|
112
|
-
def theoplayer_mediasession_version = "
|
|
112
|
+
def theoplayer_mediasession_version = "5.2.0-local"
|
|
113
113
|
def enabledV4 = theoplayer_sdk_version.toString().startsWith("4.")
|
|
114
114
|
def core_prefix = enabledV4 ? 'unified' : 'core'
|
|
115
115
|
def integration_prefix = enabledV4 ? 'unified' : 'integration'
|
|
Binary file
|
package/android/local/com/theoplayer/android-connector/mediasession/maven-metadata-local.xml
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
<groupId>com.theoplayer.android-connector</groupId>
|
|
4
4
|
<artifactId>mediasession</artifactId>
|
|
5
5
|
<versioning>
|
|
6
|
-
<latest>
|
|
7
|
-
<release>
|
|
6
|
+
<latest>5.2.0-local</latest>
|
|
7
|
+
<release>5.2.0-local</release>
|
|
8
8
|
<versions>
|
|
9
|
-
<version>
|
|
9
|
+
<version>5.2.0-local</version>
|
|
10
10
|
</versions>
|
|
11
|
-
<lastUpdated>
|
|
11
|
+
<lastUpdated>20230531125422</lastUpdated>
|
|
12
12
|
</versioning>
|
|
13
13
|
</metadata>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
<!-- Allow background audio playback by registering this service. -->
|
|
31
31
|
<service
|
|
32
|
-
android:name="com.theoplayer.
|
|
32
|
+
android:name="com.theoplayer.media.MediaPlaybackService"
|
|
33
33
|
android:description="@string/background_playback_service_description"
|
|
34
34
|
android:exported="false"
|
|
35
35
|
android:enabled="false"
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
</intent-filter>
|
|
41
41
|
</service>
|
|
42
42
|
|
|
43
|
-
<receiver android:name="
|
|
43
|
+
<receiver android:name="com.theoplayer.media.CustomMediaButtonReceiver"
|
|
44
44
|
android:exported="false">
|
|
45
45
|
<intent-filter>
|
|
46
46
|
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
|
@@ -346,7 +346,7 @@ class PlayerEventEmitter internal constructor(
|
|
|
346
346
|
private fun onPause() {
|
|
347
347
|
val player = playerView.player
|
|
348
348
|
// Do not forward the pause event in case the content player is paused because the ad player starts.
|
|
349
|
-
if (player != null && !playerView.adsApi.isPlaying) {
|
|
349
|
+
if (player != null && (!playerView.adsApi.isPlaying || player.isPaused)) {
|
|
350
350
|
receiveEvent(EVENT_PAUSE, null)
|
|
351
351
|
}
|
|
352
352
|
}
|
|
@@ -26,11 +26,20 @@ import com.theoplayer.android.api.event.player.*
|
|
|
26
26
|
import com.theoplayer.android.api.player.Player
|
|
27
27
|
import com.theoplayer.android.connector.mediasession.MediaSessionConnector
|
|
28
28
|
import com.theoplayer.audio.BackgroundAudioConfig
|
|
29
|
-
import com.theoplayer.
|
|
29
|
+
import com.theoplayer.media.MediaPlaybackService
|
|
30
30
|
import java.util.concurrent.atomic.AtomicBoolean
|
|
31
31
|
|
|
32
32
|
private const val TAG = "ReactTHEOplayerContext"
|
|
33
33
|
|
|
34
|
+
private const val ALLOWED_PLAYBACK_ACTIONS = (
|
|
35
|
+
PlaybackStateCompat.ACTION_PLAY_PAUSE or
|
|
36
|
+
PlaybackStateCompat.ACTION_PLAY or
|
|
37
|
+
PlaybackStateCompat.ACTION_PAUSE or
|
|
38
|
+
PlaybackStateCompat.ACTION_SEEK_TO or
|
|
39
|
+
PlaybackStateCompat.ACTION_FAST_FORWARD or
|
|
40
|
+
PlaybackStateCompat.ACTION_REWIND or
|
|
41
|
+
PlaybackStateCompat.ACTION_SET_PLAYBACK_SPEED)
|
|
42
|
+
|
|
34
43
|
class ReactTHEOplayerContext private constructor(
|
|
35
44
|
private val reactContext: ThemedReactContext
|
|
36
45
|
) {
|
|
@@ -59,8 +68,6 @@ class ReactTHEOplayerContext private constructor(
|
|
|
59
68
|
get() = backgroundAudioConfig.enabled
|
|
60
69
|
|
|
61
70
|
companion object {
|
|
62
|
-
private var mediaControlledInstance: ReactTHEOplayerContext? = null
|
|
63
|
-
|
|
64
71
|
fun create(
|
|
65
72
|
reactContext: ThemedReactContext,
|
|
66
73
|
playerConfig: THEOplayerConfig
|
|
@@ -75,9 +82,6 @@ class ReactTHEOplayerContext private constructor(
|
|
|
75
82
|
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
|
76
83
|
binder = service as MediaPlaybackService.MediaPlaybackBinder
|
|
77
84
|
|
|
78
|
-
// Clean-up any existing media session connector
|
|
79
|
-
mediaSessionConnector?.destroy()
|
|
80
|
-
|
|
81
85
|
// Get media session connector from service
|
|
82
86
|
mediaSessionConnector = binder?.mediaSessionConnector
|
|
83
87
|
mediaSessionConnector?.player = player
|
|
@@ -128,12 +132,26 @@ class ReactTHEOplayerContext private constructor(
|
|
|
128
132
|
}
|
|
129
133
|
}
|
|
130
134
|
|
|
135
|
+
private fun applyAllowedMediaControls() {
|
|
136
|
+
// Reduce allowed set of remote control playback actions for ads & live streams.
|
|
137
|
+
val isLive = player.duration.isInfinite()
|
|
138
|
+
val isInAd = player.ads.isPlaying
|
|
139
|
+
mediaSessionConnector?.enabledPlaybackActions = if (isInAd || isLive) {
|
|
140
|
+
0
|
|
141
|
+
} else {
|
|
142
|
+
ALLOWED_PLAYBACK_ACTIONS
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
131
146
|
private fun bindMediaPlaybackService() {
|
|
132
147
|
// Bind to an existing service, if available
|
|
133
148
|
// A bound service runs only as long as another application component is bound to it.
|
|
134
149
|
// Multiple components can bind to the service at once, but when all of them unbind, the
|
|
135
150
|
// service is destroyed.
|
|
136
151
|
if (!isBound.get()) {
|
|
152
|
+
// Clean-up any existing media session connector
|
|
153
|
+
mediaSessionConnector?.destroy()
|
|
154
|
+
|
|
137
155
|
isBound.set(
|
|
138
156
|
reactContext.bindService(
|
|
139
157
|
Intent(reactContext, MediaPlaybackService::class.java),
|
|
@@ -179,11 +197,8 @@ class ReactTHEOplayerContext private constructor(
|
|
|
179
197
|
addIntegrations(playerConfig)
|
|
180
198
|
addListeners()
|
|
181
199
|
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
if (!BuildConfig.USE_PLAYBACK_SERVICE || !isBackgroundAudioEnabled) {
|
|
185
|
-
initDefaultMediaSession()
|
|
186
|
-
}
|
|
200
|
+
if (!BuildConfig.USE_PLAYBACK_SERVICE || !isBackgroundAudioEnabled) {
|
|
201
|
+
initDefaultMediaSession()
|
|
187
202
|
}
|
|
188
203
|
|
|
189
204
|
// Apply initial backgroundPlayback config
|
|
@@ -243,10 +258,12 @@ class ReactTHEOplayerContext private constructor(
|
|
|
243
258
|
private val onSourceChange = EventListener<SourceChangeEvent> {
|
|
244
259
|
mediaSessionConnector?.setMediaSessionMetadata(player.source)
|
|
245
260
|
binder?.updateNotification()
|
|
261
|
+
applyAllowedMediaControls()
|
|
246
262
|
}
|
|
247
263
|
|
|
248
264
|
private val onLoadedMetadata = EventListener<LoadedMetadataEvent> {
|
|
249
265
|
binder?.updateNotification()
|
|
266
|
+
applyAllowedMediaControls()
|
|
250
267
|
}
|
|
251
268
|
|
|
252
269
|
private val onPlay = EventListener<PlayEvent> {
|
|
@@ -254,10 +271,12 @@ class ReactTHEOplayerContext private constructor(
|
|
|
254
271
|
bindMediaPlaybackService()
|
|
255
272
|
}
|
|
256
273
|
binder?.updateNotification(PlaybackStateCompat.STATE_PLAYING)
|
|
274
|
+
applyAllowedMediaControls()
|
|
257
275
|
}
|
|
258
276
|
|
|
259
277
|
private val onPause = EventListener<PauseEvent> {
|
|
260
278
|
binder?.updateNotification(PlaybackStateCompat.STATE_PAUSED)
|
|
279
|
+
applyAllowedMediaControls()
|
|
261
280
|
}
|
|
262
281
|
|
|
263
282
|
private fun addListeners() {
|
|
@@ -310,17 +329,14 @@ class ReactTHEOplayerContext private constructor(
|
|
|
310
329
|
}
|
|
311
330
|
|
|
312
331
|
fun destroy() {
|
|
313
|
-
if (
|
|
314
|
-
|
|
315
|
-
removeListeners()
|
|
332
|
+
if (BuildConfig.USE_PLAYBACK_SERVICE) {
|
|
333
|
+
removeListeners()
|
|
316
334
|
|
|
317
|
-
|
|
318
|
-
|
|
335
|
+
// Remove service from foreground
|
|
336
|
+
binder?.stopForegroundService()
|
|
319
337
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
mediaControlledInstance = null
|
|
338
|
+
// Unbind client from background service so it can stop
|
|
339
|
+
unbindMediaPlaybackService()
|
|
324
340
|
}
|
|
325
341
|
mediaSessionConnector?.destroy()
|
|
326
342
|
playerView.onDestroy()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package com.theoplayer.media
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.content.Intent
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import androidx.media.session.MediaButtonReceiver
|
|
7
|
+
|
|
8
|
+
private const val TAG = "MediaButtonReceiver"
|
|
9
|
+
|
|
10
|
+
class CustomMediaButtonReceiver : MediaButtonReceiver() {
|
|
11
|
+
|
|
12
|
+
override fun onReceive(context: Context?, intent: Intent?) {
|
|
13
|
+
// MediaButtonReceiver will throw an IllegalStateException in case there are
|
|
14
|
+
// none, or more than one MediaBrowserServiceCompat instances registered.
|
|
15
|
+
// Handle and ignore the exception here.
|
|
16
|
+
try {
|
|
17
|
+
super.onReceive(context, intent)
|
|
18
|
+
} catch (e: IllegalStateException) {
|
|
19
|
+
Log.e(
|
|
20
|
+
TAG,
|
|
21
|
+
e.message ?: "Failed to handle media playback button action."
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package com.theoplayer.
|
|
1
|
+
package com.theoplayer.media
|
|
2
2
|
|
|
3
3
|
import android.app.NotificationManager
|
|
4
4
|
import android.app.PendingIntent
|
|
@@ -98,6 +98,9 @@ class MediaPlaybackService : MediaBrowserServiceCompat() {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
101
|
+
// This ensures that the correct callbacks to MediaSessionCompat.Callback will be triggered
|
|
102
|
+
// based on the incoming KeyEvent.
|
|
103
|
+
// https://developer.android.com/reference/androidx/media/session/MediaButtonReceiver
|
|
101
104
|
MediaButtonReceiver.handleIntent(mediaSession, intent)
|
|
102
105
|
return super.onStartCommand(intent, flags, startId)
|
|
103
106
|
}
|
|
@@ -155,17 +158,19 @@ class MediaPlaybackService : MediaBrowserServiceCompat() {
|
|
|
155
158
|
setMediaButtonReceiver(mediaButtonPendingIntent)
|
|
156
159
|
}
|
|
157
160
|
|
|
158
|
-
// Create a MediaSessionConnector
|
|
161
|
+
// Create a MediaSessionConnector.
|
|
159
162
|
mediaSessionConnector = MediaSessionConnector(mediaSession).apply {
|
|
160
163
|
debug = BuildConfig.LOG_MEDIASESSION_EVENTS
|
|
161
164
|
|
|
162
165
|
// Set mediaSession active
|
|
163
166
|
setActive(true)
|
|
164
167
|
}
|
|
168
|
+
|
|
169
|
+
// Set the MediaBrowserServiceCompat's media session.
|
|
170
|
+
sessionToken = mediaSession.sessionToken
|
|
165
171
|
}
|
|
166
172
|
|
|
167
173
|
private fun stopForegroundService() {
|
|
168
|
-
player?.pause()
|
|
169
174
|
updateNotification(PlaybackStateCompat.STATE_STOPPED)
|
|
170
175
|
stopSelf()
|
|
171
176
|
}
|
|
@@ -24,6 +24,7 @@ import com.theoplayer.android.api.source.metadata.ChromecastMetadataImage
|
|
|
24
24
|
import com.facebook.react.bridge.ReadableArray
|
|
25
25
|
import com.theoplayer.BuildConfig
|
|
26
26
|
import com.theoplayer.android.api.error.ErrorCode
|
|
27
|
+
import com.theoplayer.android.api.source.dash.DashPlaybackConfiguration
|
|
27
28
|
import com.theoplayer.drm.ContentProtectionAdapter
|
|
28
29
|
import org.json.JSONArray
|
|
29
30
|
import org.json.JSONException
|
|
@@ -51,6 +52,8 @@ private const val PROP_TEXT_TRACKS = "textTracks"
|
|
|
51
52
|
private const val PROP_POSTER = "poster"
|
|
52
53
|
private const val PROP_ADS = "ads"
|
|
53
54
|
private const val PROP_AVAILABILITY_TYPE = "availabilityType"
|
|
55
|
+
private const val PROP_DASH = "dash"
|
|
56
|
+
private const val PROP_DASH_IGNORE_AVAILABILITYWINDOW = "ignoreAvailabilityWindow"
|
|
54
57
|
private const val ERROR_DAI_NOT_ENABLED = "Google DAI support not enabled."
|
|
55
58
|
private const val ERROR_UNSUPPORTED_SSAI_INTEGRATION = "Unsupported SSAI integration"
|
|
56
59
|
private const val ERROR_MISSING_SSAI_INTEGRATION = "Missing SSAI integration"
|
|
@@ -186,6 +189,9 @@ class SourceAdapter {
|
|
|
186
189
|
if (sourceType != null) {
|
|
187
190
|
tsBuilder.type(sourceType)
|
|
188
191
|
}
|
|
192
|
+
if (jsonTypedSource.has(PROP_DASH)) {
|
|
193
|
+
tsBuilder.dash(parseDashConfig(jsonTypedSource.getJSONObject(PROP_DASH)))
|
|
194
|
+
}
|
|
189
195
|
if (jsonTypedSource.has(PROP_LIVE_OFFSET)) {
|
|
190
196
|
tsBuilder.liveOffset(jsonTypedSource.getDouble(PROP_LIVE_OFFSET))
|
|
191
197
|
}
|
|
@@ -358,6 +364,12 @@ class SourceAdapter {
|
|
|
358
364
|
return MetadataDescription(metadata)
|
|
359
365
|
}
|
|
360
366
|
|
|
367
|
+
private fun parseDashConfig(dashConfig: JSONObject): DashPlaybackConfiguration {
|
|
368
|
+
return DashPlaybackConfiguration.Builder()
|
|
369
|
+
.ignoreAvailabilityWindow(dashConfig.optBoolean(PROP_DASH_IGNORE_AVAILABILITYWINDOW))
|
|
370
|
+
.build()
|
|
371
|
+
}
|
|
372
|
+
|
|
361
373
|
@Throws(JSONException::class)
|
|
362
374
|
private fun parseMetadataImages(metadataImages: JSONArray): List<ChromecastMetadataImage> {
|
|
363
375
|
val imageList: MutableList<ChromecastMetadataImage> = ArrayList()
|
|
@@ -124,9 +124,11 @@ object TrackListAdapter {
|
|
|
124
124
|
audioTrackPayload.putString(PROP_LANGUAGE, audioTrack.language)
|
|
125
125
|
val qualityList = audioTrack.qualities
|
|
126
126
|
val qualities = Arguments.createArray()
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
try {
|
|
128
|
+
qualityList?.forEach { quality ->
|
|
129
|
+
qualities.pushMap(fromAudioQuality(quality))
|
|
130
|
+
}
|
|
131
|
+
} catch (ignore: NullPointerException) {}
|
|
130
132
|
audioTrackPayload.putArray(PROP_QUALITIES, qualities)
|
|
131
133
|
val activeQuality = audioTrack.activeQuality
|
|
132
134
|
if (activeQuality != null) {
|
|
@@ -163,18 +165,20 @@ object TrackListAdapter {
|
|
|
163
165
|
videoTrackPayload.putString(PROP_KIND, videoTrack.kind)
|
|
164
166
|
videoTrackPayload.putString(PROP_LABEL, videoTrack.label)
|
|
165
167
|
videoTrackPayload.putString(PROP_LANGUAGE, videoTrack.language)
|
|
166
|
-
val qualityList = videoTrack.qualities
|
|
167
168
|
val qualities = Arguments.createArray()
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
try {
|
|
170
|
+
val qualityList = videoTrack.qualities
|
|
171
|
+
if (qualityList != null) {
|
|
172
|
+
// Sort qualities according to (height, bandwidth)
|
|
173
|
+
val sortedQualityList = QualityListAdapter(qualityList)
|
|
174
|
+
sortedQualityList.sort { o: VideoQuality, t1: VideoQuality ->
|
|
175
|
+
if (o.height == t1.height) t1.bandwidth.compareTo(o.bandwidth) else t1.height.compareTo(o.height)
|
|
176
|
+
}
|
|
177
|
+
for (quality in sortedQualityList) {
|
|
178
|
+
qualities.pushMap(fromVideoQuality(quality as VideoQuality))
|
|
179
|
+
}
|
|
173
180
|
}
|
|
174
|
-
|
|
175
|
-
qualities.pushMap(fromVideoQuality(quality as VideoQuality))
|
|
176
|
-
}
|
|
177
|
-
}
|
|
181
|
+
} catch (ignore: java.lang.NullPointerException) {}
|
|
178
182
|
videoTrackPayload.putArray(PROP_QUALITIES, qualities)
|
|
179
183
|
val activeQuality = videoTrack.activeQuality
|
|
180
184
|
if (activeQuality != null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["DashPlaybackConfiguration.ts"],"sourcesContent":["/**\n * The strategy for period switches (see {@link DashPlaybackConfiguration.useSeamlessPeriodSwitch}), represented by a value from the following list:\n * <br/> - `'auto'`: The player uses seamless switches if the platform supports it, and hard switches otherwise.\n * This is the default.\n * <br/> - `'never'`: The player never uses a seamless switch, and always uses a hard switch.\n * Use this if you notice that the player is attempting but failing to preload the next period on the current platform.\n * <br/> - `'always'`: The player always uses a seamless switch, and never uses a hard switch.\n * Use this if you notice that the player never preloads the next period, even though you know that the current platform\n * should support it.\n *\n * @public\n */\nexport type SeamlessPeriodSwitchStrategy = 'auto' | 'always' | 'never';\n\n/**\n * Represents a configuration for controlling playback of an MPEG-DASH stream.\n *\n * @remarks\n * <br/> - Available since v2.79.0.\n *\n * @public\n */\nexport interface DashPlaybackConfiguration {\n /**\n * Whether to seamlessly switch between DASH periods.\n *\n * @remarks\n * The player supports two strategies for handling a switch between two periods in an MPEG-DASH stream:\n * <br/> - <strong>Seamless</strong>: Once the player is done buffering the current period, it immediately starts buffering the next period.\n * This requires that the current period and the next period have compatible codecs and content protection, or that the platform\n * supports buffering different codecs in a single player. Because the next period is preloaded ahead of time, this makes the actual\n * switch between periods (almost) completely seamless.\n * <br/> - <strong>Hard</strong>: The player waits until playback reaches the end of the current period before buffering and playing the next\n * period. Because the buffering is not done ahead of time, this may result in a noticeable stall at the start of the next period.\n * However, this strategy does not require any special platform support, so it works on any platform or device.\n *\n * By default, the player will automatically choose between a seamless or a hard period switch based on the codecs and content protection of\n * the two periods, and the support information reported by the platform. However, if you notice that the player makes an incorrect decision\n * on certain streams or platforms, you can use this option to override its behavior as a stopgap solution. (You should still report this\n * problem to THEOplayer support, so we can improve the player's default behavior and you can remove this override.)\n *\n * @defaultValue `'auto'`\n */\n useSeamlessPeriodSwitch?: SeamlessPeriodSwitchStrategy;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"names":[],"sources":["DashPlaybackConfiguration.ts"],"sourcesContent":["/**\n * The strategy for period switches (see {@link DashPlaybackConfiguration.useSeamlessPeriodSwitch}), represented by a value from the following list:\n * <br/> - `'auto'`: The player uses seamless switches if the platform supports it, and hard switches otherwise.\n * This is the default.\n * <br/> - `'never'`: The player never uses a seamless switch, and always uses a hard switch.\n * Use this if you notice that the player is attempting but failing to preload the next period on the current platform.\n * <br/> - `'always'`: The player always uses a seamless switch, and never uses a hard switch.\n * Use this if you notice that the player never preloads the next period, even though you know that the current platform\n * should support it.\n *\n * @public\n */\nexport type SeamlessPeriodSwitchStrategy = 'auto' | 'always' | 'never';\n\n/**\n * Represents a configuration for controlling playback of an MPEG-DASH stream.\n *\n * @remarks\n * <br/> - Available since v2.79.0.\n *\n * @public\n */\nexport interface DashPlaybackConfiguration {\n /**\n * Whether to seamlessly switch between DASH periods.\n *\n * @remarks\n * <br/> - Available on Web only.\n *\n * The player supports two strategies for handling a switch between two periods in an MPEG-DASH stream:\n * <br/> - <strong>Seamless</strong>: Once the player is done buffering the current period, it immediately starts buffering the next period.\n * This requires that the current period and the next period have compatible codecs and content protection, or that the platform\n * supports buffering different codecs in a single player. Because the next period is preloaded ahead of time, this makes the actual\n * switch between periods (almost) completely seamless.\n * <br/> - <strong>Hard</strong>: The player waits until playback reaches the end of the current period before buffering and playing the next\n * period. Because the buffering is not done ahead of time, this may result in a noticeable stall at the start of the next period.\n * However, this strategy does not require any special platform support, so it works on any platform or device.\n *\n * By default, the player will automatically choose between a seamless or a hard period switch based on the codecs and content protection of\n * the two periods, and the support information reported by the platform. However, if you notice that the player makes an incorrect decision\n * on certain streams or platforms, you can use this option to override its behavior as a stopgap solution. (You should still report this\n * problem to THEOplayer support, so we can improve the player's default behavior and you can remove this override.)\n *\n * @defaultValue `'auto'`\n */\n useSeamlessPeriodSwitch?: SeamlessPeriodSwitchStrategy;\n\n /**\n * (Experimental) Whether the timescales of the media data need to be shifted,\n * in order to work around platform-specific issues on certain smart TV platforms.\n *\n * @remarks\n * <br/> - Available since v4.1.0.\n * <br/> - Available on Web only.\n * <br/> - On certain smart TV platforms (such as Tizen 2), playback issues may arise when\n * the timescale of the media data changes across periods or discontinuities.\n * In that case, the player may need to shift all the timescales first,\n * however this strategy may not work for all streams.\n * <br/> - When not specified, the player will decide whether or not to shift timescales\n * based on the platform.\n * <br/> - This is an experimental option. It should only be used after consulting with\n * THEOplayer support or engineering.\n */\n needsTimescaleShifting?: boolean | null;\n\n /**\n * (Experimental) The desired timescale to which the media data should be shifted.\n *\n * @remarks\n * <br/> - Available since v4.11.0.\n * <br/> - Available on Web only.\n * <br/> - When specified, if the player decides to shift the timescale (see {@link DashPlaybackConfiguration.needsTimescaleShifting}), the timescale will be set to the\n * given desired timescale.\n * <br/> - When not specified, if the player decides to shift timescale, the player will decide the timescale to which it should shift.\n * <br/> - This is an experimental option. It should only be used after consulting with\n * THEOplayer support or engineering.\n */\n desiredTimescale?: number;\n\n /**\n * Whether the player should try to force the seek on period switching to realign video and audio.\n *\n * @internal\n *\n * @remarks\n * <br/> - Available on Web only.\n */\n forceSeekToSynchronize?: boolean;\n\n /**\n * (Experimental) Force the player to ignore the availability window of individual segments in the MPD,\n * and instead consider every listed segment to be immediately available.\n *\n * @remarks\n * <br/> - Available since v5.2.0.\n * <br/> - Available on Web and Android.\n * <br/> - This only applies to livestreams (with `<MPD type=\"dynamic\">`).\n * <br/> - This only applies to streams that use `<SegmentTimeline>`.\n */\n ignoreAvailabilityWindow?: boolean;\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TextTrackType","exports","TextTrackKind","TextTrackMode","filterRenderableTracks","textTracks","filter","textTrack","kind","filterThumbnailTracks","find","isThumbnailTrack","label","hasTextTrackCue","cue","cues","c","uid","removeTextTrackCue","addTextTrackCue","push","findTextTrackByUid","t"],"sources":["TextTrack.ts"],"sourcesContent":["import type { Track } from './Track';\nimport type { TextTrackCue } from './TextTrackCue';\n\nexport enum TextTrackType {\n cea608 = 'cea608',\n id3 = 'id3',\n srt = 'srt',\n ttml = 'ttml',\n webvtt = 'webvtt',\n}\n\nexport enum TextTrackKind {\n captions = 'captions',\n chapters = 'chapters',\n descriptions = 'descriptions',\n metadata = 'metadata',\n subtitles = 'subtitles',\n thumbnails = 'thumbnails',\n}\n\nexport enum TextTrackMode {\n disabled = 'disabled',\n showing = 'showing',\n hidden = 'hidden',\n}\n\nexport interface TextTrack extends Track {\n /**\n * The kind of the text track, represented by a value from the following list:\n * <br/> - `'subtitles'`: The track contains subtitles.\n * <br/> - `'captions'`: The track contains closed captions, a translation of dialogue and sound effects.\n * <br/> - `'descriptions'`: The track contains descriptions, a textual description of the video.\n * <br/> - `'chapters'`: The track contains chapter titles.\n * <br/> - `'metadata'`: The track contains metadata. This track will not serve display purposes.\n */\n readonly kind: TextTrackKind;\n\n /**\n * The label of the text track.\n */\n label: string;\n\n /**\n * The language of the text track.\n */\n readonly language: string;\n\n /**\n * The identifier of the text track.\n *\n * @remarks\n * <br/> - This identifier can be used to distinguish between related tracks, e.g. tracks in the same list.\n */\n readonly id: string;\n\n /**\n * A unique identifier of the text track.\n *\n * @remarks\n * <br/> - This identifier is unique across tracks of a THEOplayer instance and can be used to distinguish between tracks.\n */\n readonly uid: number;\n\n /**\n * The mode of the text track, represented by a value from the following list:\n * <br/> - `'disabled'`: The track is disabled.\n * <br/> - `'showing'`: The track is showing.\n */\n mode: TextTrackMode;\n\n /**\n * The content type of the text track.\n */\n readonly type: TextTrackType;\n\n /**\n * The list of cues of the track.\n *\n * @remarks\n * <br/> - If the {@link TextTrack.mode} is `'disabled'`, this property is `null`.\n */\n cues: TextTrackCue[] | null;\n\n /**\n * The source of the text track.\n */\n readonly src: string;\n\n /**\n * Indicates whether the track contains Forced Narrative cues.\n * This may only be true for subtitle tracks where\n * <br/> - For DASH: the corresponding AdaptationSet contains a child Role with its value attribute equal to `'forced_subtitle'`\n * <br/> - For HLS: the corresponding #EXT-X-MEDIA tag contains the attributes TYPE=SUBTITLES and FORCED=YES (not supported yet)\n */\n readonly forced: boolean;\n}\n\n/**\n * Retain renderable tracks.\n * https://html.spec.whatwg.org/multipage/embedded-content.html#text-track-showing\n */\nexport function filterRenderableTracks(textTracks: TextTrack[] | undefined): TextTrack[] | undefined {\n return textTracks && textTracks.filter((textTrack) => textTrack.kind === 'subtitles' || textTrack.kind === 'captions');\n}\n\n/**\n * Retain first thumbnail track encountered in the textTracks list.\n */\nexport function filterThumbnailTracks(textTracks: TextTrack[] | undefined): TextTrack | undefined {\n return textTracks && textTracks.find(isThumbnailTrack);\n}\n\n/**\n * Query whether a track is a valid thumbnail track.\n */\nexport function isThumbnailTrack(textTrack: TextTrack | undefined): boolean {\n return !!textTrack && (textTrack.kind === 'thumbnails' || (textTrack.kind === 'metadata' && textTrack.label === 'thumbnails'));\n}\n\nexport function hasTextTrackCue(textTrack: TextTrack, cue: TextTrackCue): boolean {\n return !!(textTrack.cues && cue && textTrack.cues.find((c) => cue.uid === c.uid));\n}\n\nexport function removeTextTrackCue(textTrack
|
|
1
|
+
{"version":3,"names":["TextTrackType","exports","TextTrackKind","TextTrackMode","filterRenderableTracks","textTracks","filter","textTrack","kind","filterThumbnailTracks","find","isThumbnailTrack","label","hasTextTrackCue","cue","cues","c","uid","removeTextTrackCue","addTextTrackCue","push","findTextTrackByUid","t"],"sources":["TextTrack.ts"],"sourcesContent":["import type { Track } from './Track';\nimport type { TextTrackCue } from './TextTrackCue';\n\nexport enum TextTrackType {\n cea608 = 'cea608',\n id3 = 'id3',\n srt = 'srt',\n ttml = 'ttml',\n webvtt = 'webvtt',\n}\n\nexport enum TextTrackKind {\n captions = 'captions',\n chapters = 'chapters',\n descriptions = 'descriptions',\n metadata = 'metadata',\n subtitles = 'subtitles',\n thumbnails = 'thumbnails',\n}\n\nexport enum TextTrackMode {\n disabled = 'disabled',\n showing = 'showing',\n hidden = 'hidden',\n}\n\nexport interface TextTrack extends Track {\n /**\n * The kind of the text track, represented by a value from the following list:\n * <br/> - `'subtitles'`: The track contains subtitles.\n * <br/> - `'captions'`: The track contains closed captions, a translation of dialogue and sound effects.\n * <br/> - `'descriptions'`: The track contains descriptions, a textual description of the video.\n * <br/> - `'chapters'`: The track contains chapter titles.\n * <br/> - `'metadata'`: The track contains metadata. This track will not serve display purposes.\n */\n readonly kind: TextTrackKind;\n\n /**\n * The label of the text track.\n */\n label: string;\n\n /**\n * The language of the text track.\n */\n readonly language: string;\n\n /**\n * The identifier of the text track.\n *\n * @remarks\n * <br/> - This identifier can be used to distinguish between related tracks, e.g. tracks in the same list.\n */\n readonly id: string;\n\n /**\n * A unique identifier of the text track.\n *\n * @remarks\n * <br/> - This identifier is unique across tracks of a THEOplayer instance and can be used to distinguish between tracks.\n */\n readonly uid: number;\n\n /**\n * The mode of the text track, represented by a value from the following list:\n * <br/> - `'disabled'`: The track is disabled.\n * <br/> - `'showing'`: The track is showing.\n */\n mode: TextTrackMode;\n\n /**\n * The content type of the text track.\n */\n readonly type: TextTrackType;\n\n /**\n * The list of cues of the track.\n *\n * @remarks\n * <br/> - If the {@link TextTrack.mode} is `'disabled'`, this property is `null`.\n */\n cues: TextTrackCue[] | null;\n\n /**\n * The source of the text track.\n */\n readonly src: string;\n\n /**\n * Indicates whether the track contains Forced Narrative cues.\n * This may only be true for subtitle tracks where\n * <br/> - For DASH: the corresponding AdaptationSet contains a child Role with its value attribute equal to `'forced_subtitle'`\n * <br/> - For HLS: the corresponding #EXT-X-MEDIA tag contains the attributes TYPE=SUBTITLES and FORCED=YES (not supported yet)\n */\n readonly forced: boolean;\n}\n\n/**\n * Retain renderable tracks.\n * https://html.spec.whatwg.org/multipage/embedded-content.html#text-track-showing\n */\nexport function filterRenderableTracks(textTracks: TextTrack[] | undefined): TextTrack[] | undefined {\n return textTracks && textTracks.filter((textTrack) => textTrack.kind === 'subtitles' || textTrack.kind === 'captions');\n}\n\n/**\n * Retain first thumbnail track encountered in the textTracks list.\n */\nexport function filterThumbnailTracks(textTracks: TextTrack[] | undefined): TextTrack | undefined {\n return textTracks && textTracks.find(isThumbnailTrack);\n}\n\n/**\n * Query whether a track is a valid thumbnail track.\n */\nexport function isThumbnailTrack(textTrack: TextTrack | undefined): boolean {\n return !!textTrack && (textTrack.kind === 'thumbnails' || (textTrack.kind === 'metadata' && textTrack.label === 'thumbnails'));\n}\n\nexport function hasTextTrackCue(textTrack: TextTrack, cue: TextTrackCue): boolean {\n return !!(textTrack.cues && cue && textTrack.cues.find((c) => cue.uid === c.uid));\n}\n\nexport function removeTextTrackCue(textTrack?: TextTrack, cue?: TextTrackCue) {\n if (textTrack && textTrack.cues && cue && !hasTextTrackCue(textTrack, cue)) {\n textTrack.cues = textTrack.cues.filter((c) => c.uid !== cue.uid);\n }\n}\n\nexport function addTextTrackCue(textTrack?: TextTrack, cue?: TextTrackCue) {\n if (textTrack && textTrack.cues && cue && !hasTextTrackCue(textTrack, cue)) {\n textTrack.cues.push(cue);\n }\n}\n\nexport function findTextTrackByUid(textTracks: TextTrack[], uid: number): TextTrack | undefined {\n return textTracks.find((t) => t.uid === uid);\n}\n"],"mappings":";;;;;;;;;;;;;IAGYA,aAAa;AAAAC,OAAA,CAAAD,aAAA,GAAAA,aAAA;AAAA,WAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;AAAA,GAAbA,aAAa,KAAAC,OAAA,CAAAD,aAAA,GAAbA,aAAa;AAAA,IAQbE,aAAa;AAAAD,OAAA,CAAAC,aAAA,GAAAA,aAAA;AAAA,WAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;AAAA,GAAbA,aAAa,KAAAD,OAAA,CAAAC,aAAA,GAAbA,aAAa;AAAA,IASbC,aAAa;AAAAF,OAAA,CAAAE,aAAA,GAAAA,aAAA;AAAA,WAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;AAAA,GAAbA,aAAa,KAAAF,OAAA,CAAAE,aAAA,GAAbA,aAAa;AA6EzB;AACA;AACA;AACA;AACO,SAASC,sBAAsBA,CAACC,UAAmC,EAA2B;EACnG,OAAOA,UAAU,IAAIA,UAAU,CAACC,MAAM,CAAEC,SAAS,IAAKA,SAAS,CAACC,IAAI,KAAK,WAAW,IAAID,SAAS,CAACC,IAAI,KAAK,UAAU,CAAC;AACxH;;AAEA;AACA;AACA;AACO,SAASC,qBAAqBA,CAACJ,UAAmC,EAAyB;EAChG,OAAOA,UAAU,IAAIA,UAAU,CAACK,IAAI,CAACC,gBAAgB,CAAC;AACxD;;AAEA;AACA;AACA;AACO,SAASA,gBAAgBA,CAACJ,SAAgC,EAAW;EAC1E,OAAO,CAAC,CAACA,SAAS,KAAKA,SAAS,CAACC,IAAI,KAAK,YAAY,IAAKD,SAAS,CAACC,IAAI,KAAK,UAAU,IAAID,SAAS,CAACK,KAAK,KAAK,YAAa,CAAC;AAChI;AAEO,SAASC,eAAeA,CAACN,SAAoB,EAAEO,GAAiB,EAAW;EAChF,OAAO,CAAC,EAAEP,SAAS,CAACQ,IAAI,IAAID,GAAG,IAAIP,SAAS,CAACQ,IAAI,CAACL,IAAI,CAAEM,CAAC,IAAKF,GAAG,CAACG,GAAG,KAAKD,CAAC,CAACC,GAAG,CAAC,CAAC;AACnF;AAEO,SAASC,kBAAkBA,CAACX,SAAqB,EAAEO,GAAkB,EAAE;EAC5E,IAAIP,SAAS,IAAIA,SAAS,CAACQ,IAAI,IAAID,GAAG,IAAI,CAACD,eAAe,CAACN,SAAS,EAAEO,GAAG,CAAC,EAAE;IAC1EP,SAAS,CAACQ,IAAI,GAAGR,SAAS,CAACQ,IAAI,CAACT,MAAM,CAAEU,CAAC,IAAKA,CAAC,CAACC,GAAG,KAAKH,GAAG,CAACG,GAAG,CAAC;EAClE;AACF;AAEO,SAASE,eAAeA,CAACZ,SAAqB,EAAEO,GAAkB,EAAE;EACzE,IAAIP,SAAS,IAAIA,SAAS,CAACQ,IAAI,IAAID,GAAG,IAAI,CAACD,eAAe,CAACN,SAAS,EAAEO,GAAG,CAAC,EAAE;IAC1EP,SAAS,CAACQ,IAAI,CAACK,IAAI,CAACN,GAAG,CAAC;EAC1B;AACF;AAEO,SAASO,kBAAkBA,CAAChB,UAAuB,EAAEY,GAAW,EAAyB;EAC9F,OAAOZ,UAAU,CAACK,IAAI,CAAEY,CAAC,IAAKA,CAAC,CAACL,GAAG,KAAKA,GAAG,CAAC;AAC9C"}
|
|
@@ -94,6 +94,22 @@ class THEOplayerAdapter extends _DefaultEventDispatcher.DefaultEventDispatcher {
|
|
|
94
94
|
this._state.seekable = (_event$seekable = event.seekable) === null || _event$seekable === void 0 ? void 0 : _event$seekable.sort((a, b) => a.end - b.end);
|
|
95
95
|
this._state.buffered = (_event$buffered = event.buffered) === null || _event$buffered === void 0 ? void 0 : _event$buffered.sort((a, b) => a.end - b.end);
|
|
96
96
|
});
|
|
97
|
+
_defineProperty(this, "onTextTrack", event => {
|
|
98
|
+
const {
|
|
99
|
+
subType,
|
|
100
|
+
cue,
|
|
101
|
+
trackUid
|
|
102
|
+
} = event;
|
|
103
|
+
const track = (0, _reactNativeTheoplayer.findTextTrackByUid)(this._state.textTracks, trackUid);
|
|
104
|
+
switch (subType) {
|
|
105
|
+
case _reactNativeTheoplayer.TextTrackEventType.ADD_CUE:
|
|
106
|
+
(0, _reactNativeTheoplayer.addTextTrackCue)(track, cue);
|
|
107
|
+
break;
|
|
108
|
+
case _reactNativeTheoplayer.TextTrackEventType.REMOVE_CUE:
|
|
109
|
+
(0, _reactNativeTheoplayer.removeTextTrackCue)(track, cue);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
97
113
|
_defineProperty(this, "onTextTrackList", event => {
|
|
98
114
|
const {
|
|
99
115
|
subType,
|
|
@@ -184,6 +200,7 @@ class THEOplayerAdapter extends _DefaultEventDispatcher.DefaultEventDispatcher {
|
|
|
184
200
|
this.addEventListener(_reactNativeTheoplayer.PlayerEventType.SEEKED, this.onSeeked);
|
|
185
201
|
this.addEventListener(_reactNativeTheoplayer.PlayerEventType.PROGRESS, this.onProgress);
|
|
186
202
|
this.addEventListener(_reactNativeTheoplayer.PlayerEventType.TEXT_TRACK_LIST, this.onTextTrackList);
|
|
203
|
+
this.addEventListener(_reactNativeTheoplayer.PlayerEventType.TEXT_TRACK, this.onTextTrack);
|
|
187
204
|
this.addEventListener(_reactNativeTheoplayer.PlayerEventType.MEDIA_TRACK, this.onMediaTrack);
|
|
188
205
|
this.addEventListener(_reactNativeTheoplayer.PlayerEventType.MEDIA_TRACK_LIST, this.onMediaTrackList);
|
|
189
206
|
this.addEventListener(_reactNativeTheoplayer.PlayerEventType.PRESENTATIONMODE_CHANGE, this.onPresentationModeChange);
|