Skip to content

Commit e470d86

Browse files
Merge pull request #770 from THEOplayer/release/v10.11.0
Release/v10.11.0
2 parents ff11448 + d5ac889 commit e470d86

30 files changed

Lines changed: 581 additions & 388 deletions

CHANGELOG.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,30 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## [10.11.0] - 26-03-10
9+
10+
### Fixed
11+
12+
- Fixed an issue on Android where transitioning from picture-in-picture presentation mode would fail when using Expo Router.
13+
- Fixed an issue where the player would remove all listeners when using `<StrictMode>` on mobile platforms.
14+
15+
### Changed
16+
17+
- Updated `NativeAdBreak` to prevent iOS build failure caused by changed `AdBreak` protocol.
18+
819
## [10.10.0] - 26-02-17
920

1021
### Fixed
1122

12-
- Fixed an issue on iOS where the onPlayerStateSync callback was not called from the main thread.
23+
- Fixed an issue on iOS where the `onPlayerStateSync` callback was not called from the main thread.
24+
25+
### Added
26+
27+
- Added the `DistributionLoaded` event for THEOlive.
28+
29+
### Added
30+
31+
- Added contentProtection extraction for THEOlive endpoints on iOS.
1332

1433
## [10.9.0] - 26-01-29
1534

android/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ repositories {
124124
mavenLocal()
125125
}
126126

127-
// The minimum supported THEOplayer version is 10.0.1
128-
def theoVersion = safeExtGet('THEOplayer_sdk', '[10.0.1, 11.0.0)')
127+
// The minimum supported THEOplayer version is 10.10.0
128+
def theoVersion = safeExtGet('THEOplayer_sdk', '[10.10.0, 11.0.0)')
129129
def theoMediaSessionVersion = safeExtGet('THEOplayer_mediasession', '[8.0.0, 11.0.0)')
130130
def theoAdsWrapperVersion = "10.0.0"
131131
def coroutinesVersion = safeExtGet('coroutinesVersion', '1.10.2')

android/src/main/java/com/theoplayer/presentation/PresentationManager.kt

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -286,36 +286,43 @@ class PresentationManager(
286286
get() = findReactRootView( reactContext, reactPlayerGroup)
287287

288288
private fun reparentPlayerToRoot() {
289-
reactPlayerGroup?.let { playerGroup ->
290-
playerGroupRestoreOptions.parentNode = (playerGroup.parent as? ViewGroup)?.also { parent ->
291-
playerGroupRestoreOptions.childIndex = parent.indexOfChild(playerGroup)
289+
val root = rootView ?: return
290+
val playerGroup = reactPlayerGroup ?: return
291+
val playerGroupParent = (playerGroup.parent as? ViewGroup) ?: return
292292

293-
// Re-parent the playerViewGroup to the root node
294-
parent.removeView(playerGroup)
295-
rootView?.let { root ->
296-
root.addView(playerGroup)
297-
298-
// Attach an observer that overrides the react-native lay-out and forces fullscreen.
299-
fullScreenLayoutObserver.attach(playerGroup, root)
300-
}
301-
}
293+
// already reparented?
294+
if (playerGroup.parent == root) {
295+
return
302296
}
297+
298+
// Store the original parent and child index to be able to restore it later
299+
playerGroupRestoreOptions.store(playerGroupParent, playerGroup)
300+
301+
// Re-parent the playerViewGroup to the root node
302+
playerGroupParent.removeView(playerGroup)
303+
root.addView(playerGroup)
304+
305+
// Attach an observer that overrides the react-native lay-out and forces fullscreen.
306+
fullScreenLayoutObserver.attach(playerGroup, root)
303307
}
304308

305309
private fun reparentPlayerToOriginal() {
306-
rootView?.run {
307-
reactPlayerGroup?.let { playerGroup ->
308-
// Remove forced layout observer
309-
fullScreenLayoutObserver.remove()
310-
311-
// Re-parent the playerViewGroup from the root node to its original parent
312-
removeView(playerGroup)
313-
playerGroupRestoreOptions.parentNode?.addView(
314-
playerGroup, playerGroupRestoreOptions.childIndex ?: 0
315-
)
316-
playerGroupRestoreOptions.reset()
317-
}
310+
val root = rootView ?: return
311+
val playerGroup = reactPlayerGroup ?: return
312+
313+
// Not re-parented?
314+
if (!playerGroupRestoreOptions.isStored()) {
315+
return
318316
}
317+
318+
// Remove forced layout observer
319+
fullScreenLayoutObserver.remove()
320+
321+
// Remove the playerViewGroup the root node
322+
root.removeView(playerGroup)
323+
324+
// Restore the original parent and child index
325+
playerGroupRestoreOptions.restore()
319326
}
320327
// endregion
321328

@@ -346,11 +353,31 @@ class PresentationManager(
346353
}
347354
}
348355

356+
/**
357+
* Helper class to store the original parent and child index of the playerViewGroup when re-parenting it
358+
* to the root view for fullscreen or PiP presentation mode, and restore it when going back to inline mode.
359+
*/
349360
private class PlayerGroupRestoreOptions {
350361
var childIndex: Int? = null
362+
private set
351363
var parentNode: ViewGroup? = null
364+
private set
365+
var childNode: ReactViewGroup? = null
366+
private set
367+
368+
fun isStored(): Boolean = parentNode != null && childNode != null
352369

353-
fun reset() {
370+
fun store(parent: ViewGroup, child: ReactViewGroup) {
371+
parentNode = parent
372+
childNode = child
373+
childIndex = parent.indexOfChild(child)
374+
}
375+
376+
fun restore() {
377+
childNode?.let { child ->
378+
parentNode?.addView(child, childIndex ?: 0)
379+
}
380+
childNode = null
354381
parentNode = null
355382
childIndex = null
356383
}

android/src/main/java/com/theoplayer/theolive/THEOliveEventAdapter.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.facebook.react.bridge.Arguments
44
import com.facebook.react.bridge.WritableMap
55
import com.theoplayer.android.api.event.EventListener
66
import com.theoplayer.android.api.event.player.theolive.DistributionLoadStartEvent
7+
import com.theoplayer.android.api.event.player.theolive.DistributionLoadedEvent
78
import com.theoplayer.android.api.event.player.theolive.DistributionOfflineEvent
89
import com.theoplayer.android.api.event.player.theolive.EndpointLoadedEvent
910
import com.theoplayer.android.api.event.player.theolive.IntentToFallbackEvent
@@ -13,8 +14,11 @@ import com.theoplayer.util.PayloadBuilder
1314

1415
private const val EVENT_PROP_TYPE = "type"
1516
private const val EVENT_PROP_DISTRIBUTION_ID = "distributionId"
17+
private const val EVENT_PROP_DISTRIBUTION = "distribution"
1618
private const val EVENT_PROP_ENDPOINT = "endpoint"
1719
private const val EVENT_PROP_REASON = "reason"
20+
private const val EVENT_PROP_NAME = "name"
21+
private const val EVENT_PROP_ID = "id"
1822

1923
class THEOliveEventAdapter(private val theoLiveApi: TheoLive, private val emitter: Emitter) {
2024

@@ -24,6 +28,8 @@ class THEOliveEventAdapter(private val theoLiveApi: TheoLive, private val emitte
2428

2529
private val onDistributionLoadStart =
2630
EventListener<DistributionLoadStartEvent> { onDistributionLoadStart(it) }
31+
private val onDistributionLoaded =
32+
EventListener<DistributionLoadedEvent> { onDistributionLoaded(it) }
2733
private val onDistributionOffline =
2834
EventListener<DistributionOfflineEvent> { onDistributionOffline(it) }
2935
private val onEndPointLoaded =
@@ -33,6 +39,7 @@ class THEOliveEventAdapter(private val theoLiveApi: TheoLive, private val emitte
3339

3440
init {
3541
theoLiveApi.addEventListener(TheoLiveEventTypes.DISTRIBUTIONLOADSTART, onDistributionLoadStart)
42+
theoLiveApi.addEventListener(TheoLiveEventTypes.DISTRIBUTIONLOADED, onDistributionLoaded)
3643
theoLiveApi.addEventListener(TheoLiveEventTypes.DISTRIBUTIONOFFLINE, onDistributionOffline)
3744
theoLiveApi.addEventListener(TheoLiveEventTypes.ENDPOINTLOADED, onEndPointLoaded)
3845
theoLiveApi.addEventListener(TheoLiveEventTypes.INTENTTOFALLBACK, onIntentOfFallback)
@@ -43,6 +50,7 @@ class THEOliveEventAdapter(private val theoLiveApi: TheoLive, private val emitte
4350
TheoLiveEventTypes.DISTRIBUTIONLOADSTART,
4451
onDistributionLoadStart
4552
)
53+
theoLiveApi.removeEventListener(TheoLiveEventTypes.DISTRIBUTIONLOADED, onDistributionLoaded)
4654
theoLiveApi.removeEventListener(TheoLiveEventTypes.DISTRIBUTIONOFFLINE, onDistributionOffline)
4755
theoLiveApi.removeEventListener(TheoLiveEventTypes.ENDPOINTLOADED, onEndPointLoaded)
4856
theoLiveApi.removeEventListener(TheoLiveEventTypes.INTENTTOFALLBACK, onIntentOfFallback)
@@ -55,6 +63,16 @@ class THEOliveEventAdapter(private val theoLiveApi: TheoLive, private val emitte
5563
})
5664
}
5765

66+
private fun onDistributionLoaded(event: DistributionLoadedEvent) {
67+
emitter.emit(Arguments.createMap().apply {
68+
putString(EVENT_PROP_TYPE, "distributionloaded")
69+
putMap(EVENT_PROP_DISTRIBUTION, Arguments.createMap().apply {
70+
putString(EVENT_PROP_ID, event.getDistribution().id)
71+
putString(EVENT_PROP_NAME, event.getDistribution().name)
72+
})
73+
})
74+
}
75+
5876
private fun onDistributionOffline(event: DistributionOfflineEvent) {
5977
emitter.emit(Arguments.createMap().apply {
6078
putString(EVENT_PROP_TYPE, "distributionoffline")

e2e/android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ newArchEnabled=true
4141
hermesEnabled=true
4242

4343
# Version of the THEOplayer SDK, if not specified, the latest available version within bounds is set.
44-
#THEOplayer_sdk=[8.1.0, 11.0.0)
44+
#THEOplayer_sdk=[10.10.0, 11.0.0)
4545

4646
# Override Android sdk versions
4747
#THEOplayer_compileSdkVersion = 34

0 commit comments

Comments
 (0)