react-native-theoplayer 1.7.2 → 1.8.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 +2 -0
- package/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +115 -0
- package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +648 -0
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.kt +23 -0
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt +446 -0
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.kt +117 -0
- package/android/src/main/java/com/theoplayer/{TimeUpdateRate.java → TimeUpdateRate.kt} +2 -2
- package/android/src/main/java/com/theoplayer/ads/AdAdapter.kt +161 -0
- package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.kt +90 -0
- package/android/src/main/java/com/theoplayer/ads/AdsModule.kt +140 -0
- package/android/src/main/java/com/theoplayer/cast/CastEventAdapter.kt +81 -0
- package/android/src/main/java/com/theoplayer/cast/CastModule.kt +75 -0
- package/android/src/main/java/com/theoplayer/drm/ContentProtectionAdapter.kt +2 -2
- package/android/src/main/java/com/theoplayer/drm/ContentProtectionModule.kt +1 -2
- package/android/src/main/java/com/theoplayer/drm/ProxyContentProtectionIntegration.kt +1 -2
- package/android/src/main/java/com/theoplayer/drm/ProxyContentProtectionIntegrationFactory.kt +3 -5
- package/android/src/main/java/com/theoplayer/source/SourceAdapter.kt +402 -0
- package/android/src/main/java/com/theoplayer/track/MediaTrackEventType.kt +6 -0
- package/android/src/main/java/com/theoplayer/track/MediaTrackType.kt +6 -0
- package/android/src/main/java/com/theoplayer/track/QualityListAdapter.kt +43 -0
- package/android/src/main/java/com/theoplayer/track/QualityListFilter.kt +28 -0
- package/android/src/main/java/com/theoplayer/track/TextTrackCueEventType.kt +10 -0
- package/android/src/main/java/com/theoplayer/track/TrackEventType.kt +7 -0
- package/android/src/main/java/com/theoplayer/track/TrackListAdapter.kt +219 -0
- package/android/src/main/java/com/theoplayer/util/ViewResolver.kt +19 -0
- package/ios/THEOplayerRCTAdAggregator.swift +12 -6
- package/ios/THEOplayerRCTAdsAPI.swift +39 -40
- package/ios/THEOplayerRCTBridge.m +52 -1
- package/ios/THEOplayerRCTCastAPI.swift +275 -0
- package/ios/THEOplayerRCTDebug.swift +3 -0
- package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +91 -19
- package/ios/{THEOplayerRCTMetadataAggregator.swift → THEOplayerRCTTrackMetadataAggregator.swift} +12 -12
- package/ios/THEOplayerRCTView.swift +104 -24
- package/ios/THEOplayerRCTViewAdEventHandler.swift +2 -2
- package/ios/THEOplayerRCTViewCastEventHandler.swift +124 -0
- package/ios/THEOplayerRCTViewMainEventHandler.swift +1 -1
- package/ios/THEOplayerRCTViewMediaTrackEventHandler.swift +6 -6
- package/ios/THEOplayerRCTViewTextTrackEventHandler.swift +5 -5
- package/ios/custom/Frameworks/ios/put_custom_ios_xcframework_here.txt +1 -1
- package/ios/custom/Frameworks/tvos/put_custom_tvos_xcframework_here.txt +2 -0
- package/ios/custom/react-native-theoplayer_custom.podspec +46 -0
- package/lib/commonjs/api/THEOplayerView.js.map +1 -1
- package/lib/commonjs/api/barrel.js +21 -8
- package/lib/commonjs/api/barrel.js.map +1 -1
- package/lib/commonjs/api/cast/Airplay.js +6 -0
- package/lib/commonjs/api/cast/Airplay.js.map +1 -0
- package/lib/commonjs/api/cast/CastAPI.js +6 -0
- package/lib/commonjs/api/cast/CastAPI.js.map +1 -0
- package/lib/commonjs/api/cast/CastConfiguration.js +2 -0
- package/lib/commonjs/api/cast/CastConfiguration.js.map +1 -0
- package/lib/commonjs/api/cast/CastState.js +2 -0
- package/lib/commonjs/api/cast/CastState.js.map +1 -0
- package/lib/commonjs/api/cast/Chromecast.js +6 -0
- package/lib/commonjs/api/cast/Chromecast.js.map +1 -0
- package/lib/commonjs/api/cast/barrel.js +71 -0
- package/lib/commonjs/api/cast/barrel.js.map +1 -0
- package/lib/commonjs/api/config/PlayerConfiguration.js.map +1 -1
- package/lib/commonjs/api/error/ChromecastError.js +2 -0
- package/lib/commonjs/api/error/ChromecastError.js.map +1 -0
- package/lib/commonjs/api/error/barrel.js +13 -0
- package/lib/commonjs/api/error/barrel.js.map +1 -1
- package/lib/commonjs/api/event/CastEvent.js +21 -0
- package/lib/commonjs/api/event/CastEvent.js.map +1 -0
- package/lib/commonjs/api/event/barrel.js +25 -12
- package/lib/commonjs/api/event/barrel.js.map +1 -1
- package/lib/commonjs/api/source/SourceDescription.js.map +1 -1
- package/lib/commonjs/api/source/barrel.js +13 -0
- package/lib/commonjs/api/source/barrel.js.map +1 -1
- package/lib/commonjs/api/source/metadata/MetadataDescription.js +2 -0
- package/lib/commonjs/api/source/metadata/MetadataDescription.js.map +1 -0
- package/lib/commonjs/api/source/metadata/barrel.js +19 -0
- package/lib/commonjs/api/source/metadata/barrel.js.map +1 -0
- package/lib/commonjs/internal/THEOplayerView.js +16 -0
- package/lib/commonjs/internal/THEOplayerView.js.map +1 -1
- package/lib/commonjs/internal/THEOplayerView.web.js +9 -0
- package/lib/commonjs/internal/THEOplayerView.web.js.map +1 -1
- package/lib/commonjs/internal/cast/THEOplayerNativeAirplay.js +34 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeAirplay.js.map +1 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeCastApi.js +46 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeCastApi.js.map +1 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeChromecast.js +42 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeChromecast.js.map +1 -0
- package/lib/commonjs/internal/cast/THEOplayerWebCastApi.js +31 -0
- package/lib/commonjs/internal/cast/THEOplayerWebCastApi.js.map +1 -0
- package/lib/commonjs/internal/web/stub/CastButtonStub.js +16 -0
- package/lib/commonjs/internal/web/stub/CastButtonStub.js.map +1 -0
- package/lib/module/api/THEOplayerView.js.map +1 -1
- package/lib/module/api/barrel.js +1 -0
- package/lib/module/api/barrel.js.map +1 -1
- package/lib/module/api/cast/Airplay.js +2 -0
- package/lib/module/api/cast/Airplay.js.map +1 -0
- package/lib/module/api/cast/CastAPI.js +2 -0
- package/lib/module/api/cast/CastAPI.js.map +1 -0
- package/lib/module/api/cast/CastConfiguration.js +2 -0
- package/lib/module/api/cast/CastConfiguration.js.map +1 -0
- package/lib/module/api/cast/CastState.js +2 -0
- package/lib/module/api/cast/CastState.js.map +1 -0
- package/lib/module/api/cast/Chromecast.js +2 -0
- package/lib/module/api/cast/Chromecast.js.map +1 -0
- package/lib/module/api/cast/barrel.js +6 -0
- package/lib/module/api/cast/barrel.js.map +1 -0
- package/lib/module/api/config/PlayerConfiguration.js.map +1 -1
- package/lib/module/api/error/ChromecastError.js +2 -0
- package/lib/module/api/error/ChromecastError.js.map +1 -0
- package/lib/module/api/error/barrel.js +1 -0
- package/lib/module/api/error/barrel.js.map +1 -1
- package/lib/module/api/event/CastEvent.js +14 -0
- package/lib/module/api/event/CastEvent.js.map +1 -0
- package/lib/module/api/event/barrel.js +2 -1
- package/lib/module/api/event/barrel.js.map +1 -1
- package/lib/module/api/source/SourceDescription.js.map +1 -1
- package/lib/module/api/source/barrel.js +1 -0
- package/lib/module/api/source/barrel.js.map +1 -1
- package/lib/module/api/source/metadata/MetadataDescription.js +2 -0
- package/lib/module/api/source/metadata/MetadataDescription.js.map +1 -0
- package/lib/module/api/source/metadata/barrel.js +2 -0
- package/lib/module/api/source/metadata/barrel.js.map +1 -0
- package/lib/module/internal/THEOplayerView.js +15 -0
- package/lib/module/internal/THEOplayerView.js.map +1 -1
- package/lib/module/internal/THEOplayerView.web.js +8 -0
- package/lib/module/internal/THEOplayerView.web.js.map +1 -1
- package/lib/module/internal/cast/THEOplayerNativeAirplay.js +24 -0
- package/lib/module/internal/cast/THEOplayerNativeAirplay.js.map +1 -0
- package/lib/module/internal/cast/THEOplayerNativeCastApi.js +34 -0
- package/lib/module/internal/cast/THEOplayerNativeCastApi.js.map +1 -0
- package/lib/module/internal/cast/THEOplayerNativeChromecast.js +32 -0
- package/lib/module/internal/cast/THEOplayerNativeChromecast.js.map +1 -0
- package/lib/module/internal/cast/THEOplayerWebCastApi.js +22 -0
- package/lib/module/internal/cast/THEOplayerWebCastApi.js.map +1 -0
- package/lib/module/internal/web/stub/CastButtonStub.js +6 -0
- package/lib/module/internal/web/stub/CastButtonStub.js.map +1 -0
- package/lib/typescript/lib/commonjs/api/cast/Airplay.d.ts +1 -0
- package/lib/typescript/lib/commonjs/api/cast/CastAPI.d.ts +1 -0
- package/lib/typescript/lib/commonjs/api/cast/CastConfiguration.d.ts +0 -0
- package/lib/typescript/lib/commonjs/api/cast/CastState.d.ts +0 -0
- package/lib/typescript/lib/commonjs/api/cast/Chromecast.d.ts +1 -0
- package/lib/typescript/lib/commonjs/api/cast/barrel.d.ts +1 -0
- package/lib/typescript/lib/commonjs/api/error/ChromecastError.d.ts +0 -0
- package/lib/typescript/lib/commonjs/api/event/CastEvent.d.ts +2 -0
- package/lib/typescript/lib/commonjs/api/source/metadata/MetadataDescription.d.ts +0 -0
- package/lib/typescript/lib/commonjs/api/source/metadata/barrel.d.ts +1 -0
- package/lib/typescript/lib/commonjs/internal/THEOplayerView.d.ts +3 -0
- package/lib/typescript/lib/commonjs/internal/THEOplayerView.web.d.ts +3 -0
- package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeAirplay.d.ts +9 -0
- package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeCastApi.d.ts +12 -0
- package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeChromecast.d.ts +11 -0
- package/lib/typescript/lib/commonjs/internal/cast/THEOplayerWebCastApi.d.ts +8 -0
- package/lib/typescript/lib/commonjs/internal/web/stub/CastButtonStub.d.ts +2 -0
- package/lib/typescript/lib/module/api/barrel.d.ts +1 -0
- package/lib/typescript/lib/module/api/cast/Airplay.d.ts +1 -0
- package/lib/typescript/lib/module/api/cast/CastAPI.d.ts +1 -0
- package/lib/typescript/lib/module/api/cast/CastConfiguration.d.ts +0 -0
- package/lib/typescript/lib/module/api/cast/CastState.d.ts +0 -0
- package/lib/typescript/lib/module/api/cast/Chromecast.d.ts +1 -0
- package/lib/typescript/lib/module/api/cast/barrel.d.ts +3 -0
- package/lib/typescript/lib/module/api/error/ChromecastError.d.ts +0 -0
- package/lib/typescript/lib/module/api/event/CastEvent.d.ts +1 -0
- package/lib/typescript/lib/module/api/event/barrel.d.ts +2 -1
- package/lib/typescript/lib/module/api/source/barrel.d.ts +1 -0
- package/lib/typescript/lib/module/api/source/metadata/MetadataDescription.d.ts +0 -0
- package/lib/typescript/lib/module/api/source/metadata/barrel.d.ts +1 -0
- package/lib/typescript/lib/module/internal/THEOplayerView.d.ts +3 -0
- package/lib/typescript/lib/module/internal/THEOplayerView.web.d.ts +3 -0
- package/lib/typescript/lib/module/internal/cast/THEOplayerNativeAirplay.d.ts +8 -0
- package/lib/typescript/lib/module/internal/cast/THEOplayerNativeCastApi.d.ts +11 -0
- package/lib/typescript/lib/module/internal/cast/THEOplayerNativeChromecast.d.ts +10 -0
- package/lib/typescript/lib/module/internal/cast/THEOplayerWebCastApi.d.ts +7 -0
- package/lib/typescript/lib/module/internal/web/stub/CastButtonStub.d.ts +2 -0
- package/lib/typescript/src/api/THEOplayerView.d.ts +10 -0
- package/lib/typescript/src/api/barrel.d.ts +1 -0
- package/lib/typescript/src/api/cast/Airplay.d.ts +27 -0
- package/lib/typescript/src/api/cast/CastAPI.d.ts +25 -0
- package/lib/typescript/src/api/cast/CastConfiguration.d.ts +41 -0
- package/lib/typescript/src/api/cast/CastState.d.ts +10 -0
- package/lib/typescript/src/api/cast/Chromecast.d.ts +39 -0
- package/lib/typescript/src/api/cast/barrel.d.ts +5 -0
- package/lib/typescript/src/api/config/PlayerConfiguration.d.ts +6 -1
- package/lib/typescript/src/api/error/ChromecastError.d.ts +34 -0
- package/lib/typescript/src/api/error/barrel.d.ts +1 -0
- package/lib/typescript/src/api/event/CastEvent.d.ts +21 -0
- package/lib/typescript/src/api/event/barrel.d.ts +2 -1
- package/lib/typescript/src/api/source/SourceDescription.d.ts +7 -0
- package/lib/typescript/src/api/source/barrel.d.ts +1 -0
- package/lib/typescript/src/api/source/metadata/MetadataDescription.d.ts +12 -0
- package/lib/typescript/src/api/source/metadata/barrel.d.ts +1 -0
- package/lib/typescript/src/internal/THEOplayerView.d.ts +5 -1
- package/lib/typescript/src/internal/THEOplayerView.web.d.ts +3 -1
- package/lib/typescript/src/internal/cast/THEOplayerNativeAirplay.d.ts +9 -0
- package/lib/typescript/src/internal/cast/THEOplayerNativeCastApi.d.ts +10 -0
- package/lib/typescript/src/internal/cast/THEOplayerNativeChromecast.d.ts +11 -0
- package/lib/typescript/src/internal/cast/THEOplayerWebCastApi.d.ts +9 -0
- package/lib/typescript/src/internal/web/stub/CastButtonStub.d.ts +3 -0
- package/package.json +2 -2
- package/react-native-theoplayer.podspec +2 -2
- package/src/api/THEOplayerView.ts +12 -0
- package/src/api/barrel.ts +1 -0
- package/src/api/cast/Airplay.ts +31 -0
- package/src/api/cast/CastAPI.ts +30 -0
- package/src/api/cast/CastConfiguration.ts +44 -0
- package/src/api/cast/CastState.ts +10 -0
- package/src/api/cast/Chromecast.ts +45 -0
- package/src/api/cast/barrel.ts +5 -0
- package/src/api/config/PlayerConfiguration.ts +7 -1
- package/src/api/error/ChromecastError.ts +46 -0
- package/src/api/error/barrel.ts +1 -0
- package/src/api/event/CastEvent.ts +45 -0
- package/src/api/event/barrel.ts +2 -1
- package/src/api/source/SourceDescription.ts +8 -0
- package/src/api/source/barrel.ts +1 -0
- package/src/api/source/metadata/MetadataDescription.ts +13 -0
- package/src/api/source/metadata/barrel.ts +1 -0
- package/src/internal/THEOplayerView.tsx +17 -0
- package/src/internal/THEOplayerView.web.tsx +8 -1
- package/src/internal/cast/THEOplayerNativeAirplay.ts +22 -0
- package/src/internal/cast/THEOplayerNativeCastApi.ts +28 -0
- package/src/internal/cast/THEOplayerNativeChromecast.ts +30 -0
- package/src/internal/cast/THEOplayerWebCastApi.ts +21 -0
- package/src/internal/web/stub/CastButtonStub.tsx +7 -0
- package/android/src/main/java/com/theoplayer/PlayerConfigHelper.java +0 -70
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.java +0 -32
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.java +0 -525
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.java +0 -127
- package/android/src/main/java/com/theoplayer/SourceHelper.java +0 -362
- package/android/src/main/java/com/theoplayer/VideoEventEmitter.java +0 -578
- package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.java +0 -92
- package/android/src/main/java/com/theoplayer/ads/AdInfo.java +0 -168
- package/android/src/main/java/com/theoplayer/ads/AdsModule.java +0 -152
- package/android/src/main/java/com/theoplayer/track/MediaTrackEventType.java +0 -11
- package/android/src/main/java/com/theoplayer/track/MediaTrackType.java +0 -11
- package/android/src/main/java/com/theoplayer/track/QualityListAdapter.java +0 -54
- package/android/src/main/java/com/theoplayer/track/QualityListFilter.java +0 -40
- package/android/src/main/java/com/theoplayer/track/TextTrackCueEventType.java +0 -11
- package/android/src/main/java/com/theoplayer/track/TrackEventType.java +0 -12
- package/android/src/main/java/com/theoplayer/track/TrackListInfo.java +0 -234
- package/android/src/main/java/com/theoplayer/util/ViewResolver.java +0 -42
- package/ios/custom/react-native-theoplayer_custom_ios.podspec +0 -36
|
@@ -0,0 +1,648 @@
|
|
|
1
|
+
package com.theoplayer
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import android.view.View
|
|
5
|
+
import androidx.annotation.StringDef
|
|
6
|
+
import com.facebook.react.bridge.Arguments
|
|
7
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
+
import com.facebook.react.bridge.WritableMap
|
|
9
|
+
import com.facebook.react.uimanager.events.ReactEventEmitter
|
|
10
|
+
import com.theoplayer.ads.AdEventAdapter
|
|
11
|
+
import com.theoplayer.ads.AdEventAdapter.AdEventEmitter
|
|
12
|
+
import com.theoplayer.android.api.error.THEOplayerException
|
|
13
|
+
import com.theoplayer.android.api.event.EventListener
|
|
14
|
+
import com.theoplayer.android.api.event.EventType
|
|
15
|
+
import com.theoplayer.android.api.event.player.*
|
|
16
|
+
import com.theoplayer.android.api.event.track.mediatrack.audio.ActiveQualityChangedEvent
|
|
17
|
+
import com.theoplayer.android.api.event.track.mediatrack.audio.AudioTrackEventTypes
|
|
18
|
+
import com.theoplayer.android.api.event.track.mediatrack.audio.QualityChangedEvent
|
|
19
|
+
import com.theoplayer.android.api.event.track.mediatrack.audio.list.AudioTrackListEventTypes
|
|
20
|
+
import com.theoplayer.android.api.event.track.mediatrack.video.VideoTrackEventTypes
|
|
21
|
+
import com.theoplayer.android.api.event.track.mediatrack.video.list.VideoTrackListEventTypes
|
|
22
|
+
import com.theoplayer.android.api.event.track.texttrack.AddCueEvent
|
|
23
|
+
import com.theoplayer.android.api.event.track.texttrack.RemoveCueEvent
|
|
24
|
+
import com.theoplayer.android.api.event.track.texttrack.TextTrackEventTypes
|
|
25
|
+
import com.theoplayer.android.api.event.track.texttrack.list.AddTrackEvent
|
|
26
|
+
import com.theoplayer.android.api.event.track.texttrack.list.RemoveTrackEvent
|
|
27
|
+
import com.theoplayer.android.api.event.track.texttrack.list.TextTrackListEventTypes
|
|
28
|
+
import com.theoplayer.android.api.event.track.texttrack.list.TrackListChangeEvent
|
|
29
|
+
import com.theoplayer.android.api.event.track.tracklist.TrackListEvent
|
|
30
|
+
import com.theoplayer.android.api.player.Player
|
|
31
|
+
import com.theoplayer.android.api.player.track.mediatrack.MediaTrack
|
|
32
|
+
import com.theoplayer.android.api.player.track.mediatrack.MediaTrackList
|
|
33
|
+
import com.theoplayer.android.api.player.track.mediatrack.quality.AudioQuality
|
|
34
|
+
import com.theoplayer.android.api.player.track.mediatrack.quality.Quality
|
|
35
|
+
import com.theoplayer.android.api.player.track.mediatrack.quality.VideoQuality
|
|
36
|
+
import com.theoplayer.android.api.player.track.texttrack.TextTrack
|
|
37
|
+
import com.theoplayer.cast.CastEventAdapter
|
|
38
|
+
import com.theoplayer.track.*
|
|
39
|
+
import com.theoplayer.util.TypeUtils.encodeInfNan
|
|
40
|
+
import kotlin.math.floor
|
|
41
|
+
|
|
42
|
+
private val TAG = PlayerEventEmitter::class.java.name
|
|
43
|
+
|
|
44
|
+
private const val EVENT_SOURCECHANGE = "onNativeSourceChange"
|
|
45
|
+
private const val EVENT_LOADSTART = "onNativeLoadStart"
|
|
46
|
+
private const val EVENT_LOADEDMETADATA = "onNativeLoadedMetadata"
|
|
47
|
+
private const val EVENT_LOADEDDATA = "onNativeLoadedData"
|
|
48
|
+
private const val EVENT_PLAY = "onNativePlay"
|
|
49
|
+
private const val EVENT_PLAYING = "onNativePlaying"
|
|
50
|
+
private const val EVENT_PAUSE = "onNativePause"
|
|
51
|
+
private const val EVENT_ERROR = "onNativeError"
|
|
52
|
+
private const val EVENT_PROGRESS = "onNativeProgress"
|
|
53
|
+
private const val EVENT_SEEKING = "onNativeSeeking"
|
|
54
|
+
private const val EVENT_SEEKED = "onNativeSeeked"
|
|
55
|
+
private const val EVENT_ENDED = "onNativeEnded"
|
|
56
|
+
private const val EVENT_READYSTATECHANGE = "onNativeReadyStateChange"
|
|
57
|
+
private const val EVENT_TIMEUPDATE = "onNativeTimeUpdate"
|
|
58
|
+
private const val EVENT_DURATIONCHANGE = "onNativeDurationChange"
|
|
59
|
+
private const val EVENT_SEGMENTNOTFOUND = "onNativeSegmentNotFound"
|
|
60
|
+
private const val EVENT_TEXTTRACK_LIST_EVENT = "onNativeTextTrackListEvent"
|
|
61
|
+
private const val EVENT_TEXTTRACK_EVENT = "onNativeTextTrackEvent"
|
|
62
|
+
private const val EVENT_MEDIATRACK_LIST_EVENT = "onNativeMediaTrackListEvent"
|
|
63
|
+
private const val EVENT_MEDIATRACK_EVENT = "onNativeMediaTrackEvent"
|
|
64
|
+
private const val EVENT_AD_EVENT = "onNativeAdEvent"
|
|
65
|
+
private const val EVENT_FULLSCREEN_WILL_PRESENT = "onNativeFullscreenPlayerWillPresent"
|
|
66
|
+
private const val EVENT_FULLSCREEN_DID_PRESENT = "onNativeFullscreenPlayerDidPresent"
|
|
67
|
+
private const val EVENT_FULLSCREEN_WILL_DISMISS = "onNativeFullscreenPlayerWillDismiss"
|
|
68
|
+
private const val EVENT_FULLSCREEN_DID_DISMISS = "onNativeFullscreenPlayerDidDismiss"
|
|
69
|
+
private const val EVENT_CAST_EVENT = "onNativeCastEvent"
|
|
70
|
+
|
|
71
|
+
private const val EVENT_PROP_CURRENT_TIME = "currentTime"
|
|
72
|
+
private const val EVENT_PROP_CURRENT_PROGRAM_DATE_TIME = "currentProgramDateTime"
|
|
73
|
+
private const val EVENT_PROP_DURATION = "duration"
|
|
74
|
+
private const val EVENT_PROP_READYSTATE = "readyState"
|
|
75
|
+
private const val EVENT_PROP_ERROR = "error"
|
|
76
|
+
private const val EVENT_PROP_ERROR_CODE = "errorCode"
|
|
77
|
+
private const val EVENT_PROP_ERROR_MESSAGE = "errorMessage"
|
|
78
|
+
private const val EVENT_PROP_TEXT_TRACKS = "textTracks"
|
|
79
|
+
private const val EVENT_PROP_AUDIO_TRACKS = "audioTracks"
|
|
80
|
+
private const val EVENT_PROP_VIDEO_TRACKS = "videoTracks"
|
|
81
|
+
private const val EVENT_PROP_SELECTED_TEXT_TRACK = "selectedTextTrack"
|
|
82
|
+
private const val EVENT_PROP_SELECTED_AUDIO_TRACK = "selectedAudioTrack"
|
|
83
|
+
private const val EVENT_PROP_SELECTED_VIDEO_TRACK = "selectedVideoTrack"
|
|
84
|
+
private const val EVENT_PROP_SEEKABLE = "seekable"
|
|
85
|
+
private const val EVENT_PROP_START = "start"
|
|
86
|
+
private const val EVENT_PROP_END = "end"
|
|
87
|
+
private const val EVENT_PROP_RETRYCOUNT = "retryCount"
|
|
88
|
+
private const val EVENT_PROP_SEGMENTSTARTTIME = "segmentStartTime"
|
|
89
|
+
private const val EVENT_PROP_TRACK = "track"
|
|
90
|
+
private const val EVENT_PROP_TRACK_UID = "trackUid"
|
|
91
|
+
private const val EVENT_PROP_TRACK_TYPE = "trackType"
|
|
92
|
+
private const val EVENT_PROP_CUE = "cue"
|
|
93
|
+
private const val EVENT_PROP_TYPE = "type"
|
|
94
|
+
private const val EVENT_PROP_QUALITIES = "qualities"
|
|
95
|
+
|
|
96
|
+
@Suppress("UNCHECKED_CAST")
|
|
97
|
+
class PlayerEventEmitter internal constructor(
|
|
98
|
+
reactContext: ReactApplicationContext,
|
|
99
|
+
playerView: ReactTHEOplayerView
|
|
100
|
+
) {
|
|
101
|
+
@Retention(AnnotationRetention.SOURCE)
|
|
102
|
+
@StringDef(
|
|
103
|
+
EVENT_SOURCECHANGE,
|
|
104
|
+
EVENT_LOADSTART,
|
|
105
|
+
EVENT_LOADEDMETADATA,
|
|
106
|
+
EVENT_LOADEDDATA,
|
|
107
|
+
EVENT_PLAY,
|
|
108
|
+
EVENT_PLAYING,
|
|
109
|
+
EVENT_PAUSE,
|
|
110
|
+
EVENT_ERROR,
|
|
111
|
+
EVENT_PROGRESS,
|
|
112
|
+
EVENT_SEEKING,
|
|
113
|
+
EVENT_SEEKED,
|
|
114
|
+
EVENT_ENDED,
|
|
115
|
+
EVENT_READYSTATECHANGE,
|
|
116
|
+
EVENT_TIMEUPDATE,
|
|
117
|
+
EVENT_DURATIONCHANGE,
|
|
118
|
+
EVENT_SEGMENTNOTFOUND,
|
|
119
|
+
EVENT_TEXTTRACK_LIST_EVENT,
|
|
120
|
+
EVENT_TEXTTRACK_EVENT,
|
|
121
|
+
EVENT_MEDIATRACK_LIST_EVENT,
|
|
122
|
+
EVENT_MEDIATRACK_EVENT,
|
|
123
|
+
EVENT_AD_EVENT,
|
|
124
|
+
EVENT_FULLSCREEN_WILL_PRESENT,
|
|
125
|
+
EVENT_FULLSCREEN_DID_PRESENT,
|
|
126
|
+
EVENT_FULLSCREEN_WILL_DISMISS,
|
|
127
|
+
EVENT_FULLSCREEN_DID_DISMISS,
|
|
128
|
+
EVENT_CAST_EVENT
|
|
129
|
+
)
|
|
130
|
+
annotation class VideoEvents
|
|
131
|
+
|
|
132
|
+
companion object {
|
|
133
|
+
|
|
134
|
+
@JvmField
|
|
135
|
+
val Events = arrayOf(
|
|
136
|
+
EVENT_SOURCECHANGE,
|
|
137
|
+
EVENT_LOADSTART,
|
|
138
|
+
EVENT_LOADEDMETADATA,
|
|
139
|
+
EVENT_LOADEDDATA,
|
|
140
|
+
EVENT_PLAY,
|
|
141
|
+
EVENT_PLAYING,
|
|
142
|
+
EVENT_PAUSE,
|
|
143
|
+
EVENT_ERROR,
|
|
144
|
+
EVENT_PROGRESS,
|
|
145
|
+
EVENT_SEEKING,
|
|
146
|
+
EVENT_SEEKED,
|
|
147
|
+
EVENT_ENDED,
|
|
148
|
+
EVENT_READYSTATECHANGE,
|
|
149
|
+
EVENT_TIMEUPDATE,
|
|
150
|
+
EVENT_DURATIONCHANGE,
|
|
151
|
+
EVENT_SEGMENTNOTFOUND,
|
|
152
|
+
EVENT_TEXTTRACK_LIST_EVENT,
|
|
153
|
+
EVENT_TEXTTRACK_EVENT,
|
|
154
|
+
EVENT_MEDIATRACK_LIST_EVENT,
|
|
155
|
+
EVENT_MEDIATRACK_EVENT,
|
|
156
|
+
EVENT_AD_EVENT,
|
|
157
|
+
EVENT_FULLSCREEN_WILL_PRESENT,
|
|
158
|
+
EVENT_FULLSCREEN_DID_PRESENT,
|
|
159
|
+
EVENT_FULLSCREEN_WILL_DISMISS,
|
|
160
|
+
EVENT_FULLSCREEN_DID_DISMISS,
|
|
161
|
+
EVENT_CAST_EVENT
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private val eventEmitter: ReactEventEmitter
|
|
166
|
+
private var viewId = View.NO_ID
|
|
167
|
+
private val playerListeners = HashMap<EventType<*>, EventListener<*>>()
|
|
168
|
+
private val textTrackListeners = HashMap<EventType<*>, EventListener<*>>()
|
|
169
|
+
private val audioTrackListeners = HashMap<EventType<*>, EventListener<*>>()
|
|
170
|
+
private val videoTrackListeners = HashMap<EventType<*>, EventListener<*>>()
|
|
171
|
+
private val playerView: ReactTHEOplayerView
|
|
172
|
+
private val trackListAdapter = TrackListAdapter()
|
|
173
|
+
private var adEventAdapter: AdEventAdapter? = null
|
|
174
|
+
private var castEventAdapter: CastEventAdapter? = null
|
|
175
|
+
private var lastTimeUpdate: Long = 0
|
|
176
|
+
private var lastCurrentTime = 0.0
|
|
177
|
+
|
|
178
|
+
init {
|
|
179
|
+
eventEmitter = ReactEventEmitter(reactContext)
|
|
180
|
+
this.playerView = playerView
|
|
181
|
+
|
|
182
|
+
// Create listeners
|
|
183
|
+
playerListeners[PlayerEventTypes.SOURCECHANGE] = EventListener<PlayerEvent<*>> {
|
|
184
|
+
receiveEvent(EVENT_SOURCECHANGE, null)
|
|
185
|
+
}
|
|
186
|
+
playerListeners[PlayerEventTypes.LOADSTART] = EventListener<PlayerEvent<*>> {
|
|
187
|
+
receiveEvent(EVENT_LOADSTART, null)
|
|
188
|
+
}
|
|
189
|
+
playerListeners[PlayerEventTypes.LOADEDMETADATA] =
|
|
190
|
+
EventListener<PlayerEvent<*>> { onLoadedMetadata() }
|
|
191
|
+
playerListeners[PlayerEventTypes.LOADEDDATA] = EventListener<PlayerEvent<*>> {
|
|
192
|
+
receiveEvent(EVENT_LOADEDDATA, null)
|
|
193
|
+
}
|
|
194
|
+
playerListeners[PlayerEventTypes.PLAY] = EventListener<PlayerEvent<*>> {
|
|
195
|
+
receiveEvent(EVENT_PLAY, null)
|
|
196
|
+
}
|
|
197
|
+
playerListeners[PlayerEventTypes.PLAYING] = EventListener<PlayerEvent<*>> {
|
|
198
|
+
receiveEvent(EVENT_PLAYING, null)
|
|
199
|
+
}
|
|
200
|
+
playerListeners[PlayerEventTypes.READYSTATECHANGE] =
|
|
201
|
+
EventListener { event: ReadyStateChangeEvent -> onReadyState(event) }
|
|
202
|
+
playerListeners[PlayerEventTypes.SEEKING] =
|
|
203
|
+
EventListener { event: SeekingEvent -> onSeeking(event) }
|
|
204
|
+
playerListeners[PlayerEventTypes.SEEKED] =
|
|
205
|
+
EventListener { event: SeekedEvent -> onSeeked(event) }
|
|
206
|
+
playerListeners[PlayerEventTypes.ERROR] =
|
|
207
|
+
EventListener { event: ErrorEvent -> onError(event) }
|
|
208
|
+
playerListeners[PlayerEventTypes.ENDED] =
|
|
209
|
+
EventListener<PlayerEvent<*>> { receiveEvent(EVENT_ENDED, null) }
|
|
210
|
+
playerListeners[PlayerEventTypes.PROGRESS] = EventListener<PlayerEvent<*>> { onProgress() }
|
|
211
|
+
playerListeners[PlayerEventTypes.TIMEUPDATE] =
|
|
212
|
+
EventListener { event: TimeUpdateEvent -> onTimeUpdate(event) }
|
|
213
|
+
playerListeners[PlayerEventTypes.DURATIONCHANGE] =
|
|
214
|
+
EventListener { event: DurationChangeEvent -> onDurationChange(event) }
|
|
215
|
+
playerListeners[PlayerEventTypes.PAUSE] = EventListener<PlayerEvent<*>> { onPause() }
|
|
216
|
+
playerListeners[PlayerEventTypes.SEGMENTNOTFOUND] =
|
|
217
|
+
EventListener { event: SegmentNotFoundEvent -> onSegmentNotFound(event) }
|
|
218
|
+
textTrackListeners[TextTrackListEventTypes.ADDTRACK] =
|
|
219
|
+
EventListener { event: AddTrackEvent -> onTextTrackAdd(event) }
|
|
220
|
+
textTrackListeners[TextTrackListEventTypes.REMOVETRACK] =
|
|
221
|
+
EventListener { event: RemoveTrackEvent -> onTextTrackRemove(event) }
|
|
222
|
+
textTrackListeners[TextTrackListEventTypes.TRACKLISTCHANGE] =
|
|
223
|
+
EventListener { event: TrackListChangeEvent -> onTextTrackChange(event) }
|
|
224
|
+
audioTrackListeners[AudioTrackListEventTypes.ADDTRACK] =
|
|
225
|
+
EventListener { event: com.theoplayer.android.api.event.track.mediatrack.audio.list.AddTrackEvent ->
|
|
226
|
+
onAudioTrackAdd(event)
|
|
227
|
+
}
|
|
228
|
+
audioTrackListeners[AudioTrackListEventTypes.REMOVETRACK] =
|
|
229
|
+
EventListener { event: com.theoplayer.android.api.event.track.mediatrack.audio.list.RemoveTrackEvent ->
|
|
230
|
+
onAudioTrackRemove(event)
|
|
231
|
+
}
|
|
232
|
+
audioTrackListeners[AudioTrackListEventTypes.TRACKLISTCHANGE] =
|
|
233
|
+
EventListener { event: com.theoplayer.android.api.event.track.mediatrack.audio.list.TrackListChangeEvent ->
|
|
234
|
+
onAudioTrackChange(event)
|
|
235
|
+
}
|
|
236
|
+
videoTrackListeners[VideoTrackListEventTypes.ADDTRACK] =
|
|
237
|
+
EventListener { event: com.theoplayer.android.api.event.track.mediatrack.video.list.AddTrackEvent ->
|
|
238
|
+
onVideoTrackAdd(event)
|
|
239
|
+
}
|
|
240
|
+
videoTrackListeners[VideoTrackListEventTypes.REMOVETRACK] =
|
|
241
|
+
EventListener { event: com.theoplayer.android.api.event.track.mediatrack.video.list.RemoveTrackEvent ->
|
|
242
|
+
onVideoTrackRemove(event)
|
|
243
|
+
}
|
|
244
|
+
videoTrackListeners[VideoTrackListEventTypes.TRACKLISTCHANGE] =
|
|
245
|
+
EventListener { event: com.theoplayer.android.api.event.track.mediatrack.video.list.TrackListChangeEvent ->
|
|
246
|
+
onVideoTrackChange(event)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
fun setViewId(viewId: Int) {
|
|
251
|
+
this.viewId = viewId
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
fun emitError(exception: THEOplayerException) {
|
|
255
|
+
emitError(exception.code.name, exception.message)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private fun emitError(code: String, message: String?) {
|
|
259
|
+
val error = Arguments.createMap()
|
|
260
|
+
error.putString(EVENT_PROP_ERROR_CODE, code)
|
|
261
|
+
error.putString(EVENT_PROP_ERROR_MESSAGE, message ?: "")
|
|
262
|
+
val payload = Arguments.createMap()
|
|
263
|
+
payload.putMap(EVENT_PROP_ERROR, error)
|
|
264
|
+
receiveEvent(EVENT_ERROR, payload)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private fun onLoadedMetadata() {
|
|
268
|
+
val payload = Arguments.createMap()
|
|
269
|
+
payload.putArray(EVENT_PROP_TEXT_TRACKS, playerView.textTrackInfo)
|
|
270
|
+
payload.putArray(EVENT_PROP_AUDIO_TRACKS, playerView.audioTrackInfo)
|
|
271
|
+
payload.putArray(EVENT_PROP_VIDEO_TRACKS, playerView.videoTrackInfo)
|
|
272
|
+
val selectedTextTrack = playerView.selectedTextTrack
|
|
273
|
+
if (selectedTextTrack != null) {
|
|
274
|
+
payload.putInt(EVENT_PROP_SELECTED_TEXT_TRACK, selectedTextTrack.uid)
|
|
275
|
+
}
|
|
276
|
+
val selectedAudioTrack = playerView.selectedAudioTrack
|
|
277
|
+
if (selectedAudioTrack != null) {
|
|
278
|
+
payload.putInt(EVENT_PROP_SELECTED_AUDIO_TRACK, selectedAudioTrack.uid)
|
|
279
|
+
}
|
|
280
|
+
val selectedVideoTrack = playerView.selectedVideoTrack
|
|
281
|
+
if (selectedVideoTrack != null) {
|
|
282
|
+
payload.putInt(EVENT_PROP_SELECTED_VIDEO_TRACK, selectedVideoTrack.uid)
|
|
283
|
+
}
|
|
284
|
+
payload.putDouble(EVENT_PROP_DURATION, playerView.duration)
|
|
285
|
+
receiveEvent(EVENT_LOADEDMETADATA, payload)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private fun onSeeking(event: SeekingEvent) {
|
|
289
|
+
val payload = Arguments.createMap()
|
|
290
|
+
payload.putDouble(EVENT_PROP_CURRENT_TIME, (1e03 * event.currentTime).toLong().toDouble())
|
|
291
|
+
receiveEvent(EVENT_SEEKING, payload)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
private fun onSeeked(event: SeekedEvent) {
|
|
295
|
+
val payload = Arguments.createMap()
|
|
296
|
+
payload.putDouble(EVENT_PROP_CURRENT_TIME, (1e03 * event.currentTime).toLong().toDouble())
|
|
297
|
+
receiveEvent(EVENT_SEEKED, payload)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private fun shouldSkipTimeUpdate(now: Long, currentTime: Double): Boolean {
|
|
301
|
+
val timeUpdateRate = BuildConfig.TIMEUPDATE_RATE
|
|
302
|
+
|
|
303
|
+
// No limited update rate.
|
|
304
|
+
if (timeUpdateRate == TimeUpdateRate.UNLIMITED) {
|
|
305
|
+
return false
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Try to align updates on second boundary.
|
|
309
|
+
if (floor(lastCurrentTime) != floor(currentTime)) {
|
|
310
|
+
return false
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Limit update rate.
|
|
314
|
+
val dt = now - lastTimeUpdate
|
|
315
|
+
return timeUpdateRate == TimeUpdateRate.LIMITED_ONE_HZ && dt < 1e03 ||
|
|
316
|
+
timeUpdateRate == TimeUpdateRate.LIMITED_TWO_HZ && dt < 500 ||
|
|
317
|
+
timeUpdateRate == TimeUpdateRate.LIMITED_THREE_HZ && dt < 333
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
private fun onPause() {
|
|
321
|
+
val player = playerView.player
|
|
322
|
+
// Do not forward the pause event in case the content player is paused because the ad player starts.
|
|
323
|
+
if (player != null && !playerView.adsApi.isPlaying) {
|
|
324
|
+
receiveEvent(EVENT_PAUSE, null)
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
private fun onTimeUpdate(event: TimeUpdateEvent) {
|
|
329
|
+
val now = System.currentTimeMillis()
|
|
330
|
+
val currentTime = event.currentTime
|
|
331
|
+
|
|
332
|
+
// Check for limited timeUpdates
|
|
333
|
+
if (shouldSkipTimeUpdate(now, currentTime)) {
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
lastTimeUpdate = now
|
|
337
|
+
lastCurrentTime = currentTime
|
|
338
|
+
val payload = Arguments.createMap()
|
|
339
|
+
payload.putDouble(EVENT_PROP_CURRENT_TIME, (1e03 * currentTime).toLong().toDouble())
|
|
340
|
+
val currentProgramDateTime = event.currentProgramDateTime
|
|
341
|
+
if (currentProgramDateTime != null) {
|
|
342
|
+
payload.putDouble(
|
|
343
|
+
EVENT_PROP_CURRENT_PROGRAM_DATE_TIME,
|
|
344
|
+
(1e03 * currentProgramDateTime.time).toLong().toDouble()
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
receiveEvent(EVENT_TIMEUPDATE, payload)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
private fun onReadyState(event: ReadyStateChangeEvent) {
|
|
351
|
+
val payload = Arguments.createMap()
|
|
352
|
+
payload.putInt(EVENT_PROP_READYSTATE, event.readyState.ordinal)
|
|
353
|
+
receiveEvent(EVENT_READYSTATECHANGE, payload)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
private fun onDurationChange(event: DurationChangeEvent) {
|
|
357
|
+
val payload = Arguments.createMap()
|
|
358
|
+
payload.putDouble(EVENT_PROP_DURATION, encodeInfNan(1e03 * event.duration))
|
|
359
|
+
receiveEvent(EVENT_DURATIONCHANGE, payload)
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
private fun onError(event: ErrorEvent) {
|
|
363
|
+
emitError(event.errorObject)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
private fun onProgress() {
|
|
367
|
+
val timeRanges = playerView.getSeekableRange()
|
|
368
|
+
val payload = Arguments.createMap()
|
|
369
|
+
if (timeRanges != null) {
|
|
370
|
+
val seekable = Arguments.createArray()
|
|
371
|
+
for (i in 0 until timeRanges.length()) {
|
|
372
|
+
val range = Arguments.createMap()
|
|
373
|
+
range.putDouble(EVENT_PROP_START, 1e03 * timeRanges.getStart(i))
|
|
374
|
+
range.putDouble(EVENT_PROP_END, 1e03 * timeRanges.getEnd(i))
|
|
375
|
+
seekable.pushMap(range)
|
|
376
|
+
}
|
|
377
|
+
payload.putArray(EVENT_PROP_SEEKABLE, seekable)
|
|
378
|
+
}
|
|
379
|
+
receiveEvent(EVENT_PROGRESS, payload)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
private fun onSegmentNotFound(event: SegmentNotFoundEvent) {
|
|
383
|
+
val payload = Arguments.createMap()
|
|
384
|
+
payload.putDouble(EVENT_PROP_SEGMENTSTARTTIME, 1e03 * event.segmentStartTime)
|
|
385
|
+
payload.putString(EVENT_PROP_ERROR, event.error)
|
|
386
|
+
payload.putInt(EVENT_PROP_RETRYCOUNT, event.retryCount)
|
|
387
|
+
receiveEvent(EVENT_SEGMENTNOTFOUND, payload)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
private fun dispatchTextTrackEvent(eventType: TrackEventType, textTrack: TextTrack) {
|
|
391
|
+
val payload = Arguments.createMap()
|
|
392
|
+
payload.putMap(EVENT_PROP_TRACK, playerView.getTextTrackInfo(textTrack))
|
|
393
|
+
payload.putInt(EVENT_PROP_TYPE, eventType.type)
|
|
394
|
+
when (eventType) {
|
|
395
|
+
TrackEventType.ADD_TRACK -> {
|
|
396
|
+
textTrack.addEventListener(TextTrackEventTypes.ADDCUE) { event: AddCueEvent ->
|
|
397
|
+
onTextTrackAddCue(event)
|
|
398
|
+
}
|
|
399
|
+
textTrack.addEventListener(TextTrackEventTypes.REMOVECUE) { event: RemoveCueEvent ->
|
|
400
|
+
onTextTrackRemoveCue(event)
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
TrackEventType.REMOVE_TRACK -> {
|
|
404
|
+
textTrack.removeEventListener(TextTrackEventTypes.ADDCUE) { event: AddCueEvent ->
|
|
405
|
+
onTextTrackAddCue(event)
|
|
406
|
+
}
|
|
407
|
+
textTrack.removeEventListener(TextTrackEventTypes.REMOVECUE) { event: RemoveCueEvent ->
|
|
408
|
+
onTextTrackRemoveCue(event)
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
else -> {
|
|
412
|
+
// Ignore
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
receiveEvent(EVENT_TEXTTRACK_LIST_EVENT, payload)
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
private fun onTextTrackAdd(event: AddTrackEvent) {
|
|
419
|
+
dispatchTextTrackEvent(TrackEventType.ADD_TRACK, event.track)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
private fun onTextTrackRemove(event: RemoveTrackEvent) {
|
|
423
|
+
dispatchTextTrackEvent(TrackEventType.REMOVE_TRACK, event.track)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
private fun onTextTrackChange(event: TrackListChangeEvent) {
|
|
427
|
+
dispatchTextTrackEvent(TrackEventType.CHANGE_TRACK, event.track)
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
private fun onTextTrackAddCue(event: AddCueEvent) {
|
|
431
|
+
val payload = Arguments.createMap()
|
|
432
|
+
payload.putInt(EVENT_PROP_TRACK_UID, event.track.uid)
|
|
433
|
+
payload.putInt(EVENT_PROP_TYPE, TextTrackCueEventType.ADD_CUE.type)
|
|
434
|
+
payload.putMap(EVENT_PROP_CUE, playerView.getTextTrackCueInfo(event.cue))
|
|
435
|
+
receiveEvent(EVENT_TEXTTRACK_EVENT, payload)
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
private fun onTextTrackRemoveCue(event: RemoveCueEvent) {
|
|
439
|
+
val payload = Arguments.createMap()
|
|
440
|
+
payload.putInt(EVENT_PROP_TRACK_UID, event.track.uid)
|
|
441
|
+
payload.putInt(EVENT_PROP_TYPE, TextTrackCueEventType.REMOVE_CUE.type)
|
|
442
|
+
payload.putMap(EVENT_PROP_CUE, playerView.getTextTrackCueInfo(event.cue))
|
|
443
|
+
receiveEvent(EVENT_TEXTTRACK_EVENT, payload)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
private fun activeAudioTrack(): MediaTrack<AudioQuality>? {
|
|
447
|
+
return if (playerView.player != null) activeTrack(
|
|
448
|
+
playerView.player!!.audioTracks
|
|
449
|
+
) else null
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
private fun activeVideoTrack(): MediaTrack<VideoQuality>? {
|
|
453
|
+
return if (playerView.player != null) activeTrack(
|
|
454
|
+
playerView.player!!.videoTracks
|
|
455
|
+
) else null
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private fun <T : Quality?> activeTrack(tracks: MediaTrackList<T>): MediaTrack<T>? {
|
|
459
|
+
for (i in 0 until tracks.length()) {
|
|
460
|
+
val track = tracks.getItem(i)
|
|
461
|
+
if (track.isEnabled) {
|
|
462
|
+
return track
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return null
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
private fun onActiveQualityChanged(event: QualityChangedEvent<*, *>) {
|
|
469
|
+
val quality = event.quality
|
|
470
|
+
val trackType = if (quality is AudioQuality) MediaTrackType.AUDIO else MediaTrackType.VIDEO
|
|
471
|
+
val payload = Arguments.createMap()
|
|
472
|
+
payload.putInt(EVENT_PROP_TYPE, MediaTrackEventType.ACTIVE_QUALITY_CHANGED.type)
|
|
473
|
+
payload.putInt(EVENT_PROP_TRACK_TYPE, trackType.type)
|
|
474
|
+
val activeTrack =
|
|
475
|
+
if (trackType === MediaTrackType.AUDIO) activeAudioTrack() else activeVideoTrack()
|
|
476
|
+
if (activeTrack != null) {
|
|
477
|
+
payload.putInt(EVENT_PROP_TRACK_UID, activeTrack.uid)
|
|
478
|
+
}
|
|
479
|
+
val qualities = Arguments.createArray()
|
|
480
|
+
qualities.pushMap(trackListAdapter.fromQuality(quality))
|
|
481
|
+
payload.putArray(EVENT_PROP_QUALITIES, qualities)
|
|
482
|
+
receiveEvent(EVENT_MEDIATRACK_EVENT, payload)
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
private fun <Q : Quality?> dispatchMediaTrackEvent(
|
|
486
|
+
eventType: TrackEventType,
|
|
487
|
+
trackType: MediaTrackType,
|
|
488
|
+
track: MediaTrack<Q>
|
|
489
|
+
) {
|
|
490
|
+
val payload = Arguments.createMap()
|
|
491
|
+
payload.putInt(EVENT_PROP_TYPE, eventType.type)
|
|
492
|
+
payload.putInt(EVENT_PROP_TRACK_TYPE, trackType.type)
|
|
493
|
+
payload.putMap(EVENT_PROP_TRACK, trackListAdapter.fromMediaTrack(track, trackType))
|
|
494
|
+
val qualityChangedEventType =
|
|
495
|
+
(if (trackType === MediaTrackType.AUDIO)
|
|
496
|
+
AudioTrackEventTypes.ACTIVEQUALITYCHANGEDEVENT
|
|
497
|
+
else VideoTrackEventTypes.ACTIVEQUALITYCHANGEDEVENT) as EventType<QualityChangedEvent<Q, ActiveQualityChangedEvent>>
|
|
498
|
+
when (eventType) {
|
|
499
|
+
TrackEventType.ADD_TRACK -> track.addEventListener(qualityChangedEventType) { event: QualityChangedEvent<Q, ActiveQualityChangedEvent> ->
|
|
500
|
+
onActiveQualityChanged(event)
|
|
501
|
+
}
|
|
502
|
+
TrackEventType.REMOVE_TRACK -> track.removeEventListener(qualityChangedEventType) { event: QualityChangedEvent<Q, ActiveQualityChangedEvent> ->
|
|
503
|
+
onActiveQualityChanged(event)
|
|
504
|
+
}
|
|
505
|
+
else -> { /* ignore */
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
receiveEvent(EVENT_MEDIATRACK_LIST_EVENT, payload)
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
private fun onAudioTrackAdd(event: com.theoplayer.android.api.event.track.mediatrack.audio.list.AddTrackEvent) {
|
|
512
|
+
dispatchMediaTrackEvent(TrackEventType.ADD_TRACK, MediaTrackType.AUDIO, event.track)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
private fun onVideoTrackAdd(event: com.theoplayer.android.api.event.track.mediatrack.video.list.AddTrackEvent) {
|
|
516
|
+
dispatchMediaTrackEvent(TrackEventType.ADD_TRACK, MediaTrackType.VIDEO, event.track)
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
private fun onAudioTrackRemove(event: com.theoplayer.android.api.event.track.mediatrack.audio.list.RemoveTrackEvent) {
|
|
520
|
+
dispatchMediaTrackEvent(TrackEventType.REMOVE_TRACK, MediaTrackType.AUDIO, event.track)
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
private fun onVideoTrackRemove(event: com.theoplayer.android.api.event.track.mediatrack.video.list.RemoveTrackEvent) {
|
|
524
|
+
dispatchMediaTrackEvent(TrackEventType.REMOVE_TRACK, MediaTrackType.VIDEO, event.track)
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
private fun onAudioTrackChange(event: com.theoplayer.android.api.event.track.mediatrack.audio.list.TrackListChangeEvent) {
|
|
528
|
+
dispatchMediaTrackEvent(TrackEventType.CHANGE_TRACK, MediaTrackType.AUDIO, event.track)
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
private fun onVideoTrackChange(event: com.theoplayer.android.api.event.track.mediatrack.video.list.TrackListChangeEvent) {
|
|
532
|
+
dispatchMediaTrackEvent(TrackEventType.CHANGE_TRACK, MediaTrackType.VIDEO, event.track)
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
fun onFullscreenWillPresent() {
|
|
536
|
+
receiveEvent(EVENT_FULLSCREEN_WILL_PRESENT, null)
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
fun onFullscreenDidPresent() {
|
|
540
|
+
receiveEvent(EVENT_FULLSCREEN_DID_PRESENT, null)
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
fun onFullscreenWillDismiss() {
|
|
544
|
+
receiveEvent(EVENT_FULLSCREEN_WILL_DISMISS, null)
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
fun onFullscreenDidDismiss() {
|
|
548
|
+
receiveEvent(EVENT_FULLSCREEN_DID_DISMISS, null)
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
private fun receiveEvent(@VideoEvents type: String, event: WritableMap?) {
|
|
552
|
+
if (BuildConfig.LOG_PLAYER_EVENTS) {
|
|
553
|
+
try {
|
|
554
|
+
Log.d(TAG, "receiveEvent $type $event")
|
|
555
|
+
} catch (ignore: RuntimeException) {
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
eventEmitter.receiveEvent(viewId, type, event)
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
fun attachListeners(player: Player) {
|
|
562
|
+
// Attach player listeners
|
|
563
|
+
for ((key, value) in playerListeners) {
|
|
564
|
+
player.addEventListener(
|
|
565
|
+
key as EventType<PlayerEvent<*>>,
|
|
566
|
+
value as EventListener<PlayerEvent<*>>
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// Attach text track listeners
|
|
571
|
+
for ((key, value) in textTrackListeners) {
|
|
572
|
+
player.textTracks.addEventListener(
|
|
573
|
+
key as EventType<TrackListEvent<*, *>>,
|
|
574
|
+
value as EventListener<TrackListEvent<*, *>>
|
|
575
|
+
)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Attach audio track listeners
|
|
579
|
+
for ((key, value) in audioTrackListeners) {
|
|
580
|
+
player.audioTracks.addEventListener(
|
|
581
|
+
key as EventType<TrackListEvent<*, *>>,
|
|
582
|
+
value as EventListener<TrackListEvent<*, *>>
|
|
583
|
+
)
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Attach video track listeners
|
|
587
|
+
for ((key, value) in videoTrackListeners) {
|
|
588
|
+
player.videoTracks.addEventListener(
|
|
589
|
+
key as EventType<TrackListEvent<*, *>>,
|
|
590
|
+
value as EventListener<TrackListEvent<*, *>>
|
|
591
|
+
)
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Attach AdStateHolder
|
|
595
|
+
if (BuildConfig.EXTENSION_ADS) {
|
|
596
|
+
adEventAdapter = AdEventAdapter(playerView.adsApi,
|
|
597
|
+
object : AdEventEmitter {
|
|
598
|
+
override fun emit(payload: WritableMap?) {
|
|
599
|
+
receiveEvent(EVENT_AD_EVENT, payload)
|
|
600
|
+
}
|
|
601
|
+
})
|
|
602
|
+
}
|
|
603
|
+
if (BuildConfig.EXTENSION_CAST && playerView.castApi != null) {
|
|
604
|
+
castEventAdapter = CastEventAdapter(playerView.castApi!!,
|
|
605
|
+
object : CastEventAdapter.Emitter {
|
|
606
|
+
override fun emit(payload: WritableMap?) {
|
|
607
|
+
receiveEvent(EVENT_CAST_EVENT, payload)
|
|
608
|
+
}
|
|
609
|
+
})
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
fun removeListeners(player: Player) {
|
|
614
|
+
// Remove player listeners
|
|
615
|
+
for ((key, value) in playerListeners) {
|
|
616
|
+
player.removeEventListener(
|
|
617
|
+
key as EventType<PlayerEvent<*>>,
|
|
618
|
+
value as EventListener<PlayerEvent<*>>
|
|
619
|
+
)
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Remove text track listeners
|
|
623
|
+
for ((key, value) in textTrackListeners) {
|
|
624
|
+
player.textTracks.removeEventListener(
|
|
625
|
+
key as EventType<TrackListEvent<*, *>>,
|
|
626
|
+
value as EventListener<TrackListEvent<*, *>>
|
|
627
|
+
)
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// Remove audio track listeners
|
|
631
|
+
for ((key, value) in audioTrackListeners) {
|
|
632
|
+
player.audioTracks.removeEventListener(
|
|
633
|
+
key as EventType<TrackListEvent<*, *>>,
|
|
634
|
+
value as EventListener<TrackListEvent<*, *>>
|
|
635
|
+
)
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Remove video track listeners
|
|
639
|
+
for ((key, value) in videoTrackListeners) {
|
|
640
|
+
player.videoTracks.removeEventListener(
|
|
641
|
+
key as EventType<TrackListEvent<*, *>>,
|
|
642
|
+
value as EventListener<TrackListEvent<*, *>>
|
|
643
|
+
)
|
|
644
|
+
}
|
|
645
|
+
castEventAdapter?.destroy()
|
|
646
|
+
adEventAdapter?.destroy()
|
|
647
|
+
}
|
|
648
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package com.theoplayer
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.bridge.NativeModule
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
import com.theoplayer.ads.AdsModule
|
|
8
|
+
import com.theoplayer.drm.ContentProtectionModule
|
|
9
|
+
import com.theoplayer.cast.CastModule
|
|
10
|
+
|
|
11
|
+
class ReactTHEOplayerPackage : ReactPackage {
|
|
12
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
13
|
+
return listOf(
|
|
14
|
+
AdsModule(reactContext),
|
|
15
|
+
ContentProtectionModule(reactContext),
|
|
16
|
+
CastModule(reactContext)
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
21
|
+
return listOf<ViewManager<*, *>>(ReactTHEOplayerViewManager())
|
|
22
|
+
}
|
|
23
|
+
}
|