bitmovin-player-react-native 0.3.1 → 0.5.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/README.md +486 -24
- package/RNBitmovinPlayer.podspec +5 -1
- package/android/build.gradle +8 -5
- package/android/src/main/java/com/bitmovin/player/reactnative/AnalyticsModule.kt +154 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/DrmModule.kt +4 -5
- package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +41 -5
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +318 -2
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +70 -9
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewPackage.kt +3 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/SourceModule.kt +4 -5
- package/android/src/main/java/com/bitmovin/player/reactnative/UuidModule.kt +3 -1
- package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +389 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Any.kt +27 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReactContextExtension.kt +8 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/ReadableArray.kt +19 -2
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/String.kt +8 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/WritableMap.kt +19 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerBridge.kt +37 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/ui/FullscreenHandlerModule.kt +73 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/ui/RNPictureInPictureHandler.kt +191 -0
- package/ios/AnalyticsModule.m +14 -0
- package/ios/AnalyticsModule.swift +180 -0
- package/ios/AudioSessionModule.m +10 -0
- package/ios/AudioSessionModule.swift +65 -0
- package/ios/Event+JSON.swift +134 -0
- package/ios/FullscreenHandlerBridge.swift +33 -0
- package/ios/FullscreenHandlerModule.m +9 -0
- package/ios/FullscreenHandlerModule.swift +71 -0
- package/ios/PlayerModule.m +6 -0
- package/ios/PlayerModule.swift +44 -0
- package/ios/RCTConvert+BitmovinPlayer.swift +382 -0
- package/ios/RNPlayerView+PlayerListener.swift +56 -0
- package/ios/RNPlayerView+UserInterfaceListener.swift +35 -0
- package/ios/RNPlayerView.swift +22 -0
- package/ios/RNPlayerViewManager.m +24 -1
- package/ios/RNPlayerViewManager.swift +23 -1
- package/lib/index.d.ts +1013 -150
- package/lib/index.js +251 -48
- package/lib/index.mjs +231 -34
- package/package.json +1 -1
- package/src/advertising.ts +155 -0
- package/src/analytics/collector.ts +97 -0
- package/src/analytics/config.ts +218 -0
- package/src/analytics/index.ts +2 -0
- package/src/audioSession.ts +47 -0
- package/src/components/PlayerView/events.ts +49 -3
- package/src/components/PlayerView/index.tsx +68 -11
- package/src/components/PlayerView/native.ts +4 -1
- package/src/events.ts +255 -0
- package/src/index.ts +4 -0
- package/src/media.ts +33 -0
- package/src/player.ts +57 -1
- package/src/source.ts +4 -0
- package/src/styleConfig.ts +87 -0
- package/src/ui/fullscreenhandler.ts +19 -0
- package/src/ui/fullscreenhandlerbridge.ts +59 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
package com.bitmovin.player.reactnative
|
|
2
|
+
|
|
3
|
+
import com.bitmovin.analytics.bitmovin.player.BitmovinPlayerCollector
|
|
4
|
+
import com.bitmovin.player.reactnative.converter.JsonConverter
|
|
5
|
+
import com.facebook.react.bridge.*
|
|
6
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
7
|
+
import com.facebook.react.uimanager.UIManagerModule
|
|
8
|
+
|
|
9
|
+
private const val MODULE_NAME = "AnalyticsModule"
|
|
10
|
+
|
|
11
|
+
@ReactModule(name = MODULE_NAME)
|
|
12
|
+
class AnalyticsModule(private val context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
|
|
13
|
+
/**
|
|
14
|
+
* In-memory mapping from `nativeId`s to `BitmovinPlayerCollector` instances.
|
|
15
|
+
*/
|
|
16
|
+
private val collectors: Registry<BitmovinPlayerCollector> = mutableMapOf()
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* JS exported module name.
|
|
20
|
+
*/
|
|
21
|
+
override fun getName() = MODULE_NAME
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Fetches the `BitmovinPlayerCollector` instance associated with `nativeId` from the internal registry.
|
|
25
|
+
* @param nativeId `BitmovinPlayerCollector` instance ID.
|
|
26
|
+
* @return The associated `BitmovinPlayerCollector` instance or `null`.
|
|
27
|
+
*/
|
|
28
|
+
fun getCollector(nativeId: NativeId?): BitmovinPlayerCollector? {
|
|
29
|
+
if (nativeId == null) {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
return collectors[nativeId]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Creates a new `BitmovinPlayerCollector` instance inside the internal registry using the provided `config` object.
|
|
37
|
+
* @param config `BitmovinAnalyticsConfig` object received from JS.
|
|
38
|
+
*/
|
|
39
|
+
@ReactMethod
|
|
40
|
+
fun initWithConfig(nativeId: NativeId, config: ReadableMap?) {
|
|
41
|
+
uiManager()?.addUIBlock { _ ->
|
|
42
|
+
JsonConverter.toAnalyticsConfig(config)?.let {
|
|
43
|
+
collectors[nativeId] = BitmovinPlayerCollector(it, context)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Detaches and removes the given `BitmovinPlayerCollector` from the internal registry.
|
|
50
|
+
* @param nativeId Native Id of the collector instance.
|
|
51
|
+
*/
|
|
52
|
+
@ReactMethod
|
|
53
|
+
fun destroy(nativeId: NativeId) {
|
|
54
|
+
uiManager()?.addUIBlock {
|
|
55
|
+
if (collectors.containsKey(nativeId)) {
|
|
56
|
+
collectors[nativeId]?.detachPlayer()
|
|
57
|
+
collectors.remove(nativeId)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Attaches a `BitmovinPlayerCollector` to the `Player` instance with native Id equal to `playerId`.
|
|
64
|
+
* @param nativeId Native Id of the collector instance.
|
|
65
|
+
* @param playerId Native Id of the player instance.
|
|
66
|
+
*/
|
|
67
|
+
@ReactMethod
|
|
68
|
+
fun attach(nativeId: NativeId, playerId: NativeId) {
|
|
69
|
+
uiManager()?.addUIBlock { _ ->
|
|
70
|
+
playerModule()?.getPlayer(playerId)?.let {
|
|
71
|
+
collectors[nativeId]?.attachPlayer(it)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Detaches the player object from a `BitmovinPlayerCollector` instance.
|
|
78
|
+
* @param nativeId Native Id of the collector instance.
|
|
79
|
+
*/
|
|
80
|
+
@ReactMethod
|
|
81
|
+
fun detach(nativeId: NativeId) {
|
|
82
|
+
uiManager()?.addUIBlock { _ ->
|
|
83
|
+
collectors[nativeId]?.detachPlayer()
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Updates the custom data config for a `BitmovinPlayerCollector` instance.
|
|
89
|
+
* @param nativeId Native Id of the collector instance.
|
|
90
|
+
* @param json Custom data config json.
|
|
91
|
+
*/
|
|
92
|
+
@ReactMethod
|
|
93
|
+
fun setCustomDataOnce(nativeId: NativeId, json: ReadableMap?) {
|
|
94
|
+
uiManager()?.addUIBlock { _ ->
|
|
95
|
+
JsonConverter.toAnalyticsCustomData(json)?.let {
|
|
96
|
+
collectors[nativeId]?.setCustomDataOnce(it)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Sets the custom data config for a `BitmovinPlayerCollector` instance.
|
|
103
|
+
* @param nativeId Native Id of the collector instance.
|
|
104
|
+
* @param json Custom data config json.
|
|
105
|
+
*/
|
|
106
|
+
@ReactMethod
|
|
107
|
+
fun setCustomData(nativeId: NativeId, json: ReadableMap?) {
|
|
108
|
+
uiManager()?.addUIBlock { _ ->
|
|
109
|
+
JsonConverter.toAnalyticsCustomData(json)?.let {
|
|
110
|
+
collectors[nativeId]?.customData = it
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Gets the current custom data config for a `BitmovinPlayerCollector` instance.
|
|
117
|
+
* @param nativeId Native Id of the the collector instance.
|
|
118
|
+
* @param promise JS promise object.
|
|
119
|
+
*/
|
|
120
|
+
@ReactMethod
|
|
121
|
+
fun getCustomData(nativeId: NativeId, promise: Promise) {
|
|
122
|
+
uiManager()?.addUIBlock { _ ->
|
|
123
|
+
collectors[nativeId]?.let {
|
|
124
|
+
promise.resolve(JsonConverter.fromAnalyticsCustomData(it.customData))
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Gets the current user Id for a `BitmovinPlayerCollector` instance.
|
|
131
|
+
* @param nativeId Native Id of the the collector instance.
|
|
132
|
+
* @param promise JS promise object.
|
|
133
|
+
*/
|
|
134
|
+
@ReactMethod
|
|
135
|
+
fun getUserId(nativeId: NativeId, promise: Promise) {
|
|
136
|
+
uiManager()?.addUIBlock { _ ->
|
|
137
|
+
collectors[nativeId]?.let {
|
|
138
|
+
promise.resolve(it.userId)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Helper function that gets the instantiated `UIManagerModule` from modules registry.
|
|
145
|
+
*/
|
|
146
|
+
private fun uiManager(): UIManagerModule? =
|
|
147
|
+
context.getNativeModule(UIManagerModule::class.java)
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Helper function that gets the instantiated `PlayerModule` from modules registry.
|
|
151
|
+
*/
|
|
152
|
+
private fun playerModule(): PlayerModule? =
|
|
153
|
+
context.getNativeModule(PlayerModule::class.java)
|
|
154
|
+
}
|
|
@@ -17,7 +17,9 @@ import kotlin.concurrent.withLock
|
|
|
17
17
|
*/
|
|
18
18
|
typealias PrepareCallback = (ByteArray) -> ByteArray
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
private const val MODULE_NAME = "DrmModule"
|
|
21
|
+
|
|
22
|
+
@ReactModule(name = MODULE_NAME)
|
|
21
23
|
class DrmModule(private val context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
|
|
22
24
|
/**
|
|
23
25
|
* In-memory mapping from `nativeId`s to `WidevineConfig` instances.
|
|
@@ -52,10 +54,7 @@ class DrmModule(private val context: ReactApplicationContext) : ReactContextBase
|
|
|
52
54
|
/**
|
|
53
55
|
* JS exported module name.
|
|
54
56
|
*/
|
|
55
|
-
|
|
56
|
-
const val name = "DrmModule"
|
|
57
|
-
}
|
|
58
|
-
override fun getName() = DrmModule.name
|
|
57
|
+
override fun getName() = MODULE_NAME
|
|
59
58
|
|
|
60
59
|
/**
|
|
61
60
|
* Fetches the `WidevineConfig` instance associated with `nativeId` from internal drmConfigs.
|
|
@@ -6,7 +6,9 @@ import com.facebook.react.bridge.*
|
|
|
6
6
|
import com.facebook.react.module.annotations.ReactModule
|
|
7
7
|
import com.facebook.react.uimanager.UIManagerModule
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
private const val MODULE_NAME = "PlayerModule"
|
|
10
|
+
|
|
11
|
+
@ReactModule(name = MODULE_NAME)
|
|
10
12
|
class PlayerModule(private val context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
|
|
11
13
|
/**
|
|
12
14
|
* In-memory mapping from `nativeId`s to `Player` instances.
|
|
@@ -16,10 +18,7 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
|
|
|
16
18
|
/**
|
|
17
19
|
* JS exported module name.
|
|
18
20
|
*/
|
|
19
|
-
|
|
20
|
-
const val name = "PlayerModule"
|
|
21
|
-
}
|
|
22
|
-
override fun getName() = PlayerModule.name
|
|
21
|
+
override fun getName() = MODULE_NAME
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
24
|
* Fetches the `Player` instance associated with `nativeId` from the internal players.
|
|
@@ -280,6 +279,43 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
|
|
|
280
279
|
}
|
|
281
280
|
}
|
|
282
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Schedules an `AdItem` in the `nativeId`'s associated player.
|
|
284
|
+
* @param nativeId Target player id.
|
|
285
|
+
* @param adItemJson Json representation of the `AdItem` to be scheduled.
|
|
286
|
+
*/
|
|
287
|
+
@ReactMethod
|
|
288
|
+
fun scheduleAd(nativeId: NativeId, adItemJson: ReadableMap?) {
|
|
289
|
+
JsonConverter.toAdItem(adItemJson)?.let { adItem ->
|
|
290
|
+
uiManager()?.addUIBlock {
|
|
291
|
+
players[nativeId]?.scheduleAd(adItem)
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Skips the current ad in `nativeId`'s associated player.
|
|
298
|
+
* Has no effect if the current ad is not skippable or if no ad is being played back.
|
|
299
|
+
* @param nativeId Target player id.
|
|
300
|
+
*/
|
|
301
|
+
@ReactMethod
|
|
302
|
+
fun skipAd(nativeId: NativeId) {
|
|
303
|
+
uiManager()?.addUIBlock {
|
|
304
|
+
players[nativeId]?.skipAd()
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Returns `true` while an ad is being played back or when main content playback has been paused for ad playback.
|
|
310
|
+
* @param nativeId Target player id.
|
|
311
|
+
*/
|
|
312
|
+
@ReactMethod
|
|
313
|
+
fun isAd(nativeId: NativeId, promise: Promise) {
|
|
314
|
+
uiManager()?.addUIBlock {
|
|
315
|
+
promise.resolve(players[nativeId]?.isAd)
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
283
319
|
/**
|
|
284
320
|
* Helper function that returns the initialized `UIManager` instance.
|
|
285
321
|
*/
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
package com.bitmovin.player.reactnative
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
|
+
import android.content.res.Configuration
|
|
5
|
+
import android.graphics.Rect
|
|
6
|
+
import android.view.View
|
|
4
7
|
import android.view.ViewGroup
|
|
5
8
|
import android.widget.LinearLayout
|
|
6
9
|
import com.bitmovin.player.PlayerView
|
|
@@ -10,6 +13,9 @@ import com.bitmovin.player.api.event.PlayerEvent
|
|
|
10
13
|
import com.bitmovin.player.api.event.SourceEvent
|
|
11
14
|
import com.bitmovin.player.api.event.on
|
|
12
15
|
import com.bitmovin.player.reactnative.converter.JsonConverter
|
|
16
|
+
import com.bitmovin.player.reactnative.ui.RNPictureInPictureDelegate
|
|
17
|
+
import com.bitmovin.player.reactnative.ui.RNPictureInPictureHandler
|
|
18
|
+
import com.facebook.react.bridge.LifecycleEventListener
|
|
13
19
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
14
20
|
import com.facebook.react.bridge.ReactContext
|
|
15
21
|
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
@@ -20,9 +26,10 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
|
20
26
|
* exposes player events as bubbling events.
|
|
21
27
|
*/
|
|
22
28
|
@SuppressLint("ViewConstructor")
|
|
23
|
-
class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context)
|
|
29
|
+
class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context),
|
|
30
|
+
LifecycleEventListener, View.OnLayoutChangeListener, RNPictureInPictureDelegate {
|
|
24
31
|
/**
|
|
25
|
-
*
|
|
32
|
+
* Associated bitmovin's `PlayerView`.
|
|
26
33
|
*/
|
|
27
34
|
var playerView: PlayerView? = null
|
|
28
35
|
|
|
@@ -35,6 +42,57 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
|
|
|
35
42
|
playerView?.player = value
|
|
36
43
|
}
|
|
37
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Object that handles PiP mode changes in React Native.
|
|
47
|
+
*/
|
|
48
|
+
var pictureInPictureHandler: RNPictureInPictureHandler? = null
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Whether this view should pause video playback when activity's onPause is called.
|
|
52
|
+
* By default, `shouldPausePlaybackOnActivityPause` is set to false when entering PiP mode.
|
|
53
|
+
*/
|
|
54
|
+
private var shouldPausePlaybackOnActivityPause = true
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Register this view as an activity lifecycle listener on initialization.
|
|
58
|
+
*/
|
|
59
|
+
init {
|
|
60
|
+
context.addLifecycleEventListener(this)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Cleans up the resources and listeners produced by this view.
|
|
65
|
+
*/
|
|
66
|
+
fun dispose() {
|
|
67
|
+
stopBubblingEvents()
|
|
68
|
+
context.removeLifecycleEventListener(this)
|
|
69
|
+
playerView?.removeOnLayoutChangeListener(this)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Activity's onResume
|
|
74
|
+
*/
|
|
75
|
+
override fun onHostResume() {
|
|
76
|
+
playerView?.onResume()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Activity's onPause
|
|
81
|
+
*/
|
|
82
|
+
override fun onHostPause() {
|
|
83
|
+
if (shouldPausePlaybackOnActivityPause) {
|
|
84
|
+
playerView?.onPause()
|
|
85
|
+
}
|
|
86
|
+
shouldPausePlaybackOnActivityPause = true
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Activity's onDestroy
|
|
91
|
+
*/
|
|
92
|
+
override fun onHostDestroy() {
|
|
93
|
+
playerView?.onDestroy()
|
|
94
|
+
}
|
|
95
|
+
|
|
38
96
|
/**
|
|
39
97
|
* Set the given `playerView` as child and start bubbling events.
|
|
40
98
|
* @param playerView Shared player view instance.
|
|
@@ -44,6 +102,71 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
|
|
|
44
102
|
if (playerView.parent != this) {
|
|
45
103
|
(playerView.parent as ViewGroup?)?.removeView(playerView)
|
|
46
104
|
addView(playerView)
|
|
105
|
+
startBubblingEvents()
|
|
106
|
+
}
|
|
107
|
+
pictureInPictureHandler?.let {
|
|
108
|
+
it.setDelegate(this)
|
|
109
|
+
playerView.setPictureInPictureHandler(it)
|
|
110
|
+
playerView.addOnLayoutChangeListener(this)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Called whenever this view's activity configuration changes.
|
|
116
|
+
*/
|
|
117
|
+
override fun onConfigurationChanged(newConfig: Configuration?) {
|
|
118
|
+
super.onConfigurationChanged(newConfig)
|
|
119
|
+
pictureInPictureHandler?.onConfigurationChanged(newConfig)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Called when the player has just entered PiP mode.
|
|
124
|
+
*/
|
|
125
|
+
override fun onEnterPictureInPicture() {
|
|
126
|
+
// Playback shouldn't be paused when entering PiP mode.
|
|
127
|
+
shouldPausePlaybackOnActivityPause = false
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Called when the player has just exited PiP mode.
|
|
132
|
+
*/
|
|
133
|
+
override fun onExitPictureInPicture() {
|
|
134
|
+
// Explicitly call `exitPictureInPicture()` on PlayerView when exiting PiP state, otherwise
|
|
135
|
+
// the `PictureInPictureExit` event won't get dispatched.
|
|
136
|
+
playerView?.exitPictureInPicture()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Called when the player's PiP mode changes with a new configuration object.
|
|
141
|
+
*/
|
|
142
|
+
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration?) {
|
|
143
|
+
playerView?.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Called whenever the PiP handler needs to compute the PlayerView's global visible rect.
|
|
148
|
+
*/
|
|
149
|
+
override fun setSourceRectHint(sourceRectHint: Rect) {
|
|
150
|
+
playerView?.getGlobalVisibleRect(sourceRectHint)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Called whenever PlayerView's layout changes.
|
|
155
|
+
*/
|
|
156
|
+
override fun onLayoutChange(
|
|
157
|
+
view: View?,
|
|
158
|
+
left: Int,
|
|
159
|
+
top: Int,
|
|
160
|
+
right: Int,
|
|
161
|
+
bottom: Int,
|
|
162
|
+
oldLeft: Int,
|
|
163
|
+
oldTop: Int,
|
|
164
|
+
oldRight: Int,
|
|
165
|
+
oldBottom: Int,
|
|
166
|
+
) {
|
|
167
|
+
if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) {
|
|
168
|
+
// Update source rect hint whenever the player's layout change
|
|
169
|
+
pictureInPictureHandler?.updateSourceRectHint()
|
|
47
170
|
}
|
|
48
171
|
}
|
|
49
172
|
|
|
@@ -153,6 +276,20 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
|
|
|
153
276
|
emitEvent("seeked", it)
|
|
154
277
|
}
|
|
155
278
|
|
|
279
|
+
/**
|
|
280
|
+
* `onStallStarted` event callback.
|
|
281
|
+
*/
|
|
282
|
+
private val onStallStarted: (PlayerEvent.StallStarted) -> Unit = {
|
|
283
|
+
emitEvent("stallStarted", it)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* `onStallEnded` event callback.
|
|
288
|
+
*/
|
|
289
|
+
private val onStallEnded: (PlayerEvent.StallEnded) -> Unit = {
|
|
290
|
+
emitEvent("stallEnded", it)
|
|
291
|
+
}
|
|
292
|
+
|
|
156
293
|
/**
|
|
157
294
|
* `onTimeChanged` event callback.
|
|
158
295
|
*/
|
|
@@ -216,6 +353,139 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
|
|
|
216
353
|
emitEvent("subtitleRemoved", it)
|
|
217
354
|
}
|
|
218
355
|
|
|
356
|
+
/**
|
|
357
|
+
* `onPictureInPictureAvailabilityChanged` event callback.
|
|
358
|
+
*/
|
|
359
|
+
private val onPictureInPictureAvailabilityChanged: (PlayerEvent.PictureInPictureAvailabilityChanged) -> Unit = {
|
|
360
|
+
emitEvent("pictureInPictureAvailabilityChanged", it)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* `onPictureInPictureEnter` event callback.
|
|
365
|
+
*/
|
|
366
|
+
private val onPictureInPictureEnter: (PlayerEvent.PictureInPictureEnter) -> Unit = {
|
|
367
|
+
emitEvent("pictureInPictureEnter", it)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* `onPictureInPictureExit` event callback.
|
|
372
|
+
*/
|
|
373
|
+
private val onPictureInPictureExit: (PlayerEvent.PictureInPictureExit) -> Unit = {
|
|
374
|
+
emitEvent("pictureInPictureExit", it)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* `onAdBreakFinished` event callback.
|
|
379
|
+
*/
|
|
380
|
+
private val onAdBreakFinished: (PlayerEvent.AdBreakFinished) -> Unit = {
|
|
381
|
+
emitEvent("adBreakFinished", it)
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* `onAdBreakStarted` event callback.
|
|
386
|
+
*/
|
|
387
|
+
private val onAdBreakStarted: (PlayerEvent.AdBreakStarted) -> Unit = {
|
|
388
|
+
emitEvent("adBreakStarted", it)
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* `onAdClicked` event callback.
|
|
393
|
+
*/
|
|
394
|
+
private val onAdClicked: (PlayerEvent.AdClicked) -> Unit = {
|
|
395
|
+
emitEvent("adClicked", it)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* `onAdError` event callback.
|
|
400
|
+
*/
|
|
401
|
+
private val onAdError: (PlayerEvent.AdError) -> Unit = {
|
|
402
|
+
emitEvent("adError", it)
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* `onAdFinished` event callback.
|
|
407
|
+
*/
|
|
408
|
+
private val onAdFinished: (PlayerEvent.AdFinished) -> Unit = {
|
|
409
|
+
emitEvent("adFinished", it)
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* `onAdManifestLoad` event callback.
|
|
414
|
+
*/
|
|
415
|
+
private val onAdManifestLoad: (PlayerEvent.AdManifestLoad) -> Unit = {
|
|
416
|
+
emitEvent("adManifestLoad", it)
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* `onAdManifestLoaded` event callback.
|
|
421
|
+
*/
|
|
422
|
+
private val onAdManifestLoaded: (PlayerEvent.AdManifestLoaded) -> Unit = {
|
|
423
|
+
emitEvent("adManifestLoaded", it)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* `onAdQuartile` event callback.
|
|
428
|
+
*/
|
|
429
|
+
private val onAdQuartile: (PlayerEvent.AdQuartile) -> Unit = {
|
|
430
|
+
emitEvent("adQuartile", it)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* `onAdScheduled` event callback.
|
|
435
|
+
*/
|
|
436
|
+
private val onAdScheduled: (PlayerEvent.AdScheduled) -> Unit = {
|
|
437
|
+
emitEvent("adScheduled", it)
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* `onAdSkipped` event callback.
|
|
442
|
+
*/
|
|
443
|
+
private val onAdSkipped: (PlayerEvent.AdSkipped) -> Unit = {
|
|
444
|
+
emitEvent("adSkipped", it)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* `onAdStarted` event callback.
|
|
449
|
+
*/
|
|
450
|
+
private val onAdStarted: (PlayerEvent.AdStarted) -> Unit = {
|
|
451
|
+
emitEvent("adStarted", it)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* `onVideoPlaybackQualityChanged` event callback.
|
|
456
|
+
*/
|
|
457
|
+
private val onVideoPlaybackQualityChanged: (PlayerEvent.VideoPlaybackQualityChanged) -> Unit = {
|
|
458
|
+
emitEvent("videoPlaybackQualityChanged", it)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* `onFullscreenEnabled` event callback.
|
|
463
|
+
*/
|
|
464
|
+
private val onFullscreenEnabled: (PlayerEvent.FullscreenEnabled) -> Unit = {
|
|
465
|
+
emitEvent("fullscreenEnabled", it)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* `onFullscreenEnabled` event callback.
|
|
470
|
+
*/
|
|
471
|
+
private val onFullscreenDisabled: (PlayerEvent.FullscreenDisabled) -> Unit = {
|
|
472
|
+
emitEvent("fullscreenDisabled", it)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* `onFullscreenEnter` event callback.
|
|
477
|
+
*/
|
|
478
|
+
private val onFullscreenEnter: (PlayerEvent.FullscreenEnter) -> Unit = {
|
|
479
|
+
emitEvent("fullscreenEnter", it)
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* `onFullscreenEnter` event callback.
|
|
484
|
+
*/
|
|
485
|
+
private val onFullscreenExit: (PlayerEvent.FullscreenExit) -> Unit = {
|
|
486
|
+
emitEvent("fullscreenExit", it)
|
|
487
|
+
}
|
|
488
|
+
|
|
219
489
|
/**
|
|
220
490
|
* Start listening and emitting player events as bubbling events to the js side.
|
|
221
491
|
*/
|
|
@@ -234,6 +504,8 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
|
|
|
234
504
|
on(onPlaybackFinished)
|
|
235
505
|
on(onSeek)
|
|
236
506
|
on(onSeeked)
|
|
507
|
+
on(onStallStarted)
|
|
508
|
+
on(onStallEnded)
|
|
237
509
|
on(onTimeChanged)
|
|
238
510
|
on(onSourceLoad)
|
|
239
511
|
on(onSourceLoaded)
|
|
@@ -243,6 +515,27 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
|
|
|
243
515
|
on(onSubtitleAdded)
|
|
244
516
|
on(onSubtitleChanged)
|
|
245
517
|
on(onSubtitleRemoved)
|
|
518
|
+
on(onAdBreakFinished)
|
|
519
|
+
on(onAdBreakStarted)
|
|
520
|
+
on(onAdClicked)
|
|
521
|
+
on(onAdError)
|
|
522
|
+
on(onAdFinished)
|
|
523
|
+
on(onAdManifestLoad)
|
|
524
|
+
on(onAdManifestLoaded)
|
|
525
|
+
on(onAdQuartile)
|
|
526
|
+
on(onAdScheduled)
|
|
527
|
+
on(onAdSkipped)
|
|
528
|
+
on(onAdStarted)
|
|
529
|
+
on(onVideoPlaybackQualityChanged)
|
|
530
|
+
}
|
|
531
|
+
playerView?.apply {
|
|
532
|
+
on(onPictureInPictureAvailabilityChanged)
|
|
533
|
+
on(onPictureInPictureEnter)
|
|
534
|
+
on(onPictureInPictureExit)
|
|
535
|
+
on(onFullscreenEnabled)
|
|
536
|
+
on(onFullscreenDisabled)
|
|
537
|
+
on(onFullscreenEnter)
|
|
538
|
+
on(onFullscreenExit)
|
|
246
539
|
}
|
|
247
540
|
}
|
|
248
541
|
|
|
@@ -264,6 +557,8 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
|
|
|
264
557
|
off(onPlaybackFinished)
|
|
265
558
|
off(onSeek)
|
|
266
559
|
off(onSeeked)
|
|
560
|
+
off(onStallStarted)
|
|
561
|
+
off(onStallEnded)
|
|
267
562
|
off(onTimeChanged)
|
|
268
563
|
off(onSourceLoad)
|
|
269
564
|
off(onSourceLoaded)
|
|
@@ -273,6 +568,27 @@ class RNPlayerView(context: ReactApplicationContext) : LinearLayout(context) {
|
|
|
273
568
|
off(onSubtitleAdded)
|
|
274
569
|
off(onSubtitleChanged)
|
|
275
570
|
off(onSubtitleRemoved)
|
|
571
|
+
off(onAdBreakFinished)
|
|
572
|
+
off(onAdBreakStarted)
|
|
573
|
+
off(onAdClicked)
|
|
574
|
+
off(onAdError)
|
|
575
|
+
off(onAdFinished)
|
|
576
|
+
off(onAdManifestLoad)
|
|
577
|
+
off(onAdManifestLoaded)
|
|
578
|
+
off(onAdQuartile)
|
|
579
|
+
off(onAdScheduled)
|
|
580
|
+
off(onAdSkipped)
|
|
581
|
+
off(onAdStarted)
|
|
582
|
+
off(onVideoPlaybackQualityChanged)
|
|
583
|
+
}
|
|
584
|
+
playerView?.apply {
|
|
585
|
+
off(onPictureInPictureAvailabilityChanged)
|
|
586
|
+
off(onPictureInPictureEnter)
|
|
587
|
+
off(onPictureInPictureExit)
|
|
588
|
+
off(onFullscreenEnabled)
|
|
589
|
+
off(onFullscreenDisabled)
|
|
590
|
+
off(onFullscreenEnter)
|
|
591
|
+
off(onFullscreenExit)
|
|
276
592
|
}
|
|
277
593
|
}
|
|
278
594
|
|