react-native-theoplayer 3.1.0 → 3.2.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 +10 -0
- package/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +4 -0
- package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +5 -0
- package/android/src/main/java/com/theoplayer/player/PlayerModule.kt +8 -0
- package/android/src/main/java/com/theoplayer/track/TrackListAdapter.kt +47 -2
- package/ios/THEOplayerRCTTextTrackEventHandler.swift +21 -17
- package/ios/THEOplayerRCTTrackMetadataAggregator.swift +64 -8
- package/ios/THEOplayerRCTView.swift +4 -0
- package/lib/commonjs/api/config/PlayerConfiguration.js.map +1 -1
- package/lib/commonjs/api/track/DateRangeCue.js +19 -0
- package/lib/commonjs/api/track/DateRangeCue.js.map +1 -0
- package/lib/commonjs/api/track/TextTrack.js +2 -0
- package/lib/commonjs/api/track/TextTrack.js.map +1 -1
- package/lib/commonjs/api/track/barrel.js +11 -0
- package/lib/commonjs/api/track/barrel.js.map +1 -1
- package/lib/commonjs/internal/THEOplayerView.js +17 -2
- package/lib/commonjs/internal/THEOplayerView.js.map +1 -1
- package/lib/commonjs/internal/adapter/THEOplayerAdapter.js +3 -3
- package/lib/commonjs/internal/adapter/THEOplayerAdapter.js.map +1 -1
- package/lib/commonjs/internal/adapter/WebEventForwarder.js +3 -0
- package/lib/commonjs/internal/adapter/WebEventForwarder.js.map +1 -1
- package/lib/commonjs/internal/adapter/web/TrackUtils.js +17 -1
- package/lib/commonjs/internal/adapter/web/TrackUtils.js.map +1 -1
- package/lib/module/api/config/PlayerConfiguration.js.map +1 -1
- package/lib/module/api/track/DateRangeCue.js +13 -0
- package/lib/module/api/track/DateRangeCue.js.map +1 -0
- package/lib/module/api/track/TextTrack.js +2 -0
- package/lib/module/api/track/TextTrack.js.map +1 -1
- package/lib/module/api/track/barrel.js +1 -0
- package/lib/module/api/track/barrel.js.map +1 -1
- package/lib/module/internal/THEOplayerView.js +18 -2
- package/lib/module/internal/THEOplayerView.js.map +1 -1
- package/lib/module/internal/adapter/THEOplayerAdapter.js +3 -3
- package/lib/module/internal/adapter/THEOplayerAdapter.js.map +1 -1
- package/lib/module/internal/adapter/WebEventForwarder.js +4 -1
- package/lib/module/internal/adapter/WebEventForwarder.js.map +1 -1
- package/lib/module/internal/adapter/web/TrackUtils.js +16 -1
- package/lib/module/internal/adapter/web/TrackUtils.js.map +1 -1
- package/lib/typescript/api/config/PlayerConfiguration.d.ts +4 -0
- package/lib/typescript/api/track/DateRangeCue.d.ts +61 -0
- package/lib/typescript/api/track/TextTrack.d.ts +4 -1
- package/lib/typescript/api/track/barrel.d.ts +1 -0
- package/lib/typescript/internal/THEOplayerView.d.ts +2 -1
- package/lib/typescript/internal/adapter/web/TrackUtils.d.ts +2 -1
- package/package.json +1 -1
- package/src/api/config/PlayerConfiguration.ts +5 -0
- package/src/api/track/DateRangeCue.ts +74 -0
- package/src/api/track/TextTrack.ts +3 -0
- package/src/api/track/barrel.ts +1 -0
- package/src/internal/THEOplayerView.tsx +19 -3
- package/src/internal/adapter/THEOplayerAdapter.ts +3 -3
- package/src/internal/adapter/WebEventForwarder.ts +5 -0
- package/src/internal/adapter/web/TrackUtils.ts +18 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ 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.1.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.2.0] - 23-11-29
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Fixed an issue on iOS and Android were selecting an audio, video or text track that has a `uid` with value `0`, would fail.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Added support for HLS #EXT-X-DATERANGE timed metadata tags. The tags appear as cues in a dedicated text track with type `daterange`.
|
|
17
|
+
|
|
8
18
|
## [3.1.0] - 23-10-27
|
|
9
19
|
|
|
10
20
|
### Changed
|
|
@@ -18,6 +18,7 @@ private const val PROP_PRELOAD = "preload"
|
|
|
18
18
|
private const val PROP_UI_ENABLED = "uiEnabled"
|
|
19
19
|
private const val PROP_CAST_STRATEGY = "strategy"
|
|
20
20
|
private const val PROP_RETRY_CONFIG = "retryConfiguration"
|
|
21
|
+
private const val PROP_HLS_DATE_RANGE = "hlsDateRange"
|
|
21
22
|
private const val PROP_RETRY_MAX_RETRIES = "maxRetries"
|
|
22
23
|
private const val PROP_RETRY_MIN_BACKOFF = "minimumBackoff"
|
|
23
24
|
private const val PROP_RETRY_MAX_BACKOFF = "maximumBackoff"
|
|
@@ -44,6 +45,9 @@ class PlayerConfigAdapter(private val configProps: ReadableMap?) {
|
|
|
44
45
|
if (hasKey(PROP_RETRY_CONFIG)) {
|
|
45
46
|
networkConfiguration(networkConfig())
|
|
46
47
|
}
|
|
48
|
+
if (hasKey(PROP_HLS_DATE_RANGE)) {
|
|
49
|
+
hlsDateRange(getBoolean(PROP_HLS_DATE_RANGE))
|
|
50
|
+
}
|
|
47
51
|
pipConfiguration(PipConfiguration.Builder().build())
|
|
48
52
|
}
|
|
49
53
|
}.build()
|
|
@@ -38,6 +38,7 @@ import com.theoplayer.android.api.player.track.mediatrack.quality.AudioQuality
|
|
|
38
38
|
import com.theoplayer.android.api.player.track.mediatrack.quality.Quality
|
|
39
39
|
import com.theoplayer.android.api.player.track.mediatrack.quality.VideoQuality
|
|
40
40
|
import com.theoplayer.android.api.player.track.texttrack.TextTrack
|
|
41
|
+
import com.theoplayer.android.api.player.track.texttrack.TextTrackKind
|
|
41
42
|
import com.theoplayer.android.api.player.track.texttrack.TextTrackMode
|
|
42
43
|
import com.theoplayer.cast.CastEventAdapter
|
|
43
44
|
import com.theoplayer.presentation.PresentationModeChangeContext
|
|
@@ -474,6 +475,10 @@ class PlayerEventEmitter internal constructor(
|
|
|
474
475
|
}
|
|
475
476
|
|
|
476
477
|
private fun onTextTrackAdd(event: AddTrackEvent) {
|
|
478
|
+
// By default, set metadata tracks to mode 'hidden', until we add an API to set the mode.
|
|
479
|
+
if (event.track.kind == TextTrackKind.METADATA.type) {
|
|
480
|
+
event.track.mode = TextTrackMode.HIDDEN
|
|
481
|
+
}
|
|
477
482
|
dispatchTextTrackEvent(TrackEventType.ADD_TRACK, event.track)
|
|
478
483
|
}
|
|
479
484
|
|
|
@@ -98,6 +98,10 @@ class PlayerModule(context: ReactApplicationContext) : ReactContextBaseJavaModul
|
|
|
98
98
|
|
|
99
99
|
@ReactMethod
|
|
100
100
|
fun setSelectedAudioTrack(tag: Int, uid: Int) {
|
|
101
|
+
if (uid == -1) {
|
|
102
|
+
// Do not allow disabling all audio tracks
|
|
103
|
+
return
|
|
104
|
+
}
|
|
101
105
|
viewResolver.resolveViewByTag(tag) { view: ReactTHEOplayerView? ->
|
|
102
106
|
view?.player?.let {
|
|
103
107
|
for (track in it.audioTracks) {
|
|
@@ -109,6 +113,10 @@ class PlayerModule(context: ReactApplicationContext) : ReactContextBaseJavaModul
|
|
|
109
113
|
|
|
110
114
|
@ReactMethod
|
|
111
115
|
fun setSelectedVideoTrack(tag: Int, uid: Int) {
|
|
116
|
+
if (uid == -1) {
|
|
117
|
+
// Do not allow disabling all video tracks
|
|
118
|
+
return
|
|
119
|
+
}
|
|
112
120
|
viewResolver.resolveViewByTag(tag) { view: ReactTHEOplayerView? ->
|
|
113
121
|
view?.player?.let {
|
|
114
122
|
for (track in it.videoTracks) {
|
|
@@ -11,6 +11,7 @@ import com.theoplayer.android.api.player.track.mediatrack.quality.Quality
|
|
|
11
11
|
import com.theoplayer.android.api.player.track.mediatrack.quality.AudioQuality
|
|
12
12
|
import com.theoplayer.android.api.player.track.mediatrack.quality.VideoQuality
|
|
13
13
|
import com.theoplayer.android.api.player.track.mediatrack.MediaTrackList
|
|
14
|
+
import com.theoplayer.android.api.player.track.texttrack.cue.DateRangeCue
|
|
14
15
|
import com.theoplayer.util.TypeUtils
|
|
15
16
|
|
|
16
17
|
private const val PROP_ID = "id"
|
|
@@ -35,6 +36,16 @@ private const val PROP_STARTTIME = "startTime"
|
|
|
35
36
|
private const val PROP_ENDTIME = "endTime"
|
|
36
37
|
private const val PROP_CUES = "cues"
|
|
37
38
|
private const val PROP_CUE_CONTENT = "content"
|
|
39
|
+
private const val PROP_ATTRIBUTE_CLASS = "class"
|
|
40
|
+
private const val PROP_STARTDATE = "startDate"
|
|
41
|
+
private const val PROP_ENDDATE = "endDate"
|
|
42
|
+
private const val PROP_DURATION = "duration"
|
|
43
|
+
private const val PROP_PLANNED_DURATION = "plannedDuration"
|
|
44
|
+
private const val PROP_END_ON_NEXT = "endOnNext"
|
|
45
|
+
private const val PROP_SCTE35CMD = "scte35Cmd"
|
|
46
|
+
private const val PROP_SCTE35OUT = "scte35Out"
|
|
47
|
+
private const val PROP_SCTE35IN = "scte35In"
|
|
48
|
+
private const val PROP_CUSTOM_ATTRIBUTES = "customAttributes"
|
|
38
49
|
|
|
39
50
|
object TrackListAdapter {
|
|
40
51
|
|
|
@@ -85,6 +96,38 @@ object TrackListAdapter {
|
|
|
85
96
|
content.optString("content") ?: content.optString("contentString")
|
|
86
97
|
)
|
|
87
98
|
}
|
|
99
|
+
|
|
100
|
+
if (cue is DateRangeCue) {
|
|
101
|
+
cue.attributeClass?.run {
|
|
102
|
+
cuePayload.putString(PROP_ATTRIBUTE_CLASS, this)
|
|
103
|
+
}
|
|
104
|
+
cuePayload.putDouble(PROP_STARTDATE, cue.startDate.time.toDouble())
|
|
105
|
+
cue.endDate?.run {
|
|
106
|
+
cuePayload.putDouble(PROP_ENDDATE, this.time.toDouble())
|
|
107
|
+
}
|
|
108
|
+
cue.duration?.run {
|
|
109
|
+
cuePayload.putDouble(PROP_DURATION, TypeUtils.encodeInfNan(1e3 * this))
|
|
110
|
+
}
|
|
111
|
+
cue.plannedDuration?.run {
|
|
112
|
+
cuePayload.putDouble(PROP_PLANNED_DURATION, TypeUtils.encodeInfNan(1e3 * this))
|
|
113
|
+
}
|
|
114
|
+
cuePayload.putBoolean(PROP_END_ON_NEXT, cue.isEndOnNext)
|
|
115
|
+
cue.customAttributes?.asMap()?.run {
|
|
116
|
+
val attributes = Arguments.createMap()
|
|
117
|
+
forEach { (key, value) ->
|
|
118
|
+
when (value) {
|
|
119
|
+
is String -> attributes.putString(key, value)
|
|
120
|
+
is Boolean -> attributes.putBoolean(key, value)
|
|
121
|
+
is Int -> attributes.putInt(key, value)
|
|
122
|
+
is Double -> attributes.putDouble(key, value)
|
|
123
|
+
// TODO: support array & sub-objects
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
cuePayload.putMap(PROP_CUSTOM_ATTRIBUTES, attributes)
|
|
127
|
+
}
|
|
128
|
+
// TODO: Add SCTE marker properties
|
|
129
|
+
}
|
|
130
|
+
|
|
88
131
|
return cuePayload
|
|
89
132
|
}
|
|
90
133
|
|
|
@@ -128,7 +171,8 @@ object TrackListAdapter {
|
|
|
128
171
|
qualityList?.forEach { quality ->
|
|
129
172
|
qualities.pushMap(fromAudioQuality(quality))
|
|
130
173
|
}
|
|
131
|
-
} catch (ignore: NullPointerException) {
|
|
174
|
+
} catch (ignore: NullPointerException) {
|
|
175
|
+
}
|
|
132
176
|
audioTrackPayload.putArray(PROP_QUALITIES, qualities)
|
|
133
177
|
val activeQuality = audioTrack.activeQuality
|
|
134
178
|
if (activeQuality != null) {
|
|
@@ -178,7 +222,8 @@ object TrackListAdapter {
|
|
|
178
222
|
qualities.pushMap(fromVideoQuality(quality as VideoQuality))
|
|
179
223
|
}
|
|
180
224
|
}
|
|
181
|
-
} catch (ignore: java.lang.NullPointerException) {
|
|
225
|
+
} catch (ignore: java.lang.NullPointerException) {
|
|
226
|
+
}
|
|
182
227
|
videoTrackPayload.putArray(PROP_QUALITIES, qualities)
|
|
183
228
|
val activeQuality = videoTrack.activeQuality
|
|
184
229
|
if (activeQuality != null) {
|
|
@@ -53,14 +53,14 @@ class THEOplayerRCTTextTrackEventHandler {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// ADD_TRACK
|
|
56
|
-
self.addTrackListener = player.textTracks.addEventListener(type: TextTrackListEventTypes.ADD_TRACK) { [weak self] event in
|
|
57
|
-
guard let welf = self else { return }
|
|
56
|
+
self.addTrackListener = player.textTracks.addEventListener(type: TextTrackListEventTypes.ADD_TRACK) { [weak self, weak player] event in
|
|
57
|
+
guard let welf = self, let wplayer = player else { return }
|
|
58
58
|
if let forwardedTextTrackListEvent = welf.onNativeTextTrackListEvent,
|
|
59
59
|
let textTrack = event.track as? TextTrack {
|
|
60
60
|
if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received ADD_TRACK event from THEOplayer textTrack list: trackUid = \(textTrack.uid)") }
|
|
61
61
|
// trigger tracklist event
|
|
62
62
|
forwardedTextTrackListEvent([
|
|
63
|
-
"track" : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack),
|
|
63
|
+
"track" : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack, player: wplayer),
|
|
64
64
|
"type" : TrackListEventType.ADD_TRACK.rawValue
|
|
65
65
|
])
|
|
66
66
|
// start listening for cue events on this track and keep listener for later removal
|
|
@@ -77,14 +77,14 @@ class THEOplayerRCTTextTrackEventHandler {
|
|
|
77
77
|
if DEBUG_EVENTHANDLER { PrintUtils.printLog(logText: "[NATIVE] AddTrack listener attached to THEOplayer textTrack list") }
|
|
78
78
|
|
|
79
79
|
// REMOVE_TRACK
|
|
80
|
-
self.removeTrackListener = player.textTracks.addEventListener(type: TextTrackListEventTypes.REMOVE_TRACK) { [weak self] event in
|
|
81
|
-
guard let welf = self else { return }
|
|
80
|
+
self.removeTrackListener = player.textTracks.addEventListener(type: TextTrackListEventTypes.REMOVE_TRACK) { [weak self, weak player] event in
|
|
81
|
+
guard let welf = self, let wplayer = player else { return }
|
|
82
82
|
if let forwardedTextTrackListEvent = welf.onNativeTextTrackListEvent,
|
|
83
83
|
let textTrack = event.track as? TextTrack {
|
|
84
84
|
if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received REMOVE_TRACK event from THEOplayer textTrack list: trackUid = \(textTrack.uid)") }
|
|
85
85
|
// trigger tracklist event
|
|
86
86
|
forwardedTextTrackListEvent([
|
|
87
|
-
"track" : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack),
|
|
87
|
+
"track" : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack, player: wplayer),
|
|
88
88
|
"type" : TrackListEventType.REMOVE_TRACK.rawValue
|
|
89
89
|
])
|
|
90
90
|
// stop listening for cue events on this track
|
|
@@ -109,14 +109,14 @@ class THEOplayerRCTTextTrackEventHandler {
|
|
|
109
109
|
if DEBUG_EVENTHANDLER { PrintUtils.printLog(logText: "[NATIVE] RemoveTrack listener attached to THEOplayer textTrack list") }
|
|
110
110
|
|
|
111
111
|
// CHANGE
|
|
112
|
-
self.changeTrackListener = player.textTracks.addEventListener(type: TextTrackListEventTypes.CHANGE) { [weak self] event in
|
|
113
|
-
guard let welf = self else { return }
|
|
112
|
+
self.changeTrackListener = player.textTracks.addEventListener(type: TextTrackListEventTypes.CHANGE) { [weak self, weak player] event in
|
|
113
|
+
guard let welf = self, let wplayer = player else { return }
|
|
114
114
|
if let forwardedTextTrackListEvent = welf.onNativeTextTrackListEvent,
|
|
115
115
|
let textTrack = event.track as? TextTrack {
|
|
116
116
|
if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received CHANGE event from THEOplayer textTrack list: trackUid = \(textTrack.uid)") }
|
|
117
117
|
// trigger tracklist event
|
|
118
118
|
forwardedTextTrackListEvent([
|
|
119
|
-
"track" : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack),
|
|
119
|
+
"track" : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack, player: wplayer),
|
|
120
120
|
"type" : TrackListEventType.CHANGE_TRACK.rawValue
|
|
121
121
|
])
|
|
122
122
|
}
|
|
@@ -176,48 +176,52 @@ class THEOplayerRCTTextTrackEventHandler {
|
|
|
176
176
|
// MARK: - dynamic textTrack Listeners
|
|
177
177
|
private func addCueListener(_ event: AddCueEvent) {
|
|
178
178
|
if let forwardedTextTrackEvent = self.onNativeTextTrackEvent,
|
|
179
|
-
let textTrack = event.cue.track
|
|
179
|
+
let textTrack = event.cue.track,
|
|
180
|
+
let player = self.player {
|
|
180
181
|
if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received ADD_CUE event from textTrack: trackUid = \(textTrack.uid), cueUid = \(event.cue.uid)") }
|
|
181
182
|
forwardedTextTrackEvent([
|
|
182
183
|
"trackUid" : textTrack.uid,
|
|
183
184
|
"type": TrackCueEventType.ADD_CUE.rawValue,
|
|
184
|
-
"cue": THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: event.cue)
|
|
185
|
+
"cue": THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: event.cue, player: player)
|
|
185
186
|
])
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
189
|
|
|
189
190
|
private func removeCueListener(_ event: RemoveCueEvent) {
|
|
190
191
|
if let forwardedTextTrackEvent = self.onNativeTextTrackEvent,
|
|
191
|
-
let textTrack = event.cue.track
|
|
192
|
+
let textTrack = event.cue.track,
|
|
193
|
+
let player = self.player {
|
|
192
194
|
if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received REMOVE_CUE event from textTrack: trackUid = \(textTrack.uid), cueUid = \(event.cue.uid)") }
|
|
193
195
|
forwardedTextTrackEvent([
|
|
194
196
|
"trackUid" : textTrack.uid,
|
|
195
197
|
"type": TrackCueEventType.REMOVE_CUE.rawValue,
|
|
196
|
-
"cue": THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: event.cue)
|
|
198
|
+
"cue": THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: event.cue, player: player)
|
|
197
199
|
])
|
|
198
200
|
}
|
|
199
201
|
}
|
|
200
202
|
|
|
201
203
|
private func enterCueListener(_ event: EnterCueEvent) {
|
|
202
204
|
if let forwardedTextTrackEvent = self.onNativeTextTrackEvent,
|
|
203
|
-
let textTrack = event.cue.track
|
|
205
|
+
let textTrack = event.cue.track,
|
|
206
|
+
let player = self.player {
|
|
204
207
|
if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received ENTER_CUE event from textTrack: trackUid = \(textTrack.uid), cueUid = \(event.cue.uid)") }
|
|
205
208
|
forwardedTextTrackEvent([
|
|
206
209
|
"trackUid" : textTrack.uid,
|
|
207
210
|
"type": TrackCueEventType.ENTER_CUE.rawValue,
|
|
208
|
-
"cue": THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: event.cue)
|
|
211
|
+
"cue": THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: event.cue, player: player)
|
|
209
212
|
])
|
|
210
213
|
}
|
|
211
214
|
}
|
|
212
215
|
|
|
213
216
|
private func exitCueListener(_ event: ExitCueEvent) {
|
|
214
217
|
if let forwardedTextTrackEvent = self.onNativeTextTrackEvent,
|
|
215
|
-
let textTrack = event.cue.track
|
|
218
|
+
let textTrack = event.cue.track,
|
|
219
|
+
let player = self.player {
|
|
216
220
|
if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received EXIT_CUE event from textTrack: trackUid = \(textTrack.uid), cueUid = \(event.cue.uid)") }
|
|
217
221
|
forwardedTextTrackEvent([
|
|
218
222
|
"trackUid" : textTrack.uid,
|
|
219
223
|
"type": TrackCueEventType.EXIT_CUE.rawValue,
|
|
220
|
-
"cue": THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: event.cue)
|
|
224
|
+
"cue": THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: event.cue, player: player)
|
|
221
225
|
])
|
|
222
226
|
}
|
|
223
227
|
}
|
|
@@ -24,7 +24,14 @@ let PROP_STARTTIME: String = "startTime"
|
|
|
24
24
|
let PROP_ENDTIME: String = "endTime"
|
|
25
25
|
let PROP_CUES: String = "cues"
|
|
26
26
|
let PROP_CUE_CONTENT: String = "content"
|
|
27
|
+
let PROP_CUE_CUSTOM_ATTRIBUTES: String = "customAttributes"
|
|
27
28
|
let PROP_SRC: String = "src"
|
|
29
|
+
let PROP_START_DATE: String = "startDate"
|
|
30
|
+
let PROP_END_DATE: String = "endDate"
|
|
31
|
+
let PROP_ATTRIBUTE_CLASS: String = "class"
|
|
32
|
+
let PROP_DURATION: String = "duration"
|
|
33
|
+
let PROP_PLANNED_DURATION: String = "plannedDuration"
|
|
34
|
+
let PROP_END_ON_NEXT: String = "endOnNext"
|
|
28
35
|
|
|
29
36
|
class THEOplayerRCTTrackMetadataAggregator {
|
|
30
37
|
|
|
@@ -33,7 +40,7 @@ class THEOplayerRCTTrackMetadataAggregator {
|
|
|
33
40
|
let audioTracks: AudioTrackList = player.audioTracks
|
|
34
41
|
let videoTracks: VideoTrackList = player.videoTracks
|
|
35
42
|
return [
|
|
36
|
-
EVENT_PROP_TEXT_TRACKS : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackListInfo(textTracks: textTracks, metadataTracks: metadataTracksInfo),
|
|
43
|
+
EVENT_PROP_TEXT_TRACKS : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackListInfo(textTracks: textTracks, metadataTracks: metadataTracksInfo, player: player),
|
|
37
44
|
EVENT_PROP_AUDIO_TRACKS : THEOplayerRCTTrackMetadataAggregator.aggregatedAudioTrackListInfo(audioTracks: audioTracks),
|
|
38
45
|
EVENT_PROP_VIDEO_TRACKS : THEOplayerRCTTrackMetadataAggregator.aggregatedVideoTrackListInfo(videoTracks: videoTracks),
|
|
39
46
|
EVENT_PROP_SELECTED_TEXT_TRACK: THEOplayerRCTTrackMetadataAggregator.selectedTextTrack(textTracks: textTracks),
|
|
@@ -44,19 +51,19 @@ class THEOplayerRCTTrackMetadataAggregator {
|
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
// MARK: TEXTTRACKS
|
|
47
|
-
class func aggregatedTextTrackListInfo(textTracks: TextTrackList, metadataTracks: [[String:Any]]) -> [[String:Any]] {
|
|
54
|
+
class func aggregatedTextTrackListInfo(textTracks: TextTrackList, metadataTracks: [[String:Any]], player: THEOplayer) -> [[String:Any]] {
|
|
48
55
|
var trackEntries:[[String:Any]] = metadataTracks
|
|
49
56
|
guard textTracks.count > 0 else {
|
|
50
57
|
return trackEntries
|
|
51
58
|
}
|
|
52
59
|
for i in 0...textTracks.count-1 {
|
|
53
60
|
let textTrack: TextTrack = textTracks.get(i)
|
|
54
|
-
trackEntries.append(THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack))
|
|
61
|
+
trackEntries.append(THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack, player: player))
|
|
55
62
|
}
|
|
56
63
|
return trackEntries
|
|
57
64
|
}
|
|
58
65
|
|
|
59
|
-
class func aggregatedTextTrackInfo(textTrack: TextTrack) -> [String:Any] {
|
|
66
|
+
class func aggregatedTextTrackInfo(textTrack: TextTrack, player: THEOplayer) -> [String:Any] {
|
|
60
67
|
var entry: [String:Any] = [:]
|
|
61
68
|
entry[PROP_ID] = textTrack.id
|
|
62
69
|
entry[PROP_UID] = textTrack.uid
|
|
@@ -70,7 +77,7 @@ class THEOplayerRCTTrackMetadataAggregator {
|
|
|
70
77
|
if !textTrack.cues.isEmpty {
|
|
71
78
|
var cueList: [[String:Any]] = []
|
|
72
79
|
for cue in textTrack.cues {
|
|
73
|
-
cueList.append(THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: cue))
|
|
80
|
+
cueList.append(THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: cue, player: player))
|
|
74
81
|
}
|
|
75
82
|
entry[PROP_CUES] = cueList
|
|
76
83
|
}
|
|
@@ -91,17 +98,66 @@ class THEOplayerRCTTrackMetadataAggregator {
|
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
// MARK: TEXTTRACK CUES
|
|
94
|
-
class func aggregatedTextTrackCueInfo(textTrackCue: TextTrackCue) -> [String:Any] {
|
|
101
|
+
class func aggregatedTextTrackCueInfo(textTrackCue: TextTrackCue, player: THEOplayer) -> [String:Any] {
|
|
95
102
|
var entry: [String:Any] = [:]
|
|
96
103
|
entry[PROP_ID] = textTrackCue.id
|
|
97
104
|
entry[PROP_UID] = textTrackCue.uid
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
var startTime = textTrackCue.startTime
|
|
106
|
+
var endTime = textTrackCue.endTime
|
|
107
|
+
if let dateRangeCue = textTrackCue as? DateRangeCue,
|
|
108
|
+
let programDateTime = player.currentProgramDateTime?.timeIntervalSince1970 {
|
|
109
|
+
let currentTime = player.currentTime
|
|
110
|
+
let offset = programDateTime - currentTime
|
|
111
|
+
startTime = dateRangeCue.startDate.timeIntervalSince1970 - offset
|
|
112
|
+
endTime = dateRangeCue.endDate != nil ? dateRangeCue.endDate!.timeIntervalSince1970 - offset : .infinity
|
|
113
|
+
}
|
|
114
|
+
entry[PROP_STARTTIME] = THEOplayerRCTTypeUtils.encodeInfNan((startTime ?? 0) * 1000)
|
|
115
|
+
entry[PROP_ENDTIME] = THEOplayerRCTTypeUtils.encodeInfNan((endTime ?? 0) * 1000)
|
|
100
116
|
if let content = textTrackCue.content {
|
|
101
117
|
entry[PROP_CUE_CONTENT] = content
|
|
102
118
|
} else if let contentString = textTrackCue.contentString {
|
|
103
119
|
entry[PROP_CUE_CONTENT] = contentString
|
|
104
120
|
}
|
|
121
|
+
if let dateRangeCue = textTrackCue as? DateRangeCue {
|
|
122
|
+
entry[PROP_START_DATE] = dateRangeCue.startDate.timeIntervalSince1970 * 1000
|
|
123
|
+
if let endDate = dateRangeCue.endDate {
|
|
124
|
+
entry[PROP_END_DATE] = endDate.timeIntervalSince1970 * 1000
|
|
125
|
+
}
|
|
126
|
+
if let attributeClass = dateRangeCue.attributeClass {
|
|
127
|
+
entry[PROP_ATTRIBUTE_CLASS] = attributeClass
|
|
128
|
+
}
|
|
129
|
+
if let duration = dateRangeCue.duration {
|
|
130
|
+
entry[PROP_DURATION] = THEOplayerRCTTypeUtils.encodeInfNan(duration * 1000)
|
|
131
|
+
}
|
|
132
|
+
if let plannedDuration = dateRangeCue.plannedDuration {
|
|
133
|
+
entry[PROP_PLANNED_DURATION] = THEOplayerRCTTypeUtils.encodeInfNan(plannedDuration * 1000)
|
|
134
|
+
}
|
|
135
|
+
entry[PROP_END_ON_NEXT] = dateRangeCue.endOnNext
|
|
136
|
+
let customAttributes = dateRangeCue.customAttributes
|
|
137
|
+
let customAttributesDict = customAttributes.getAttributesAsDictionary()
|
|
138
|
+
if !customAttributesDict.isEmpty {
|
|
139
|
+
var attributesEntry: [String:Any] = [:]
|
|
140
|
+
for (key, _) in customAttributesDict {
|
|
141
|
+
do {
|
|
142
|
+
// try reading as string
|
|
143
|
+
attributesEntry[key] = try customAttributes.getString(for: key)
|
|
144
|
+
} catch {
|
|
145
|
+
do {
|
|
146
|
+
// try reading as double
|
|
147
|
+
attributesEntry[key] = try customAttributes.getDouble(for: key)
|
|
148
|
+
} catch {
|
|
149
|
+
do {
|
|
150
|
+
// try reading as data
|
|
151
|
+
attributesEntry[key] = try customAttributes.getBytes(for: key)
|
|
152
|
+
} catch {
|
|
153
|
+
print("Unable to extract customAttribute from DateRange cue. Content is limited to String, Double or Data.")
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
entry[PROP_CUE_CUSTOM_ATTRIBUTES] = attributesEntry
|
|
159
|
+
}
|
|
160
|
+
}
|
|
105
161
|
return entry
|
|
106
162
|
}
|
|
107
163
|
|
|
@@ -37,6 +37,7 @@ public class THEOplayerRCTView: UIView {
|
|
|
37
37
|
private var license: String?
|
|
38
38
|
private var licenseUrl: String?
|
|
39
39
|
private var chromeless: Bool = true
|
|
40
|
+
private var hlsDateRange: Bool = false
|
|
40
41
|
private var config: THEOplayerConfiguration?
|
|
41
42
|
|
|
42
43
|
// MARK: - Initialisation / view setup
|
|
@@ -108,6 +109,7 @@ public class THEOplayerRCTView: UIView {
|
|
|
108
109
|
pip: self.playerPipConfiguration(),
|
|
109
110
|
ads: self.playerAdsConfiguration(),
|
|
110
111
|
cast: self.playerCastConfiguration(),
|
|
112
|
+
hlsDateRange: self.hlsDateRange,
|
|
111
113
|
license: self.license,
|
|
112
114
|
licenseUrl: self.licenseUrl))
|
|
113
115
|
self.initAdsIntegration()
|
|
@@ -120,6 +122,7 @@ public class THEOplayerRCTView: UIView {
|
|
|
120
122
|
private func initPlayer() -> THEOplayer? {
|
|
121
123
|
self.player = THEOplayer(configuration: THEOplayerConfiguration(chromeless: self.chromeless,
|
|
122
124
|
ads: self.playerAdsConfiguration(),
|
|
125
|
+
hlsDateRange: self.hlsDateRange,
|
|
123
126
|
license: self.license,
|
|
124
127
|
licenseUrl: self.licenseUrl,
|
|
125
128
|
pip: self.playerPipConfiguration()))
|
|
@@ -168,6 +171,7 @@ public class THEOplayerRCTView: UIView {
|
|
|
168
171
|
self.license = configDict["license"] as? String
|
|
169
172
|
self.licenseUrl = configDict["licenseUrl"] as? String
|
|
170
173
|
self.chromeless = configDict["chromeless"] as? Bool ?? true
|
|
174
|
+
self.hlsDateRange = configDict["hlsDateRange"] as? Bool ?? false
|
|
171
175
|
self.parseAdsConfig(configDict: configDict)
|
|
172
176
|
self.parseCastConfig(configDict: configDict)
|
|
173
177
|
if DEBUG_VIEW { PrintUtils.printLog(logText: "[NATIVE] config prop updated.") }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["PlayerConfiguration.ts"],"sourcesContent":["import type { AdsConfiguration } from '../ads/AdsConfiguration';\nimport type { CastConfiguration } from '../cast/CastConfiguration';\nimport type { MediaControlConfiguration } from '../media/MediaControlConfiguration';\nimport type { RetryConfiguration } from '../utils/RetryConfiguration';\n\nexport interface PlayerConfiguration {\n /**\n * The directory in which the THEOplayer library worker files are located.\n * These worker files are THEOplayer.transmux.*\n *\n * @remarks\n * <br/> - This parameter is required when using a HLS source and has no default.\n *\n * @example\n * `'/lib/theoplayer/'`\n */\n libraryLocation?: string;\n\n /**\n * The muted autoplay policy for web.\n *\n * @remarks\n * <br/> - The muted autoplay policy is impacted by this property and {@link SourceConfiguration.mutedAutoplay}.\n *\n * @defaultValue `'none'`.\n */\n mutedAutoplay?: MutedAutoplayConfiguration;\n\n /**\n * The ads configuration for the player.\n */\n ads?: AdsConfiguration;\n\n /**\n * The cast configuration for the player.\n */\n cast?: CastConfiguration;\n\n /**\n * The configuration of media controls and media sessions across platforms.\n */\n mediaControl?: MediaControlConfiguration;\n\n /**\n * The license for the player\n */\n readonly license?: string;\n\n /**\n * The url to fetch the license for the player\n */\n readonly licenseUrl?: string;\n\n /**\n * Sets whether the native player is chromeless (without UI).\n *\n * @remarks\n * <br/> - This parameter only applies to Web platforms.\n */\n readonly chromeless?: boolean;\n\n /**\n * The retry configuration for the player.\n *\n * @remarks\n * <br/> - This parameter only applies to Web and Android platforms.\n */\n readonly retryConfiguration?: RetryConfiguration;\n}\n\n/**\n * The muted autoplay policy of a player for web.\n * <br/> - `'none'`: Disallow muted autoplay. If the player is requested to autoplay while unmuted, and the platform does not support unmuted autoplay, the player will not start playback.\n * <br/> - `'all'`: Allow muted autoplay. If the player is requested to autoplay while unmuted, and the platform supports muted autoplay, the player will start muted playback.\n * <br/> - `'content'`: Allow muted autoplay only for the main content. Disallow muted autoplay for e.g. advertisements. (Not yet supported.)\n *\n * @public\n */\nexport type MutedAutoplayConfiguration = 'none' | 'all' | 'content';\n"],"mappings":""}
|
|
1
|
+
{"version":3,"names":[],"sources":["PlayerConfiguration.ts"],"sourcesContent":["import type { AdsConfiguration } from '../ads/AdsConfiguration';\nimport type { CastConfiguration } from '../cast/CastConfiguration';\nimport type { MediaControlConfiguration } from '../media/MediaControlConfiguration';\nimport type { RetryConfiguration } from '../utils/RetryConfiguration';\n\nexport interface PlayerConfiguration {\n /**\n * The directory in which the THEOplayer library worker files are located.\n * These worker files are THEOplayer.transmux.*\n *\n * @remarks\n * <br/> - This parameter is required when using a HLS source and has no default.\n *\n * @example\n * `'/lib/theoplayer/'`\n */\n libraryLocation?: string;\n\n /**\n * The muted autoplay policy for web.\n *\n * @remarks\n * <br/> - The muted autoplay policy is impacted by this property and {@link SourceConfiguration.mutedAutoplay}.\n *\n * @defaultValue `'none'`.\n */\n mutedAutoplay?: MutedAutoplayConfiguration;\n\n /**\n * The ads configuration for the player.\n */\n ads?: AdsConfiguration;\n\n /**\n * The cast configuration for the player.\n */\n cast?: CastConfiguration;\n\n /**\n * The configuration of media controls and media sessions across platforms.\n */\n mediaControl?: MediaControlConfiguration;\n\n /**\n * The license for the player\n */\n readonly license?: string;\n\n /**\n * The url to fetch the license for the player\n */\n readonly licenseUrl?: string;\n\n /**\n * Sets whether the native player is chromeless (without UI).\n *\n * @remarks\n * <br/> - This parameter only applies to Web platforms.\n */\n readonly chromeless?: boolean;\n\n /**\n * Sets whether DateRange tags from the playlists should be imported as a textTrack.\n */\n readonly hlsDateRange?: boolean;\n\n /**\n * The retry configuration for the player.\n *\n * @remarks\n * <br/> - This parameter only applies to Web and Android platforms.\n */\n readonly retryConfiguration?: RetryConfiguration;\n}\n\n/**\n * The muted autoplay policy of a player for web.\n * <br/> - `'none'`: Disallow muted autoplay. If the player is requested to autoplay while unmuted, and the platform does not support unmuted autoplay, the player will not start playback.\n * <br/> - `'all'`: Allow muted autoplay. If the player is requested to autoplay while unmuted, and the platform supports muted autoplay, the player will start muted playback.\n * <br/> - `'content'`: Allow muted autoplay only for the main content. Disallow muted autoplay for e.g. advertisements. (Not yet supported.)\n *\n * @public\n */\nexport type MutedAutoplayConfiguration = 'none' | 'all' | 'content';\n"],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isDateRangeCue = isDateRangeCue;
|
|
7
|
+
/**
|
|
8
|
+
* Represents a cue of a HLS date range metadata text track.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Check whether a text track cue is of type DateRangeCue.
|
|
15
|
+
*/
|
|
16
|
+
function isDateRangeCue(cue) {
|
|
17
|
+
return cue.customAttributes != undefined;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=DateRangeCue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["isDateRangeCue","cue","customAttributes","undefined"],"sources":["DateRangeCue.ts"],"sourcesContent":["import type { TextTrackCue } from './TextTrackCue';\n\n/**\n * Represents a cue of a HLS date range metadata text track.\n *\n * @public\n */\nexport interface DateRangeCue extends TextTrackCue {\n /**\n * The class of the date range cue.\n *\n * @remarks\n * <br/> - The class is a client-defined string specifying a set of attributes with associated value semantics.\n */\n class: string | undefined;\n\n /**\n * The playback position at which the date range cue becomes active, as a Date.\n */\n startDate: Date;\n\n /**\n * The playback position at which the date range cue becomes inactive, as a Date.\n */\n endDate: Date | undefined;\n\n /**\n * The duration of the date range cue, in milliseconds.\n */\n duration: number | undefined;\n\n /**\n * The planned duration of the date range cue, in milliseconds.\n *\n * @remarks\n * <br/> - This is used when the exact duration is not known yet.\n */\n plannedDuration: number | undefined;\n\n /**\n * Whether end-on-next is enabled for the date range cue.\n *\n * @remarks\n * <br/> - End-on-next results in the {@link DateRangeCue.endDate} of the date range cue becoming equal to the {@link DateRangeCue.startDate} of the next date range cue with the same {@link DateRangeCue.\"class\"}, once it is known.\n */\n endOnNext: boolean;\n\n /**\n * The SCTE 'cmd' splice_info_section of the date range cue.\n */\n scte35Cmd: ArrayBuffer | undefined;\n\n /**\n * The SCTE 'out' splice_info_section of the date range cue.\n */\n scte35Out: ArrayBuffer | undefined;\n\n /**\n * The SCTE 'in' splice_info_section of the date range cue.\n */\n scte35In: ArrayBuffer | undefined;\n\n /**\n * Custom attributes extracted from the cue source.\n */\n customAttributes: Record<string, string | number | ArrayBuffer>;\n}\n\n/**\n * Check whether a text track cue is of type DateRangeCue.\n */\nexport function isDateRangeCue(cue: TextTrackCue): cue is DateRangeCue {\n return (cue as DateRangeCue).customAttributes != undefined;\n}\n"],"mappings":";;;;;;AAEA;AACA;AACA;AACA;AACA;;AA8DA;AACA;AACA;AACO,SAASA,cAAcA,CAACC,GAAiB,EAAuB;EACrE,OAAQA,GAAG,CAAkBC,gBAAgB,IAAIC,SAAS;AAC5D"}
|
|
@@ -17,6 +17,8 @@ let TextTrackType = exports.TextTrackType = /*#__PURE__*/function (TextTrackType
|
|
|
17
17
|
TextTrackType["srt"] = "srt";
|
|
18
18
|
TextTrackType["ttml"] = "ttml";
|
|
19
19
|
TextTrackType["webvtt"] = "webvtt";
|
|
20
|
+
TextTrackType["daterange"] = "daterange";
|
|
21
|
+
TextTrackType["eventstream"] = "eventstream";
|
|
20
22
|
return TextTrackType;
|
|
21
23
|
}({});
|
|
22
24
|
let TextTrackKind = exports.TextTrackKind = /*#__PURE__*/function (TextTrackKind) {
|
|
@@ -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 readonly 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,GAAAC,OAAA,CAAAD,aAAA,0BAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAA,OAAbA,aAAa;AAAA;AAAA,
|
|
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 daterange = 'daterange',\n eventstream = 'eventstream',\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 readonly 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 * <br/> - `'hidden'`: The track is enabled and loading cues, but not shown. (used for metadata tracks)\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,GAAAC,OAAA,CAAAD,aAAA,0BAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAA,OAAbA,aAAa;AAAA;AAAA,IAUbE,aAAa,GAAAD,OAAA,CAAAC,aAAA,0BAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAA,OAAbA,aAAa;AAAA;AAAA,IASbC,aAAa,GAAAF,OAAA,CAAAE,aAAA,0BAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAbA,aAAa;EAAA,OAAbA,aAAa;AAAA;AA8EzB;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,IAAID,eAAe,CAACN,SAAS,EAAEO,GAAG,CAAC,EAAE;IACzEP,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"}
|
|
@@ -69,4 +69,15 @@ Object.keys(_TextTrackStyle).forEach(function (key) {
|
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
|
+
var _DateRangeCue = require("./DateRangeCue");
|
|
73
|
+
Object.keys(_DateRangeCue).forEach(function (key) {
|
|
74
|
+
if (key === "default" || key === "__esModule") return;
|
|
75
|
+
if (key in exports && exports[key] === _DateRangeCue[key]) return;
|
|
76
|
+
Object.defineProperty(exports, key, {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function () {
|
|
79
|
+
return _DateRangeCue[key];
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
72
83
|
//# sourceMappingURL=barrel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_MediaTrack","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_Quality","_TextTrack","_TextTrackCue","_Track","_TextTrackStyle"],"sources":["barrel.ts"],"sourcesContent":["export * from './MediaTrack';\nexport * from './Quality';\nexport * from './TextTrack';\nexport * from './TextTrackCue';\nexport * from './Track';\nexport * from './TextTrackStyle';\n"],"mappings":";;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,WAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,WAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,WAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,QAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,QAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,QAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,QAAA,CAAAL,GAAA;IAAA;EAAA;AAAA;AACA,IAAAM,UAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,UAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,UAAA,CAAAN,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAE,UAAA,CAAAN,GAAA;IAAA;EAAA;AAAA;AACA,IAAAO,aAAA,GAAAX,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAS,aAAA,EAAAR,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAO,aAAA,CAAAP,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAG,aAAA,CAAAP,GAAA;IAAA;EAAA;AAAA;AACA,IAAAQ,MAAA,GAAAZ,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAU,MAAA,EAAAT,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAQ,MAAA,CAAAR,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAI,MAAA,CAAAR,GAAA;IAAA;EAAA;AAAA;AACA,IAAAS,eAAA,GAAAb,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAW,eAAA,EAAAV,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAS,eAAA,CAAAT,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAK,eAAA,CAAAT,GAAA;IAAA;EAAA;AAAA"}
|
|
1
|
+
{"version":3,"names":["_MediaTrack","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_Quality","_TextTrack","_TextTrackCue","_Track","_TextTrackStyle","_DateRangeCue"],"sources":["barrel.ts"],"sourcesContent":["export * from './MediaTrack';\nexport * from './Quality';\nexport * from './TextTrack';\nexport * from './TextTrackCue';\nexport * from './Track';\nexport * from './TextTrackStyle';\nexport * from './DateRangeCue';\n"],"mappings":";;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,WAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,WAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,WAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,QAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,QAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,QAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,QAAA,CAAAL,GAAA;IAAA;EAAA;AAAA;AACA,IAAAM,UAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,UAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,UAAA,CAAAN,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAE,UAAA,CAAAN,GAAA;IAAA;EAAA;AAAA;AACA,IAAAO,aAAA,GAAAX,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAS,aAAA,EAAAR,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAO,aAAA,CAAAP,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAG,aAAA,CAAAP,GAAA;IAAA;EAAA;AAAA;AACA,IAAAQ,MAAA,GAAAZ,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAU,MAAA,EAAAT,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAQ,MAAA,CAAAR,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAI,MAAA,CAAAR,GAAA;IAAA;EAAA;AAAA;AACA,IAAAS,eAAA,GAAAb,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAW,eAAA,EAAAV,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAS,eAAA,CAAAT,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAK,eAAA,CAAAT,GAAA;IAAA;EAAA;AAAA;AACA,IAAAU,aAAA,GAAAd,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAY,aAAA,EAAAX,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAU,aAAA,CAAAV,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAM,aAAA,CAAAV,GAAA;IAAA;EAAA;AAAA"}
|
|
@@ -112,8 +112,7 @@ class THEOplayerView extends _react.PureComponent {
|
|
|
112
112
|
const nativeEvent = event.nativeEvent;
|
|
113
113
|
const cue = nativeEvent.cue;
|
|
114
114
|
if (cue) {
|
|
115
|
-
|
|
116
|
-
cue.endTime = (0, _TypeUtils.decodeNanInf)(cue.endTime);
|
|
115
|
+
this.normalizeCue(cue);
|
|
117
116
|
}
|
|
118
117
|
this._facade.dispatchEvent(new _PlayerEvents.DefaultTextTrackEvent((0, _NativeTrackEvent.toTextTrackEventType)(nativeEvent.type), nativeEvent.trackUid, cue));
|
|
119
118
|
});
|
|
@@ -172,6 +171,22 @@ class THEOplayerView extends _react.PureComponent {
|
|
|
172
171
|
reset() {
|
|
173
172
|
this.setState(THEOplayerView.initialState);
|
|
174
173
|
}
|
|
174
|
+
normalizeCue(cue) {
|
|
175
|
+
cue.startTime = (0, _TypeUtils.decodeNanInf)(cue.startTime);
|
|
176
|
+
cue.endTime = (0, _TypeUtils.decodeNanInf)(cue.endTime);
|
|
177
|
+
if ((0, _reactNativeTheoplayer.isDateRangeCue)(cue)) {
|
|
178
|
+
cue.startDate = new Date(cue.startDate);
|
|
179
|
+
if (cue.endDate) {
|
|
180
|
+
cue.endDate = new Date(cue.endDate);
|
|
181
|
+
}
|
|
182
|
+
if (cue.duration) {
|
|
183
|
+
cue.duration = (0, _TypeUtils.decodeNanInf)(cue.duration);
|
|
184
|
+
}
|
|
185
|
+
if (cue.plannedDuration) {
|
|
186
|
+
cue.plannedDuration = (0, _TypeUtils.decodeNanInf)(cue.plannedDuration);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
175
190
|
render() {
|
|
176
191
|
const {
|
|
177
192
|
config,
|