react-native-theoplayer 3.0.2 → 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 +22 -0
- package/android/src/main/AndroidManifest.xml +1 -1
- 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/ReactTHEOplayerContext.kt +4 -29
- 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/THEOplayerRCTNetworkUtils.swift +3 -1
- package/ios/THEOplayerRCTTextTrackEventHandler.swift +21 -17
- package/ios/THEOplayerRCTTrackMetadataAggregator.swift +64 -8
- package/ios/THEOplayerRCTView.swift +4 -0
- package/ios/contentprotection/THEOplayerRCTContentProtectionAPI.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 +9 -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 +9 -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 +6 -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,28 @@ 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
|
+
|
|
18
|
+
## [3.1.0] - 23-10-27
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Revised audio focus protocol on Android. When resuming an app, audio focus is retrieved only if the player is not paused.
|
|
23
|
+
- Changed the behaviour of the Android component supporting background playback. It is stopped but not disabled when setting `backgroundAudioConfiguration.enabled = true`.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- Fixed an issue on Android where during play-out of a locally stored media asset the `seekable` property would not update.
|
|
28
|
+
- Fixed an issue on iOS where the error was not forwarded to theoplayer if a drm request fails on the iOS bridge
|
|
29
|
+
|
|
8
30
|
## [3.0.2] - 23-10-17
|
|
9
31
|
|
|
10
32
|
### Fixed
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
android:name="com.theoplayer.media.MediaPlaybackService"
|
|
33
33
|
android:description="@string/background_playback_service_description"
|
|
34
34
|
android:exported="false"
|
|
35
|
-
android:enabled="
|
|
35
|
+
android:enabled="true"
|
|
36
36
|
android:foregroundServiceType="mediaPlayback">
|
|
37
37
|
<intent-filter>
|
|
38
38
|
<action android:name="android.media.browse.MediaBrowserService" />
|
|
@@ -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
|
|
|
@@ -5,7 +5,6 @@ import android.content.ComponentName
|
|
|
5
5
|
import android.content.Context
|
|
6
6
|
import android.content.Intent
|
|
7
7
|
import android.content.ServiceConnection
|
|
8
|
-
import android.content.pm.PackageManager
|
|
9
8
|
import android.content.res.Configuration
|
|
10
9
|
import android.os.Handler
|
|
11
10
|
import android.os.IBinder
|
|
@@ -74,7 +73,7 @@ class ReactTHEOplayerContext private constructor(
|
|
|
74
73
|
var imaIntegration: GoogleImaIntegration? = null
|
|
75
74
|
var castIntegration: CastIntegration? = null
|
|
76
75
|
var wasPlayingOnHostPause: Boolean = false
|
|
77
|
-
var isHostPaused: Boolean = false
|
|
76
|
+
private var isHostPaused: Boolean = false
|
|
78
77
|
|
|
79
78
|
private val isBackgroundAudioEnabled: Boolean
|
|
80
79
|
get() = backgroundAudioConfig.enabled
|
|
@@ -113,27 +112,6 @@ class ReactTHEOplayerContext private constructor(
|
|
|
113
112
|
}
|
|
114
113
|
}
|
|
115
114
|
|
|
116
|
-
private fun setPlaybackServiceEnabled(enabled: Boolean) {
|
|
117
|
-
// Toggle the MediaPlaybackService.
|
|
118
|
-
toggleComponent(enabled, ComponentName(reactContext.applicationContext, MediaPlaybackService::class.java))
|
|
119
|
-
|
|
120
|
-
// Also toggle any registered MediaButtonReceiver broadcast receiver.
|
|
121
|
-
// It will crash the app if it remains active and tries to find our disabled MediaBrowserService instance.
|
|
122
|
-
toggleComponent(enabled, ComponentName(reactContext.applicationContext, androidx.media.session.MediaButtonReceiver::class.java))
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Enable or disable a receiver component.
|
|
127
|
-
*/
|
|
128
|
-
private fun toggleComponent(enabled: Boolean, componentName: ComponentName) {
|
|
129
|
-
reactContext.applicationContext.packageManager.setComponentEnabledSetting(
|
|
130
|
-
componentName,
|
|
131
|
-
if (enabled) PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
|
132
|
-
else PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
|
133
|
-
PackageManager.DONT_KILL_APP
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
115
|
private fun applyBackgroundPlaybackConfig(
|
|
138
116
|
config: BackgroundAudioConfig,
|
|
139
117
|
prevConfig: BackgroundAudioConfig?
|
|
@@ -148,13 +126,8 @@ class ReactTHEOplayerContext private constructor(
|
|
|
148
126
|
if (BuildConfig.USE_PLAYBACK_SERVICE) {
|
|
149
127
|
if (prevConfig?.enabled != true && config.enabled) {
|
|
150
128
|
// Enable & bind background playback
|
|
151
|
-
setPlaybackServiceEnabled(true)
|
|
152
129
|
bindMediaPlaybackService()
|
|
153
130
|
} else if (prevConfig?.enabled == true) {
|
|
154
|
-
// First disable the MediaPlaybackService and MediaButtonReceiver so that no more media
|
|
155
|
-
// button events can be captured.
|
|
156
|
-
setPlaybackServiceEnabled(false)
|
|
157
|
-
|
|
158
131
|
// Stop & unbind MediaPlaybackService.
|
|
159
132
|
binder?.stopForegroundService()
|
|
160
133
|
unbindMediaPlaybackService()
|
|
@@ -379,7 +352,9 @@ class ReactTHEOplayerContext private constructor(
|
|
|
379
352
|
isHostPaused = false
|
|
380
353
|
mediaSessionConnector?.setActive(true)
|
|
381
354
|
playerView.onResume()
|
|
382
|
-
|
|
355
|
+
if (!player.isPaused) {
|
|
356
|
+
audioFocusManager?.retrieveAudioFocus()
|
|
357
|
+
}
|
|
383
358
|
}
|
|
384
359
|
|
|
385
360
|
fun destroy() {
|
|
@@ -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) {
|
|
@@ -31,7 +31,6 @@ class THEOplayerRCTNetworkUtils: NSObject, URLSessionDataDelegate {
|
|
|
31
31
|
let task = self.defaultUrlSession.dataTask(with: request) { data, response, error in
|
|
32
32
|
if let error = error {
|
|
33
33
|
PrintUtils.printLog(logText: "request Error: \(error.localizedDescription)")
|
|
34
|
-
return
|
|
35
34
|
}
|
|
36
35
|
if let urlResponse = response as? HTTPURLResponse {
|
|
37
36
|
let statusCode = urlResponse.statusCode
|
|
@@ -44,7 +43,10 @@ class THEOplayerRCTNetworkUtils: NSObject, URLSessionDataDelegate {
|
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
45
|
completion?(data, statusCode, allHeaders, error)
|
|
46
|
+
} else {
|
|
47
|
+
completion?(data, -1, [:], error)
|
|
47
48
|
}
|
|
49
|
+
|
|
48
50
|
}
|
|
49
51
|
// start the task
|
|
50
52
|
task.resume()
|
|
@@ -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.") }
|
|
@@ -211,8 +211,10 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
211
211
|
THEOplayerRCTNetworkUtils.shared.requestFromUrl(url: url, method: method, body: bodyData, headers: headers) { data, statusCode, responseHeaders, error in
|
|
212
212
|
if let responseError = error {
|
|
213
213
|
print(CPI_TAG, "Certificate request failure: error = \(responseError.localizedDescription)")
|
|
214
|
+
completion(data, error)
|
|
214
215
|
} else if statusCode >= 400 {
|
|
215
216
|
PrintUtils.printLog(logText: "Certificate request failure: statusCode = \(statusCode)")
|
|
217
|
+
completion(data, nil)
|
|
216
218
|
} else {
|
|
217
219
|
if DEBUG_CONTENT_PROTECTION_API {print(CPI_TAG, "Certificate request success: statusCode = \(statusCode)") }
|
|
218
220
|
let certificateRequest = CertificateRequest(url: urlString, method: method, headers: headers, body: bodyData)
|
|
@@ -278,8 +280,10 @@ class THEOplayerRCTContentProtectionAPI: RCTEventEmitter {
|
|
|
278
280
|
THEOplayerRCTNetworkUtils.shared.requestFromUrl(url: url, method: method, body: bodyData, headers: headers) { data, statusCode, responseHeaders, error in
|
|
279
281
|
if let responseError = error {
|
|
280
282
|
print(CPI_TAG, "License request failure: error = \(responseError.localizedDescription)")
|
|
283
|
+
completion(data, error)
|
|
281
284
|
} else if statusCode >= 400 {
|
|
282
285
|
print(CPI_TAG, "License request failure: statusCode = \(statusCode)")
|
|
286
|
+
completion(data, nil)
|
|
283
287
|
} else {
|
|
284
288
|
if DEBUG_CONTENT_PROTECTION_API {print(CPI_TAG, "License request success: statusCode = \(statusCode)") }
|
|
285
289
|
let licenseRequest = LicenseRequest(url: urlString, method: method, headers: headers, body: bodyData, fairplaySkdUrl: nil, useCredentials: false)
|
|
@@ -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) {
|