bitmovin-player-react-native 0.5.0 → 0.6.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 +4 -3
- package/RNBitmovinPlayer.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/bitmovin/player/reactnative/EventRelay.kt +47 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/PlayerModule.kt +46 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +74 -411
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +3 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +49 -6
- package/android/src/main/java/com/bitmovin/player/reactnative/extensions/Events.kt +3 -0
- package/ios/Event+JSON.swift +34 -0
- package/ios/PlayerModule.m +14 -0
- package/ios/PlayerModule.swift +62 -2
- package/ios/RCTConvert+BitmovinPlayer.swift +19 -3
- package/ios/RNPlayerView+PlayerListener.swift +12 -0
- package/ios/RNPlayerView.swift +3 -0
- package/ios/RNPlayerViewManager.m +3 -0
- package/lib/index.d.ts +86 -2
- package/lib/index.js +12 -0
- package/lib/index.mjs +12 -0
- package/package.json +3 -4
- package/src/audioTrack.ts +25 -0
- package/src/components/PlayerView/events.ts +6 -0
- package/src/components/PlayerView/index.tsx +4 -1
- package/src/drm/widevineConfig.ts +13 -1
- package/src/events.ts +35 -0
- package/src/index.ts +1 -0
- package/src/player.ts +22 -0
- package/src/ui/index.ts +1 -0
package/README.md
CHANGED
|
@@ -69,9 +69,10 @@ Features of the native mobile Player SDKs are progressively being implemented in
|
|
|
69
69
|
| Playback of DRM-protected assets | :white_check_mark: Available since v0.2.0 |
|
|
70
70
|
| Subtitles & Captions | :white_check_mark: Available since v0.2.0 |
|
|
71
71
|
| Advertising | :white_check_mark: Available since v0.4.0 |
|
|
72
|
+
| Analytics | :white_check_mark: Available since v0.5.0 |
|
|
72
73
|
| Playlist API | :x: Not available |
|
|
74
|
+
| Casting | :x: Not available |
|
|
73
75
|
| Offline Playback | :x: Not available |
|
|
74
|
-
| Analytics | :x: Coming Q1 2023 |
|
|
75
76
|
|
|
76
77
|
## Installation
|
|
77
78
|
|
|
@@ -460,9 +461,9 @@ const drmSource: SourceConfig = {
|
|
|
460
461
|
};
|
|
461
462
|
```
|
|
462
463
|
|
|
463
|
-
The [`FairplayConfig`](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm.ts
|
|
464
|
+
The [`FairplayConfig`](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm/fairplayConfig.ts) interface provides a bunch of hooks that can be used to fetch and transform different DRM related data. Check out the [docs]([https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm/fairplayConfig.ts](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm/fairplayConfig.ts)) for a complete list and detailed information on them.
|
|
464
465
|
|
|
465
|
-
Also, don't forget to check out the [example](https://github.com/bitmovin/bitmovin-player-react-native/tree/development/example) app for a complete iOS/Android [DRM example](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/example/src/screens/
|
|
466
|
+
Also, don't forget to check out the [example](https://github.com/bitmovin/bitmovin-player-react-native/tree/development/example) app for a complete iOS/Android [DRM example](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/example/src/screens/BasicDrmPlayback.tsx).
|
|
466
467
|
|
|
467
468
|
### Adding external subtitle tracks
|
|
468
469
|
|
package/RNBitmovinPlayer.podspec
CHANGED
|
@@ -19,7 +19,7 @@ Pod::Spec.new do |s|
|
|
|
19
19
|
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
20
20
|
|
|
21
21
|
s.dependency "React-Core"
|
|
22
|
-
s.dependency "BitmovinPlayer", "3.
|
|
22
|
+
s.dependency "BitmovinPlayer", "3.36.0"
|
|
23
23
|
s.dependency "BitmovinAnalyticsCollector/Core", "2.9.4"
|
|
24
24
|
s.dependency "BitmovinAnalyticsCollector/BitmovinPlayer", "2.9.4"
|
|
25
25
|
s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.17.0"
|
package/android/build.gradle
CHANGED
|
@@ -53,6 +53,6 @@ dependencies {
|
|
|
53
53
|
implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.26.0'
|
|
54
54
|
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
|
|
55
55
|
implementation 'com.bitmovin.analytics:collector-bitmovin-player:2.12.1'
|
|
56
|
-
implementation 'com.bitmovin.player:player:3.
|
|
56
|
+
implementation 'com.bitmovin.player:player:3.35.0'
|
|
57
57
|
implementation 'com.facebook.react:react-native:+'
|
|
58
58
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
package com.bitmovin.player.reactnative
|
|
2
|
+
|
|
3
|
+
import com.bitmovin.player.api.event.Event
|
|
4
|
+
import com.bitmovin.player.api.event.EventEmitter
|
|
5
|
+
import kotlin.reflect.KClass
|
|
6
|
+
|
|
7
|
+
private data class Subscription<E : Event>(
|
|
8
|
+
val eventClass: KClass<out E>,
|
|
9
|
+
val action: (E) -> Unit,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Attaches and detaches listener for the provided forwarding events on the current [EventEmitter] instance and
|
|
14
|
+
* relays the received events together with their associated name to the provided event output.
|
|
15
|
+
*/
|
|
16
|
+
class EventRelay<E : EventEmitter<T>, T : Event>(
|
|
17
|
+
/**
|
|
18
|
+
* List of events that should be relayed and their associated name.
|
|
19
|
+
*/
|
|
20
|
+
forwardingEventClassesAndNameMapping: Map<KClass<out T>, String>,
|
|
21
|
+
/**
|
|
22
|
+
* Is called for every relayed event together with its associated name.
|
|
23
|
+
*/
|
|
24
|
+
private val eventOutput: (String, Event) -> Unit
|
|
25
|
+
) {
|
|
26
|
+
private val eventListeners = forwardingEventClassesAndNameMapping.map {
|
|
27
|
+
Subscription(it.key) { event -> eventOutput(it.value, event) }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The [EventEmitter] for which the events are relayed.
|
|
32
|
+
*/
|
|
33
|
+
var eventEmitter: E? = null
|
|
34
|
+
set(value) {
|
|
35
|
+
field?.detachListeners(eventListeners)
|
|
36
|
+
field = value
|
|
37
|
+
value?.attachListeners(eventListeners)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private fun <T : Event, E : T> EventEmitter<T>.attachListeners(eventListener: List<Subscription<E>>) {
|
|
42
|
+
eventListener.forEach { on(it.eventClass, it.action) }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private fun <T : Event, E : T> EventEmitter<T>.detachListeners(eventListener: List<Subscription<E>>) {
|
|
46
|
+
eventListener.forEach { off(it.eventClass, it.action) }
|
|
47
|
+
}
|
|
@@ -261,6 +261,38 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
|
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Resolve `nativeId`'s player available audio tracks.
|
|
266
|
+
* @param nativeId Target player Id.
|
|
267
|
+
* @param promise JS promise object.
|
|
268
|
+
*/
|
|
269
|
+
@ReactMethod
|
|
270
|
+
fun getAvailableAudioTracks(nativeId: NativeId, promise: Promise) {
|
|
271
|
+
uiManager()?.addUIBlock {
|
|
272
|
+
val audioTracks = Arguments.createArray()
|
|
273
|
+
players[nativeId]?.source?.availableAudioTracks?.let { tracks ->
|
|
274
|
+
tracks.forEach {
|
|
275
|
+
audioTracks.pushMap(JsonConverter.fromAudioTrack(it))
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
promise.resolve(audioTracks)
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Set `nativeId`'s player audio track.
|
|
284
|
+
* @param nativeId Target player Id.
|
|
285
|
+
* @param trackIdentifier The audio track identifier.
|
|
286
|
+
* @param promise JS promise object.
|
|
287
|
+
*/
|
|
288
|
+
@ReactMethod
|
|
289
|
+
fun setAudioTrack(nativeId: NativeId, trackIdentifier: String, promise: Promise) {
|
|
290
|
+
uiManager()?.addUIBlock {
|
|
291
|
+
players[nativeId]?.source?.setAudioTrack(trackIdentifier)
|
|
292
|
+
promise.resolve(null)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
264
296
|
/**
|
|
265
297
|
* Resolve `nativeId`'s player available subtitle tracks.
|
|
266
298
|
* @param nativeId Target player Id.
|
|
@@ -279,6 +311,20 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
|
|
|
279
311
|
}
|
|
280
312
|
}
|
|
281
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Set `nativeId`'s player subtitle track.
|
|
316
|
+
* @param nativeId Target player Id.
|
|
317
|
+
* @param trackIdentifier The subtitle track identifier.
|
|
318
|
+
* @param promise JS promise object.
|
|
319
|
+
*/
|
|
320
|
+
@ReactMethod
|
|
321
|
+
fun setSubtitleTrack(nativeId: NativeId, trackIdentifier: String?, promise: Promise) {
|
|
322
|
+
uiManager()?.addUIBlock {
|
|
323
|
+
players[nativeId]?.source?.setSubtitleTrack(trackIdentifier)
|
|
324
|
+
promise.resolve(null)
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
282
328
|
/**
|
|
283
329
|
* Schedules an `AdItem` in the `nativeId`'s associated player.
|
|
284
330
|
* @param nativeId Target player id.
|
|
@@ -11,7 +11,6 @@ import com.bitmovin.player.api.Player
|
|
|
11
11
|
import com.bitmovin.player.api.event.Event
|
|
12
12
|
import com.bitmovin.player.api.event.PlayerEvent
|
|
13
13
|
import com.bitmovin.player.api.event.SourceEvent
|
|
14
|
-
import com.bitmovin.player.api.event.on
|
|
15
14
|
import com.bitmovin.player.reactnative.converter.JsonConverter
|
|
16
15
|
import com.bitmovin.player.reactnative.ui.RNPictureInPictureDelegate
|
|
17
16
|
import com.bitmovin.player.reactnative.ui.RNPictureInPictureHandler
|
|
@@ -19,6 +18,59 @@ import com.facebook.react.bridge.LifecycleEventListener
|
|
|
19
18
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
20
19
|
import com.facebook.react.bridge.ReactContext
|
|
21
20
|
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
21
|
+
import kotlin.reflect.KClass
|
|
22
|
+
|
|
23
|
+
private val EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING = mapOf(
|
|
24
|
+
PlayerEvent::class to "event",
|
|
25
|
+
PlayerEvent.Error::class to "playerError",
|
|
26
|
+
PlayerEvent.Warning::class to "playerWarning",
|
|
27
|
+
PlayerEvent.Destroy::class to "destroy",
|
|
28
|
+
PlayerEvent.Muted::class to "muted",
|
|
29
|
+
PlayerEvent.Unmuted::class to "unmuted",
|
|
30
|
+
PlayerEvent.Ready::class to "ready",
|
|
31
|
+
PlayerEvent.Paused::class to "paused",
|
|
32
|
+
PlayerEvent.Play::class to "play",
|
|
33
|
+
PlayerEvent.Playing::class to "playing",
|
|
34
|
+
PlayerEvent.PlaybackFinished::class to "playbackFinished",
|
|
35
|
+
PlayerEvent.Seek::class to "seek",
|
|
36
|
+
PlayerEvent.Seeked::class to "seeked",
|
|
37
|
+
PlayerEvent.StallStarted::class to "stallStarted",
|
|
38
|
+
PlayerEvent.StallEnded::class to "stallEnded",
|
|
39
|
+
PlayerEvent.TimeChanged::class to "timeChanged",
|
|
40
|
+
SourceEvent.Load::class to "sourceLoad",
|
|
41
|
+
SourceEvent.Loaded::class to "sourceLoaded",
|
|
42
|
+
SourceEvent.Unloaded::class to "sourceUnloaded",
|
|
43
|
+
SourceEvent.Error::class to "sourceError",
|
|
44
|
+
SourceEvent.Warning::class to "sourceWarning",
|
|
45
|
+
SourceEvent.SubtitleTrackAdded::class to "subtitleAdded",
|
|
46
|
+
SourceEvent.SubtitleTrackChanged::class to "subtitleChanged",
|
|
47
|
+
SourceEvent.SubtitleTrackRemoved::class to "subtitleRemoved",
|
|
48
|
+
SourceEvent.AudioTrackAdded::class to "audioAdded",
|
|
49
|
+
SourceEvent.AudioTrackChanged::class to "audioChanged",
|
|
50
|
+
SourceEvent.AudioTrackRemoved::class to "audioRemoved",
|
|
51
|
+
PlayerEvent.AdBreakFinished::class to "adBreakFinished",
|
|
52
|
+
PlayerEvent.AdBreakStarted::class to "adBreakStarted",
|
|
53
|
+
PlayerEvent.AdClicked::class to "adClicked",
|
|
54
|
+
PlayerEvent.AdError::class to "adError",
|
|
55
|
+
PlayerEvent.AdFinished::class to "adFinished",
|
|
56
|
+
PlayerEvent.AdManifestLoad::class to "adManifestLoad",
|
|
57
|
+
PlayerEvent.AdManifestLoaded::class to "adManifestLoaded",
|
|
58
|
+
PlayerEvent.AdQuartile::class to "adQuartile",
|
|
59
|
+
PlayerEvent.AdScheduled::class to "adScheduled",
|
|
60
|
+
PlayerEvent.AdSkipped::class to "adSkipped",
|
|
61
|
+
PlayerEvent.AdStarted::class to "adStarted",
|
|
62
|
+
PlayerEvent.VideoPlaybackQualityChanged::class to "videoPlaybackQualityChanged",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
private val EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING_UI = mapOf<KClass<out Event>, String>(
|
|
66
|
+
PlayerEvent.PictureInPictureAvailabilityChanged::class to "pictureInPictureAvailabilityChanged",
|
|
67
|
+
PlayerEvent.PictureInPictureEnter::class to "pictureInPictureEnter",
|
|
68
|
+
PlayerEvent.PictureInPictureExit::class to "pictureInPictureExit",
|
|
69
|
+
PlayerEvent.FullscreenEnabled::class to "fullscreenEnabled",
|
|
70
|
+
PlayerEvent.FullscreenDisabled::class to "fullscreenDisabled",
|
|
71
|
+
PlayerEvent.FullscreenEnter::class to "fullscreenEnter",
|
|
72
|
+
PlayerEvent.FullscreenExit::class to "fullscreenExit",
|
|
73
|
+
)
|
|
22
74
|
|
|
23
75
|
/**
|
|
24
76
|
* Native view wrapper for component instances. It both serves as the main view
|
|
@@ -28,10 +80,26 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
|
28
80
|
@SuppressLint("ViewConstructor")
|
|
29
81
|
class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context),
|
|
30
82
|
LifecycleEventListener, View.OnLayoutChangeListener, RNPictureInPictureDelegate {
|
|
83
|
+
/**
|
|
84
|
+
* Relays the provided set of events, emitted by the player, together with the associated name
|
|
85
|
+
* to the `eventOutput` callback.
|
|
86
|
+
*/
|
|
87
|
+
private val playerEventRelay = EventRelay<Player, Event>(EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING, ::emitEvent)
|
|
88
|
+
/**
|
|
89
|
+
* Relays the provided set of events, emitted by the player view, together with the associated name
|
|
90
|
+
* to the `eventOutput` callback.
|
|
91
|
+
*/
|
|
92
|
+
private val viewEventRelay = EventRelay<PlayerView, Event>(EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING_UI, ::emitEvent)
|
|
93
|
+
|
|
31
94
|
/**
|
|
32
95
|
* Associated bitmovin's `PlayerView`.
|
|
33
96
|
*/
|
|
34
97
|
var playerView: PlayerView? = null
|
|
98
|
+
set(value) {
|
|
99
|
+
field = value
|
|
100
|
+
viewEventRelay.eventEmitter = field
|
|
101
|
+
playerEventRelay.eventEmitter = field?.player
|
|
102
|
+
}
|
|
35
103
|
|
|
36
104
|
/**
|
|
37
105
|
* Handy property accessor for `playerView`'s player instance.
|
|
@@ -40,6 +108,7 @@ class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context)
|
|
|
40
108
|
get() = playerView?.player
|
|
41
109
|
set(value) {
|
|
42
110
|
playerView?.player = value
|
|
111
|
+
playerEventRelay.eventEmitter = value
|
|
43
112
|
}
|
|
44
113
|
|
|
45
114
|
/**
|
|
@@ -64,7 +133,8 @@ class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context)
|
|
|
64
133
|
* Cleans up the resources and listeners produced by this view.
|
|
65
134
|
*/
|
|
66
135
|
fun dispose() {
|
|
67
|
-
|
|
136
|
+
viewEventRelay.eventEmitter = null
|
|
137
|
+
playerEventRelay.eventEmitter = null
|
|
68
138
|
context.removeLifecycleEventListener(this)
|
|
69
139
|
playerView?.removeOnLayoutChangeListener(this)
|
|
70
140
|
}
|
|
@@ -102,7 +172,6 @@ class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context)
|
|
|
102
172
|
if (playerView.parent != this) {
|
|
103
173
|
(playerView.parent as ViewGroup?)?.removeView(playerView)
|
|
104
174
|
addView(playerView)
|
|
105
|
-
startBubblingEvents()
|
|
106
175
|
}
|
|
107
176
|
pictureInPictureHandler?.let {
|
|
108
177
|
it.setDelegate(this)
|
|
@@ -180,418 +249,12 @@ class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context)
|
|
|
180
249
|
post {
|
|
181
250
|
measure(
|
|
182
251
|
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
|
183
|
-
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
|
|
252
|
+
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
|
|
253
|
+
)
|
|
184
254
|
layout(left, top, right, bottom)
|
|
185
255
|
}
|
|
186
256
|
}
|
|
187
257
|
|
|
188
|
-
/**
|
|
189
|
-
* `onEvent` event callback.
|
|
190
|
-
*/
|
|
191
|
-
private val onEvent: (PlayerEvent) -> Unit = {
|
|
192
|
-
emitEvent("event", it)
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* `onPlayerError` event callback.
|
|
197
|
-
*/
|
|
198
|
-
private val onPlayerError: (PlayerEvent.Error) -> Unit = {
|
|
199
|
-
emitEvent("playerError", it)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* `onPlayerWarning` event callback.
|
|
204
|
-
*/
|
|
205
|
-
private val onPlayerWarning: (PlayerEvent.Warning) -> Unit = {
|
|
206
|
-
emitEvent("playerWarning", it)
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* `onDestroy` event callback.
|
|
211
|
-
*/
|
|
212
|
-
private val onDestroy: (PlayerEvent.Destroy) -> Unit = {
|
|
213
|
-
emitEvent("destroy", it)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* `onMuted` event callback.
|
|
218
|
-
*/
|
|
219
|
-
private val onMuted: (PlayerEvent.Muted) -> Unit = {
|
|
220
|
-
emitEvent("muted", it)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* `onUnmuted` event callback.
|
|
225
|
-
*/
|
|
226
|
-
private val onUnmuted: (PlayerEvent.Unmuted) -> Unit = {
|
|
227
|
-
emitEvent("unmuted", it)
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* `onReady` event callback.
|
|
232
|
-
*/
|
|
233
|
-
private val onReady: (PlayerEvent.Ready) -> Unit = {
|
|
234
|
-
emitEvent("ready", it)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* `onPaused` event callback.
|
|
239
|
-
*/
|
|
240
|
-
private val onPaused: (PlayerEvent.Paused) -> Unit = {
|
|
241
|
-
emitEvent("paused", it)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* `onPlay` event callback.
|
|
246
|
-
*/
|
|
247
|
-
private val onPlay: (PlayerEvent.Play) -> Unit = {
|
|
248
|
-
emitEvent("play", it)
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* `onPlaying` event callback.
|
|
253
|
-
*/
|
|
254
|
-
private val onPlaying: (PlayerEvent.Playing) -> Unit = {
|
|
255
|
-
emitEvent("playing", it)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* `onPlaybackFinished` event callback.
|
|
260
|
-
*/
|
|
261
|
-
private val onPlaybackFinished: (PlayerEvent.PlaybackFinished) -> Unit = {
|
|
262
|
-
emitEvent("playbackFinished", it)
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* `onSeek` event callback.
|
|
267
|
-
*/
|
|
268
|
-
private val onSeek: (PlayerEvent.Seek) -> Unit = {
|
|
269
|
-
emitEvent("seek", it)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* `onSeeked` event callback.
|
|
274
|
-
*/
|
|
275
|
-
private val onSeeked: (PlayerEvent.Seeked) -> Unit = {
|
|
276
|
-
emitEvent("seeked", it)
|
|
277
|
-
}
|
|
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
|
-
|
|
293
|
-
/**
|
|
294
|
-
* `onTimeChanged` event callback.
|
|
295
|
-
*/
|
|
296
|
-
private val onTimeChanged: (PlayerEvent.TimeChanged) -> Unit = {
|
|
297
|
-
emitEvent("timeChanged", it)
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* `onSourceLoad` event callback.
|
|
302
|
-
*/
|
|
303
|
-
private val onSourceLoad: (SourceEvent.Load) -> Unit = {
|
|
304
|
-
emitEvent("sourceLoad", it)
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* `onSourceLoaded` event callback.
|
|
309
|
-
*/
|
|
310
|
-
private val onSourceLoaded: (SourceEvent.Loaded) -> Unit = {
|
|
311
|
-
emitEvent("sourceLoaded", it)
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* `onSourceUnloaded` event callback.
|
|
316
|
-
*/
|
|
317
|
-
private val onSourceUnloaded: (SourceEvent.Unloaded) -> Unit = {
|
|
318
|
-
emitEvent("sourceUnloaded", it)
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* `onSourceError` event callback.
|
|
323
|
-
*/
|
|
324
|
-
private val onSourceError: (SourceEvent.Error) -> Unit = {
|
|
325
|
-
emitEvent("sourceError", it)
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* `onSourceWarning` event callback.
|
|
330
|
-
*/
|
|
331
|
-
private val onSourceWarning: (SourceEvent.Warning) -> Unit = {
|
|
332
|
-
emitEvent("sourceWarning", it)
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* `onSubtitleAdded` event callback.
|
|
337
|
-
*/
|
|
338
|
-
private val onSubtitleAdded: (SourceEvent.SubtitleTrackAdded) -> Unit = {
|
|
339
|
-
emitEvent("subtitleAdded", it)
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* `onSubtitleChanged` event callback.
|
|
344
|
-
*/
|
|
345
|
-
private val onSubtitleChanged: (SourceEvent.SubtitleTrackChanged) -> Unit = {
|
|
346
|
-
emitEvent("subtitleChanged", it)
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**
|
|
350
|
-
* `onSubtitleRemoved` event callback.
|
|
351
|
-
*/
|
|
352
|
-
private val onSubtitleRemoved: (SourceEvent.SubtitleTrackRemoved) -> Unit = {
|
|
353
|
-
emitEvent("subtitleRemoved", it)
|
|
354
|
-
}
|
|
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
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Start listening and emitting player events as bubbling events to the js side.
|
|
491
|
-
*/
|
|
492
|
-
fun startBubblingEvents() {
|
|
493
|
-
player?.apply {
|
|
494
|
-
on(onEvent)
|
|
495
|
-
on(onPlayerError)
|
|
496
|
-
on(onPlayerWarning)
|
|
497
|
-
on(onDestroy)
|
|
498
|
-
on(onMuted)
|
|
499
|
-
on(onUnmuted)
|
|
500
|
-
on(onReady)
|
|
501
|
-
on(onPaused)
|
|
502
|
-
on(onPlay)
|
|
503
|
-
on(onPlaying)
|
|
504
|
-
on(onPlaybackFinished)
|
|
505
|
-
on(onSeek)
|
|
506
|
-
on(onSeeked)
|
|
507
|
-
on(onStallStarted)
|
|
508
|
-
on(onStallEnded)
|
|
509
|
-
on(onTimeChanged)
|
|
510
|
-
on(onSourceLoad)
|
|
511
|
-
on(onSourceLoaded)
|
|
512
|
-
on(onSourceUnloaded)
|
|
513
|
-
on(onSourceError)
|
|
514
|
-
on(onSourceWarning)
|
|
515
|
-
on(onSubtitleAdded)
|
|
516
|
-
on(onSubtitleChanged)
|
|
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)
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Stop listening for player events and cease to emit bubbling events.
|
|
544
|
-
*/
|
|
545
|
-
fun stopBubblingEvents() {
|
|
546
|
-
player?.apply {
|
|
547
|
-
off(onEvent)
|
|
548
|
-
off(onPlayerError)
|
|
549
|
-
off(onPlayerWarning)
|
|
550
|
-
off(onDestroy)
|
|
551
|
-
off(onMuted)
|
|
552
|
-
off(onUnmuted)
|
|
553
|
-
off(onReady)
|
|
554
|
-
off(onPaused)
|
|
555
|
-
off(onPlay)
|
|
556
|
-
off(onPlaying)
|
|
557
|
-
off(onPlaybackFinished)
|
|
558
|
-
off(onSeek)
|
|
559
|
-
off(onSeeked)
|
|
560
|
-
off(onStallStarted)
|
|
561
|
-
off(onStallEnded)
|
|
562
|
-
off(onTimeChanged)
|
|
563
|
-
off(onSourceLoad)
|
|
564
|
-
off(onSourceLoaded)
|
|
565
|
-
off(onSourceUnloaded)
|
|
566
|
-
off(onSourceError)
|
|
567
|
-
off(onSourceWarning)
|
|
568
|
-
off(onSubtitleAdded)
|
|
569
|
-
off(onSubtitleChanged)
|
|
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)
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
|
|
595
258
|
/**
|
|
596
259
|
* Emits a bubbling event with payload to js.
|
|
597
260
|
* @param event Native event name.
|
|
@@ -78,6 +78,9 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
|
|
|
78
78
|
"sourceUnloaded" to "onSourceUnloaded",
|
|
79
79
|
"sourceError" to "onSourceError",
|
|
80
80
|
"sourceWarning" to "onSourceWarning",
|
|
81
|
+
"audioAdded" to "onAudioAdded",
|
|
82
|
+
"audioChanged" to "onAudioChanged",
|
|
83
|
+
"audioRemoved" to "onAudioRemoved",
|
|
81
84
|
"subtitleAdded" to "onSubtitleAdded",
|
|
82
85
|
"subtitleChanged" to "onSubtitleChanged",
|
|
83
86
|
"subtitleRemoved" to "onSubtitleRemoved",
|