bitmovin-player-react-native 0.3.0 → 0.3.1
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/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +85 -8
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableArray.kt +18 -0
- package/ios/RCTConvert+BitmovinPlayer.swift +77 -15
- package/lib/index.d.ts +158 -0
- package/package.json +1 -1
- package/src/player.ts +5 -0
- package/src/tweaksConfig.ts +153 -0
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
package com.bitmovin.player.reactnative.converter
|
|
2
2
|
|
|
3
|
+
import com.bitmovin.player.api.DeviceDescription.DeviceName
|
|
4
|
+
import com.bitmovin.player.api.DeviceDescription.ModelName
|
|
3
5
|
import com.bitmovin.player.api.PlaybackConfig
|
|
4
6
|
import com.bitmovin.player.api.PlayerConfig
|
|
7
|
+
import com.bitmovin.player.api.TweaksConfig
|
|
5
8
|
import com.bitmovin.player.api.drm.WidevineConfig
|
|
6
9
|
import com.bitmovin.player.api.event.PlayerEvent
|
|
7
10
|
import com.bitmovin.player.api.event.SourceEvent
|
|
@@ -11,6 +14,7 @@ import com.bitmovin.player.api.source.Source
|
|
|
11
14
|
import com.bitmovin.player.api.source.SourceConfig
|
|
12
15
|
import com.bitmovin.player.api.source.SourceType
|
|
13
16
|
import com.bitmovin.player.reactnative.extensions.getName
|
|
17
|
+
import com.bitmovin.player.reactnative.extensions.toList
|
|
14
18
|
import com.facebook.react.bridge.*
|
|
15
19
|
import java.util.UUID
|
|
16
20
|
|
|
@@ -33,20 +37,93 @@ class JsonConverter {
|
|
|
33
37
|
PlayerConfig()
|
|
34
38
|
}
|
|
35
39
|
if (json.hasKey("playbackConfig")) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
playerConfig.playbackConfig.isAutoplayEnabled = playbackConfigJson.getBoolean("isAutoplayEnabled")
|
|
40
|
+
toPlaybackConfig(json.getMap("playbackConfig"))?.let {
|
|
41
|
+
playerConfig.playbackConfig = it
|
|
39
42
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
playerConfig.playbackConfig.isTimeShiftEnabled = playbackConfigJson.getBoolean("isTimeShiftEnabled")
|
|
43
|
+
}
|
|
44
|
+
if (json.hasKey("tweaksConfig")) {
|
|
45
|
+
toTweaksConfig(json.getMap("tweaksConfig"))?.let {
|
|
46
|
+
playerConfig.tweaksConfig = it
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
return playerConfig
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Converts any JS object into a `PlaybackConfig` object.
|
|
54
|
+
* @param json JS object representing the `PlaybackConfig`.
|
|
55
|
+
* @return The generated `PlaybackConfig` if successful, `null` otherwise.
|
|
56
|
+
*/
|
|
57
|
+
@JvmStatic
|
|
58
|
+
fun toPlaybackConfig(json: ReadableMap?): PlaybackConfig? {
|
|
59
|
+
if (json == null) {
|
|
60
|
+
return null
|
|
61
|
+
}
|
|
62
|
+
val playbackConfig = PlaybackConfig()
|
|
63
|
+
if (json.hasKey("isAutoplayEnabled")) {
|
|
64
|
+
playbackConfig.isAutoplayEnabled = json.getBoolean("isAutoplayEnabled")
|
|
65
|
+
}
|
|
66
|
+
if (json.hasKey("isMuted")) {
|
|
67
|
+
playbackConfig.isMuted = json.getBoolean("isMuted")
|
|
68
|
+
}
|
|
69
|
+
if (json.hasKey("isTimeShiftEnabled")) {
|
|
70
|
+
playbackConfig.isTimeShiftEnabled = json.getBoolean("isTimeShiftEnabled")
|
|
71
|
+
}
|
|
72
|
+
return playbackConfig
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Converts any JS object into a `TweaksConfig` object.
|
|
77
|
+
* @param json JS object representing the `TweaksConfig`.
|
|
78
|
+
* @return The generated `TweaksConfig` if successful, `null` otherwise.
|
|
79
|
+
*/
|
|
80
|
+
@JvmStatic
|
|
81
|
+
fun toTweaksConfig(json: ReadableMap?): TweaksConfig? {
|
|
82
|
+
if (json == null) {
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
val tweaksConfig = TweaksConfig()
|
|
86
|
+
if (json.hasKey("timeChangedInterval")) {
|
|
87
|
+
tweaksConfig.timeChangedInterval = json.getDouble("timeChangedInterval")
|
|
88
|
+
}
|
|
89
|
+
if (json.hasKey("bandwidthEstimateWeightLimit")) {
|
|
90
|
+
tweaksConfig.bandwidthEstimateWeightLimit = json.getInt("bandwidthEstimateWeightLimit")
|
|
91
|
+
}
|
|
92
|
+
if (json.hasKey("devicesThatRequireSurfaceWorkaround")) {
|
|
93
|
+
val devices = json.getMap("devicesThatRequireSurfaceWorkaround")
|
|
94
|
+
val deviceNames = devices?.getArray("deviceNames")
|
|
95
|
+
?.toList<String>()
|
|
96
|
+
?.mapNotNull { it }
|
|
97
|
+
?.map { DeviceName(it) }
|
|
98
|
+
?: emptyList()
|
|
99
|
+
val modelNames = devices?.getArray("modelNames")
|
|
100
|
+
?.toList<String>()
|
|
101
|
+
?.mapNotNull { it }
|
|
102
|
+
?.map { ModelName(it) }
|
|
103
|
+
?: emptyList()
|
|
104
|
+
tweaksConfig.devicesThatRequireSurfaceWorkaround = deviceNames + modelNames
|
|
105
|
+
}
|
|
106
|
+
if (json.hasKey("languagePropertyNormalization")) {
|
|
107
|
+
tweaksConfig.languagePropertyNormalization = json.getBoolean("languagePropertyNormalization")
|
|
108
|
+
}
|
|
109
|
+
if (json.hasKey("localDynamicDashWindowUpdateInterval")) {
|
|
110
|
+
tweaksConfig.localDynamicDashWindowUpdateInterval = json.getDouble("localDynamicDashWindowUpdateInterval")
|
|
111
|
+
}
|
|
112
|
+
if (json.hasKey("shouldApplyTtmlRegionWorkaround")) {
|
|
113
|
+
tweaksConfig.shouldApplyTtmlRegionWorkaround = json.getBoolean("shouldApplyTtmlRegionWorkaround")
|
|
114
|
+
}
|
|
115
|
+
if (json.hasKey("useDrmSessionForClearPeriods")) {
|
|
116
|
+
tweaksConfig.useDrmSessionForClearPeriods = json.getBoolean("useDrmSessionForClearPeriods")
|
|
117
|
+
}
|
|
118
|
+
if (json.hasKey("useDrmSessionForClearSources")) {
|
|
119
|
+
tweaksConfig.useDrmSessionForClearSources = json.getBoolean("useDrmSessionForClearSources")
|
|
120
|
+
}
|
|
121
|
+
if (json.hasKey("useFiletypeExtractorFallbackForHls")) {
|
|
122
|
+
tweaksConfig.useFiletypeExtractorFallbackForHls = json.getBoolean("useFiletypeExtractorFallbackForHls")
|
|
123
|
+
}
|
|
124
|
+
return tweaksConfig
|
|
125
|
+
}
|
|
126
|
+
|
|
50
127
|
/**
|
|
51
128
|
* Converts an arbitrary `json` to `SourceConfig`.
|
|
52
129
|
* @param json JS object representing the `SourceConfig`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package com.bitmovin.player.reactnative.extensions
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableArray
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
|
|
6
|
+
inline fun <reified T> ReadableArray.toList(): List<T?> = (0 until size()).map { i ->
|
|
7
|
+
getDynamic(i).let {
|
|
8
|
+
when (T::class) {
|
|
9
|
+
Boolean::class -> it.asBoolean() as T
|
|
10
|
+
String::class -> it.asString() as T
|
|
11
|
+
Double::class -> it.asDouble() as T
|
|
12
|
+
Int::class -> it.asInt() as T
|
|
13
|
+
ReadableArray::class -> it.asArray() as T
|
|
14
|
+
ReadableMap::class -> it.asMap() as T
|
|
15
|
+
else -> null
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -15,24 +15,86 @@ extension RCTConvert {
|
|
|
15
15
|
if let licenseKey = json["licenseKey"] as? String {
|
|
16
16
|
playerConfig.key = licenseKey
|
|
17
17
|
}
|
|
18
|
-
if let playbackConfig = json["playbackConfig"]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
if let playbackConfig = RCTConvert.playbackConfig(json["playbackConfig"]) {
|
|
19
|
+
playerConfig.playbackConfig = playbackConfig
|
|
20
|
+
}
|
|
21
|
+
if let tweaksConfig = RCTConvert.tweaksConfig(json["tweaksConfig"]) {
|
|
22
|
+
playerConfig.tweaksConfig = tweaksConfig
|
|
23
|
+
}
|
|
24
|
+
return playerConfig
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
Utility method to instantiate a `PlaybackConfig` from a JS object.
|
|
29
|
+
- Parameter json: JS object.
|
|
30
|
+
- Returns: The produced `PlaybackConfig` object.
|
|
31
|
+
*/
|
|
32
|
+
static func playbackConfig(_ json: Any?) -> PlaybackConfig? {
|
|
33
|
+
guard let json = json as? [String: Any?] else {
|
|
34
|
+
return nil
|
|
35
|
+
}
|
|
36
|
+
let playbackConfig = PlaybackConfig()
|
|
37
|
+
if let isAutoplayEnabled = json["isAutoplayEnabled"] as? Bool {
|
|
38
|
+
playbackConfig.isAutoplayEnabled = isAutoplayEnabled
|
|
39
|
+
}
|
|
40
|
+
if let isMuted = json["isMuted"] as? Bool {
|
|
41
|
+
playbackConfig.isMuted = isMuted
|
|
42
|
+
}
|
|
43
|
+
if let isTimeShiftEnabled = json["isTimeShiftEnabled"] as? Bool {
|
|
44
|
+
playbackConfig.isTimeShiftEnabled = isTimeShiftEnabled
|
|
45
|
+
}
|
|
46
|
+
if let isBackgroundPlaybackEnabled = json["isBackgroundPlaybackEnabled"] as? Bool {
|
|
47
|
+
playbackConfig.isBackgroundPlaybackEnabled = isBackgroundPlaybackEnabled
|
|
48
|
+
}
|
|
49
|
+
if let isPictureInPictureEnabled = json["isPictureInPictureEnabled"] as? Bool {
|
|
50
|
+
playbackConfig.isPictureInPictureEnabled = isPictureInPictureEnabled
|
|
51
|
+
}
|
|
52
|
+
return playbackConfig
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
Utility method to instantiate a `TweaksConfig` from a JS object.
|
|
57
|
+
- Parameter json: JS object.
|
|
58
|
+
- Returns: The produced `TweaksConfig` object.
|
|
59
|
+
*/
|
|
60
|
+
static func tweaksConfig(_ json: Any?) -> TweaksConfig? {
|
|
61
|
+
guard let json = json as? [String: Any?] else {
|
|
62
|
+
return nil
|
|
63
|
+
}
|
|
64
|
+
let tweaksConfig = TweaksConfig()
|
|
65
|
+
if let isNativeHlsParsingEnabled = json["isNativeHlsParsingEnabled"] as? Bool {
|
|
66
|
+
tweaksConfig.isNativeHlsParsingEnabled = isNativeHlsParsingEnabled
|
|
67
|
+
}
|
|
68
|
+
if let isCustomHlsLoadingEnabled = json["isCustomHlsLoadingEnabled"] as? Bool {
|
|
69
|
+
tweaksConfig.isCustomHlsLoadingEnabled = isCustomHlsLoadingEnabled
|
|
70
|
+
}
|
|
71
|
+
if let timeChangedInterval = json["timeChangedInterval"] as? NSNumber {
|
|
72
|
+
tweaksConfig.timeChangedInterval = timeChangedInterval.doubleValue
|
|
73
|
+
}
|
|
74
|
+
if let seekToEndThreshold = json["seekToEndThreshold"] as? NSNumber {
|
|
75
|
+
tweaksConfig.seekToEndThreshold = seekToEndThreshold.doubleValue
|
|
76
|
+
}
|
|
77
|
+
if let playbackStartBehaviour = json["playbackStartBehaviour"] as? String {
|
|
78
|
+
switch playbackStartBehaviour {
|
|
79
|
+
case "relaxed":
|
|
80
|
+
tweaksConfig.playbackStartBehaviour = .relaxed
|
|
81
|
+
case "aggressive":
|
|
82
|
+
tweaksConfig.playbackStartBehaviour = .aggressive
|
|
83
|
+
default:
|
|
84
|
+
break
|
|
30
85
|
}
|
|
31
|
-
|
|
32
|
-
|
|
86
|
+
}
|
|
87
|
+
if let unstallingBehaviour = json["unstallingBehaviour"] as? String {
|
|
88
|
+
switch unstallingBehaviour {
|
|
89
|
+
case "relaxed":
|
|
90
|
+
tweaksConfig.unstallingBehaviour = .relaxed
|
|
91
|
+
case "aggressive":
|
|
92
|
+
tweaksConfig.unstallingBehaviour = .aggressive
|
|
93
|
+
default:
|
|
94
|
+
break
|
|
33
95
|
}
|
|
34
96
|
}
|
|
35
|
-
return
|
|
97
|
+
return tweaksConfig
|
|
36
98
|
}
|
|
37
99
|
|
|
38
100
|
/**
|
package/lib/index.d.ts
CHANGED
|
@@ -740,6 +740,160 @@ declare class Source extends NativeInstance<SourceConfig> {
|
|
|
740
740
|
loadingState: () => Promise<LoadingState>;
|
|
741
741
|
}
|
|
742
742
|
|
|
743
|
+
/**
|
|
744
|
+
* This configuration is used as an incubator for experimental features. Tweaks are not officially
|
|
745
|
+
* supported and are not guaranteed to be stable, i.e. their naming, functionality and API can
|
|
746
|
+
* change at any time within the tweaks or when being promoted to an official feature and moved
|
|
747
|
+
* into its final configuration namespace.
|
|
748
|
+
*/
|
|
749
|
+
interface TweaksConfig {
|
|
750
|
+
/**
|
|
751
|
+
* The frequency in seconds onTimeChanged is called with TimeChangedEvents.
|
|
752
|
+
*
|
|
753
|
+
* Default value in iOS is `1.0`.
|
|
754
|
+
* Default value in Android is `0.2`.
|
|
755
|
+
*
|
|
756
|
+
* @platform iOS, Android
|
|
757
|
+
*/
|
|
758
|
+
timeChangedInterval?: number;
|
|
759
|
+
/**
|
|
760
|
+
* If enabled, HLS playlists will be parsed and additional features and events are enabled. This includes:
|
|
761
|
+
*
|
|
762
|
+
* - MetadataEvents carrying segment-specific metadata for custom HLS tags, like #EXT-X-SCTE35
|
|
763
|
+
* - MetadataParsedEvents carrying segment-specific metadata for custom HLS tags, like #EXT-X-SCTE35
|
|
764
|
+
* - DrmDataParsedEvents when a #EXT-X-KEY is found
|
|
765
|
+
* - Player.availableVideoQualities includes additional information
|
|
766
|
+
* - Automatic retries when HLS playlist requests failed with non-2xx HTTP status code
|
|
767
|
+
*
|
|
768
|
+
* Default is false.
|
|
769
|
+
*
|
|
770
|
+
* @platform iOS
|
|
771
|
+
*/
|
|
772
|
+
isNativeHlsParsingEnabled?: boolean;
|
|
773
|
+
/**
|
|
774
|
+
* If enabled, playlists will be downloaded by the Bitmovin Player SDK instead of AVFoundation.
|
|
775
|
+
* This enables additional features and events, like:
|
|
776
|
+
*
|
|
777
|
+
* - DownloadFinishedEvents for playlist downloads.
|
|
778
|
+
* - SourceWarningEvents when no #EXT-X-PLAYLIST-TYPE is found If set to false, enabling
|
|
779
|
+
* nativeHlsParsingEnabled won’t have any effect.
|
|
780
|
+
*
|
|
781
|
+
* Default is true.
|
|
782
|
+
*
|
|
783
|
+
* @platform iOS
|
|
784
|
+
*/
|
|
785
|
+
isCustomHlsLoadingEnabled?: boolean;
|
|
786
|
+
/**
|
|
787
|
+
* The threshold which will be applied when seeking to the end in seconds. This value will be used
|
|
788
|
+
* to calculate the maximum seekable time when calling player.seek(time:) or player.playlist.seek(source:time:),
|
|
789
|
+
* so the maximum value will be duration - seekToEndThreshold.
|
|
790
|
+
*
|
|
791
|
+
* This is useful if the duration of the segments does not match the duration specified in the
|
|
792
|
+
* manifest. In this case, if we try to seek to the end, AVPlayer could get stuck and might stall
|
|
793
|
+
* forever Therefore increasing this value could help.
|
|
794
|
+
*
|
|
795
|
+
* Default is 0.5.
|
|
796
|
+
*
|
|
797
|
+
* @platform iOS
|
|
798
|
+
*/
|
|
799
|
+
seekToEndThreshold?: number;
|
|
800
|
+
/**
|
|
801
|
+
* Specifies the player behaviour when Player.play is called. Default is 'relaxed'.
|
|
802
|
+
*
|
|
803
|
+
* - 'relaxed': Starts playback when enough media data is buffered and continuous playback without stalling can be ensured. If insufficient media data is buffered for playback to start, the player will act as if the buffer became empty during playback.
|
|
804
|
+
* - 'aggressive': When the buffer is not empty, this setting will cause the player to start playback of available media immediately. If insufficient media data is buffered for playback to start, the player will act as if the buffer became empty during playback.
|
|
805
|
+
*
|
|
806
|
+
* @platform iOS
|
|
807
|
+
*/
|
|
808
|
+
playbackStartBehaviour?: 'relaxed' | 'aggressive';
|
|
809
|
+
/**
|
|
810
|
+
* Specifies the player behaviour when stalling should be exited. Default is 'relaxed'.
|
|
811
|
+
*
|
|
812
|
+
* - 'relaxed': The player will wait until the buffer is filled that it can, most likely, ensure continuous playback without another stalling right after playback continued.
|
|
813
|
+
* - 'aggressive': The player will try to unstall as soon as some media data became available and will start playback of this media immediately.
|
|
814
|
+
*
|
|
815
|
+
* @platform iOS
|
|
816
|
+
*/
|
|
817
|
+
unstallingBehaviour?: 'relaxed' | 'aggressive';
|
|
818
|
+
/**
|
|
819
|
+
* Constantly aggregated and weighted bandwidth samples are summed up to this weight limit to calculate an bandwidth estimation. Remaining samples (i.e. that would lead to exceeding the limit) are dropped from memory as they are not relevant anymore.
|
|
820
|
+
* Default is 2000.
|
|
821
|
+
*
|
|
822
|
+
* @platform Android
|
|
823
|
+
*/
|
|
824
|
+
bandwidthEstimateWeightLimit?: number;
|
|
825
|
+
/**
|
|
826
|
+
* Some devices have an incorrect implementation of MediaCodec.setOutputSurface. This leads to failure when the surface changes. To prevent failure, the codec will be released and re-instantiated in those scenarios.
|
|
827
|
+
*
|
|
828
|
+
* @platform Android
|
|
829
|
+
*/
|
|
830
|
+
devicesThatRequireSurfaceWorkaround?: {
|
|
831
|
+
/**
|
|
832
|
+
* A device name as reported by Build.DEVICE.
|
|
833
|
+
*
|
|
834
|
+
* @see Build.DEVICE: https://developer.android.com/reference/kotlin/android/os/Build.html#DEVICE--
|
|
835
|
+
*/
|
|
836
|
+
deviceNames?: string[];
|
|
837
|
+
/**
|
|
838
|
+
* A model name as reported by Build.MODEL.
|
|
839
|
+
*
|
|
840
|
+
* @see Build.MODEL: https://developer.android.com/reference/kotlin/android/os/Build.html#MODEL--
|
|
841
|
+
*/
|
|
842
|
+
modelNames?: string[];
|
|
843
|
+
};
|
|
844
|
+
/**
|
|
845
|
+
* Specifies if the language property on DASH Representations, HLS Renditions and SmoothStreaming QualityLevels is normalized.
|
|
846
|
+
* If enabled, language properties are normalized to IETF BCP 47 language tags. Default is true.
|
|
847
|
+
*
|
|
848
|
+
* Examples:
|
|
849
|
+
* - "ENG" is normalized to "en"
|
|
850
|
+
* - "en_us" is normalized to "en-us"
|
|
851
|
+
* - "en-US-x-lvariant-POSIX" is normalized to "en-us-posix"
|
|
852
|
+
*
|
|
853
|
+
* @platform Android
|
|
854
|
+
*/
|
|
855
|
+
languagePropertyNormalization?: boolean;
|
|
856
|
+
/**
|
|
857
|
+
* The interval in which dynamic DASH windows are updated locally. I.e. The rate by which the
|
|
858
|
+
* playback window is moved forward on the timeline.
|
|
859
|
+
*
|
|
860
|
+
* @platform Android
|
|
861
|
+
*/
|
|
862
|
+
localDynamicDashWindowUpdateInterval?: number;
|
|
863
|
+
/**
|
|
864
|
+
* Specifies whether default positioning values should be assumed when parsing TTML regions in case of
|
|
865
|
+
* unsupported TTML features. Default is true
|
|
866
|
+
*
|
|
867
|
+
* @platform Android
|
|
868
|
+
*/
|
|
869
|
+
shouldApplyTtmlRegionWorkaround?: boolean;
|
|
870
|
+
/**
|
|
871
|
+
* Specifies whether a DRM session should be used for clear tracks of type video and audio. Using
|
|
872
|
+
* DRM sessions for clear content avoids the recreation of decoders when transitioning between clear
|
|
873
|
+
* and encrypted sections of content. Default is false.
|
|
874
|
+
*
|
|
875
|
+
* @platform Android
|
|
876
|
+
*/
|
|
877
|
+
useDrmSessionForClearPeriods?: boolean;
|
|
878
|
+
/**
|
|
879
|
+
* Specifies whether a DRM session should be used for clear tracks of type video and audio in a clear
|
|
880
|
+
* source that follows after a DRM protected source. In addition, a DRM session will be used for clear
|
|
881
|
+
* periods in a DRM protected source. Using DRM sessions for clear content avoids the recreation of
|
|
882
|
+
* decoders when transitioning between clear and encrypted sections of content. Default is false.
|
|
883
|
+
*
|
|
884
|
+
* @platform Android
|
|
885
|
+
*/
|
|
886
|
+
useDrmSessionForClearSources?: boolean;
|
|
887
|
+
/**
|
|
888
|
+
* Specifies if the player should always fall back to an extractor matching the file type, if no
|
|
889
|
+
* matching extractor was found. If the fallback is applied, this will ignore potential incompatibilities
|
|
890
|
+
* with streams and thus can result in unstable or failing playback.
|
|
891
|
+
*
|
|
892
|
+
* @platform Android
|
|
893
|
+
*/
|
|
894
|
+
useFiletypeExtractorFallbackForHls?: boolean;
|
|
895
|
+
}
|
|
896
|
+
|
|
743
897
|
/**
|
|
744
898
|
* Object used to configure a new `Player` instance.
|
|
745
899
|
*/
|
|
@@ -767,6 +921,10 @@ interface PlayerConfig extends NativeInstanceConfig {
|
|
|
767
921
|
* Configures playback behaviour. A default PlaybackConfig is set initially.
|
|
768
922
|
*/
|
|
769
923
|
playbackConfig?: PlaybackConfig;
|
|
924
|
+
/**
|
|
925
|
+
* Configures experimental features. A default TweaksConfig is set initially.
|
|
926
|
+
*/
|
|
927
|
+
tweaksConfig?: TweaksConfig;
|
|
770
928
|
}
|
|
771
929
|
/**
|
|
772
930
|
* Configures the playback behaviour of the player.
|
package/package.json
CHANGED
package/src/player.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { NativeModules, Platform } from 'react-native';
|
|
|
2
2
|
import NativeInstance, { NativeInstanceConfig } from './nativeInstance';
|
|
3
3
|
import { Source, SourceConfig } from './source';
|
|
4
4
|
import { SubtitleTrack } from './subtitleTrack';
|
|
5
|
+
import { TweaksConfig } from './tweaksConfig';
|
|
5
6
|
|
|
6
7
|
const PlayerModule = NativeModules.PlayerModule;
|
|
7
8
|
|
|
@@ -32,6 +33,10 @@ export interface PlayerConfig extends NativeInstanceConfig {
|
|
|
32
33
|
* Configures playback behaviour. A default PlaybackConfig is set initially.
|
|
33
34
|
*/
|
|
34
35
|
playbackConfig?: PlaybackConfig;
|
|
36
|
+
/**
|
|
37
|
+
* Configures experimental features. A default TweaksConfig is set initially.
|
|
38
|
+
*/
|
|
39
|
+
tweaksConfig?: TweaksConfig;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
/**
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This configuration is used as an incubator for experimental features. Tweaks are not officially
|
|
3
|
+
* supported and are not guaranteed to be stable, i.e. their naming, functionality and API can
|
|
4
|
+
* change at any time within the tweaks or when being promoted to an official feature and moved
|
|
5
|
+
* into its final configuration namespace.
|
|
6
|
+
*/
|
|
7
|
+
export interface TweaksConfig {
|
|
8
|
+
/**
|
|
9
|
+
* The frequency in seconds onTimeChanged is called with TimeChangedEvents.
|
|
10
|
+
*
|
|
11
|
+
* Default value in iOS is `1.0`.
|
|
12
|
+
* Default value in Android is `0.2`.
|
|
13
|
+
*
|
|
14
|
+
* @platform iOS, Android
|
|
15
|
+
*/
|
|
16
|
+
timeChangedInterval?: number;
|
|
17
|
+
/**
|
|
18
|
+
* If enabled, HLS playlists will be parsed and additional features and events are enabled. This includes:
|
|
19
|
+
*
|
|
20
|
+
* - MetadataEvents carrying segment-specific metadata for custom HLS tags, like #EXT-X-SCTE35
|
|
21
|
+
* - MetadataParsedEvents carrying segment-specific metadata for custom HLS tags, like #EXT-X-SCTE35
|
|
22
|
+
* - DrmDataParsedEvents when a #EXT-X-KEY is found
|
|
23
|
+
* - Player.availableVideoQualities includes additional information
|
|
24
|
+
* - Automatic retries when HLS playlist requests failed with non-2xx HTTP status code
|
|
25
|
+
*
|
|
26
|
+
* Default is false.
|
|
27
|
+
*
|
|
28
|
+
* @platform iOS
|
|
29
|
+
*/
|
|
30
|
+
isNativeHlsParsingEnabled?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* If enabled, playlists will be downloaded by the Bitmovin Player SDK instead of AVFoundation.
|
|
33
|
+
* This enables additional features and events, like:
|
|
34
|
+
*
|
|
35
|
+
* - DownloadFinishedEvents for playlist downloads.
|
|
36
|
+
* - SourceWarningEvents when no #EXT-X-PLAYLIST-TYPE is found If set to false, enabling
|
|
37
|
+
* nativeHlsParsingEnabled won’t have any effect.
|
|
38
|
+
*
|
|
39
|
+
* Default is true.
|
|
40
|
+
*
|
|
41
|
+
* @platform iOS
|
|
42
|
+
*/
|
|
43
|
+
isCustomHlsLoadingEnabled?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* The threshold which will be applied when seeking to the end in seconds. This value will be used
|
|
46
|
+
* to calculate the maximum seekable time when calling player.seek(time:) or player.playlist.seek(source:time:),
|
|
47
|
+
* so the maximum value will be duration - seekToEndThreshold.
|
|
48
|
+
*
|
|
49
|
+
* This is useful if the duration of the segments does not match the duration specified in the
|
|
50
|
+
* manifest. In this case, if we try to seek to the end, AVPlayer could get stuck and might stall
|
|
51
|
+
* forever Therefore increasing this value could help.
|
|
52
|
+
*
|
|
53
|
+
* Default is 0.5.
|
|
54
|
+
*
|
|
55
|
+
* @platform iOS
|
|
56
|
+
*/
|
|
57
|
+
seekToEndThreshold?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Specifies the player behaviour when Player.play is called. Default is 'relaxed'.
|
|
60
|
+
*
|
|
61
|
+
* - 'relaxed': Starts playback when enough media data is buffered and continuous playback without stalling can be ensured. If insufficient media data is buffered for playback to start, the player will act as if the buffer became empty during playback.
|
|
62
|
+
* - 'aggressive': When the buffer is not empty, this setting will cause the player to start playback of available media immediately. If insufficient media data is buffered for playback to start, the player will act as if the buffer became empty during playback.
|
|
63
|
+
*
|
|
64
|
+
* @platform iOS
|
|
65
|
+
*/
|
|
66
|
+
playbackStartBehaviour?: 'relaxed' | 'aggressive';
|
|
67
|
+
/**
|
|
68
|
+
* Specifies the player behaviour when stalling should be exited. Default is 'relaxed'.
|
|
69
|
+
*
|
|
70
|
+
* - 'relaxed': The player will wait until the buffer is filled that it can, most likely, ensure continuous playback without another stalling right after playback continued.
|
|
71
|
+
* - 'aggressive': The player will try to unstall as soon as some media data became available and will start playback of this media immediately.
|
|
72
|
+
*
|
|
73
|
+
* @platform iOS
|
|
74
|
+
*/
|
|
75
|
+
unstallingBehaviour?: 'relaxed' | 'aggressive';
|
|
76
|
+
/**
|
|
77
|
+
* Constantly aggregated and weighted bandwidth samples are summed up to this weight limit to calculate an bandwidth estimation. Remaining samples (i.e. that would lead to exceeding the limit) are dropped from memory as they are not relevant anymore.
|
|
78
|
+
* Default is 2000.
|
|
79
|
+
*
|
|
80
|
+
* @platform Android
|
|
81
|
+
*/
|
|
82
|
+
bandwidthEstimateWeightLimit?: number;
|
|
83
|
+
/**
|
|
84
|
+
* Some devices have an incorrect implementation of MediaCodec.setOutputSurface. This leads to failure when the surface changes. To prevent failure, the codec will be released and re-instantiated in those scenarios.
|
|
85
|
+
*
|
|
86
|
+
* @platform Android
|
|
87
|
+
*/
|
|
88
|
+
devicesThatRequireSurfaceWorkaround?: {
|
|
89
|
+
/**
|
|
90
|
+
* A device name as reported by Build.DEVICE.
|
|
91
|
+
*
|
|
92
|
+
* @see Build.DEVICE: https://developer.android.com/reference/kotlin/android/os/Build.html#DEVICE--
|
|
93
|
+
*/
|
|
94
|
+
deviceNames?: string[];
|
|
95
|
+
/**
|
|
96
|
+
* A model name as reported by Build.MODEL.
|
|
97
|
+
*
|
|
98
|
+
* @see Build.MODEL: https://developer.android.com/reference/kotlin/android/os/Build.html#MODEL--
|
|
99
|
+
*/
|
|
100
|
+
modelNames?: string[];
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Specifies if the language property on DASH Representations, HLS Renditions and SmoothStreaming QualityLevels is normalized.
|
|
104
|
+
* If enabled, language properties are normalized to IETF BCP 47 language tags. Default is true.
|
|
105
|
+
*
|
|
106
|
+
* Examples:
|
|
107
|
+
* - "ENG" is normalized to "en"
|
|
108
|
+
* - "en_us" is normalized to "en-us"
|
|
109
|
+
* - "en-US-x-lvariant-POSIX" is normalized to "en-us-posix"
|
|
110
|
+
*
|
|
111
|
+
* @platform Android
|
|
112
|
+
*/
|
|
113
|
+
languagePropertyNormalization?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* The interval in which dynamic DASH windows are updated locally. I.e. The rate by which the
|
|
116
|
+
* playback window is moved forward on the timeline.
|
|
117
|
+
*
|
|
118
|
+
* @platform Android
|
|
119
|
+
*/
|
|
120
|
+
localDynamicDashWindowUpdateInterval?: number;
|
|
121
|
+
/**
|
|
122
|
+
* Specifies whether default positioning values should be assumed when parsing TTML regions in case of
|
|
123
|
+
* unsupported TTML features. Default is true
|
|
124
|
+
*
|
|
125
|
+
* @platform Android
|
|
126
|
+
*/
|
|
127
|
+
shouldApplyTtmlRegionWorkaround?: boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Specifies whether a DRM session should be used for clear tracks of type video and audio. Using
|
|
130
|
+
* DRM sessions for clear content avoids the recreation of decoders when transitioning between clear
|
|
131
|
+
* and encrypted sections of content. Default is false.
|
|
132
|
+
*
|
|
133
|
+
* @platform Android
|
|
134
|
+
*/
|
|
135
|
+
useDrmSessionForClearPeriods?: boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Specifies whether a DRM session should be used for clear tracks of type video and audio in a clear
|
|
138
|
+
* source that follows after a DRM protected source. In addition, a DRM session will be used for clear
|
|
139
|
+
* periods in a DRM protected source. Using DRM sessions for clear content avoids the recreation of
|
|
140
|
+
* decoders when transitioning between clear and encrypted sections of content. Default is false.
|
|
141
|
+
*
|
|
142
|
+
* @platform Android
|
|
143
|
+
*/
|
|
144
|
+
useDrmSessionForClearSources?: boolean;
|
|
145
|
+
/**
|
|
146
|
+
* Specifies if the player should always fall back to an extractor matching the file type, if no
|
|
147
|
+
* matching extractor was found. If the fallback is applied, this will ignore potential incompatibilities
|
|
148
|
+
* with streams and thus can result in unstable or failing playback.
|
|
149
|
+
*
|
|
150
|
+
* @platform Android
|
|
151
|
+
*/
|
|
152
|
+
useFiletypeExtractorFallbackForHls?: boolean;
|
|
153
|
+
}
|