Skip to content

Commit 172f3b0

Browse files
authored
Merge pull request #707 from THEOplayer/OPTI-658-millicast-config-react-native
Expose webrtc in TheoLiveSource on iOS/Android
2 parents f3612bf + 330b53a commit 172f3b0

File tree

8 files changed

+81
-10
lines changed

8 files changed

+81
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1414
### Added
1515

1616
- Added `useExperimentalPipeline` to `CastConfiguration` for iOS, that controls the usage of an experimental, alternative implementation of the chromecast pipeline with a different feature set.
17+
- Added a webrtc configuration property `webrtc` in `TheoLiveSource`, to enable configuring the playout delay for Millicast streams consumed through OptiVew Live.
1718

1819
## [10.6.0] - 25-12-02
1920

android/src/main/java/com/theoplayer/source/SourceAdapter.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import com.theoplayer.android.api.cmcd.CMCDTransmissionMode
2424
import com.theoplayer.android.api.error.ErrorCode
2525
import com.theoplayer.android.api.source.AdIntegration
2626
import com.theoplayer.android.api.source.dash.DashPlaybackConfiguration
27+
import com.theoplayer.android.api.theolive.PlayoutDelay
2728
import com.theoplayer.android.api.theolive.TheoLiveSource
29+
import com.theoplayer.android.api.theolive.WebRTCOptions
2830
import com.theoplayer.cmcd.CmcdTransmissionMode
2931
import com.theoplayer.drm.ContentProtectionAdapter
3032
import com.theoplayer.latency.parseLatencyConfiguration
@@ -72,6 +74,10 @@ private const val PROP_SSE_ENDPOINT = "sseEndpoint"
7274
private const val PROP_STREAM_ACTIVITY_MONITOR_ID = "streamActivityMonitorId"
7375
private const val PROP_LATENCY_CONFIGURATION = "latencyConfiguration"
7476
private const val PROP_PROFILE = "profile"
77+
private const val PROP_WEBRTC: String = "webrtc"
78+
private const val PROP_PLAYOUT_DELAY: String = "playoutDelayMs"
79+
private const val PROP_PLAYOUT_DELAY_MIN: String = "minimum"
80+
private const val PROP_PLAYOUT_DELAY_MAX: String = "maximum"
7581

7682
private const val ERROR_IMA_NOT_ENABLED = "Google IMA support not enabled."
7783
private const val ERROR_THEOADS_NOT_ENABLED = "THEOads support not enabled."
@@ -183,10 +189,23 @@ class SourceAdapter {
183189
drm=jsonTypedSource.optJSONObject(PROP_CONTENT_PROTECTION)?.let {
184190
ContentProtectionAdapter.drmConfigurationFromJson(it)
185191
},
186-
profile=jsonTypedSource.optString(PROP_PROFILE)
192+
profile=jsonTypedSource.optString(PROP_PROFILE),
193+
webrtc=parseWebRTCOptions(jsonTypedSource)
187194
)
188195
}
189196

197+
@Throws(THEOplayerException::class)
198+
private fun parseWebRTCOptions(jsonWebrtcOptions: JSONObject): WebRTCOptions? {
199+
val webrtc = jsonWebrtcOptions.optJSONObject(PROP_WEBRTC)
200+
val playoutDelay = webrtc?.optJSONObject(PROP_PLAYOUT_DELAY)
201+
val playoutDelayMin = playoutDelay?.optInt(PROP_PLAYOUT_DELAY_MIN)
202+
val playoutDelayMax = playoutDelay?.optInt(PROP_PLAYOUT_DELAY_MAX)
203+
204+
if (playoutDelayMin == null || playoutDelayMax == null) return null
205+
206+
return WebRTCOptions(playoutDelayMs = PlayoutDelay(playoutDelayMin, playoutDelayMax))
207+
}
208+
190209
@Throws(THEOplayerException::class)
191210
private fun parseTypedSource(jsonTypedSource: JSONObject, cmcdTransmissionMode: CMCDTransmissionMode? = null): TypedSource {
192211
// Property `integration` will be replaced with `type`.

ios/theolive/THEOplayerRCTSourceDescriptionBuilder+Theolive.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,22 @@ import THEOplayerTHEOliveIntegration
99
#endif
1010

1111
let SD_PROP_PROFILE: String = "profile"
12+
let SD_PROP_WEBRTC: String = "webrtc"
13+
let SD_PROP_PLAYOUT_DELAY: String = "playoutDelayMs"
14+
let SD_PROP_PLAYOUT_DELAY_MIN: String = "minimum"
15+
let SD_PROP_PLAYOUT_DELAY_MAX: String = "maximum"
1216

1317
extension THEOplayerRCTSourceDescriptionBuilder {
1418

19+
private static func buildWebrtcOptions(_ theoliveData: [String: Any]) -> WebrtcOptions? {
20+
let webrtc = theoliveData[SD_PROP_WEBRTC] as? NSDictionary
21+
let playoutDelay = webrtc?[SD_PROP_PLAYOUT_DELAY] as? NSDictionary
22+
let playoutDelayMin = playoutDelay?[SD_PROP_PLAYOUT_DELAY_MIN] as? Int
23+
let playoutDelayMax = playoutDelay?[SD_PROP_PLAYOUT_DELAY_MAX] as? Int
24+
guard let playoutDelayMin, let playoutDelayMax else { return nil }
25+
return WebrtcOptions(playoutDelayMs: PlayoutDelay(minimum: playoutDelayMin, maximum: playoutDelayMax))
26+
}
27+
1528
/**
1629
Builds a THEOplayer SourceDescription that can be passed as a source for the THEOplayer.
1730
- returns: a THEOlive TypedSource.
@@ -20,7 +33,8 @@ extension THEOplayerRCTSourceDescriptionBuilder {
2033
#if canImport(THEOplayerTHEOliveIntegration)
2134
if let src = theoliveData[SD_PROP_SRC] as? String {
2235
let profile = theoliveData[SD_PROP_PROFILE] as? String;
23-
return TheoLiveSource(channelId: src, drm: contentProtection, profile: profile)
36+
let webrtc = buildWebrtcOptions(theoliveData)
37+
return TheoLiveSource(channelId: src, drm: contentProtection, profile: profile, webrtc: webrtc)
2438
}
2539
#endif
2640
return nil

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-theoplayer",
3-
"version": "10.6.1",
3+
"version": "10.7.0",
44
"description": "A THEOplayer video component for react-native.",
55
"main": "lib/commonjs/index",
66
"module": "lib/module/index",

react-native-theoplayer.podspec

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,37 +43,37 @@ Pod::Spec.new do |s|
4343

4444
# THEOplayer Dependency
4545
puts "Adding THEOplayerSDK-core"
46-
s.dependency "THEOplayerSDK-core", "~> 10.6"
46+
s.dependency "THEOplayerSDK-core", "~> 10.7"
4747

4848
# THEOlive Dependency
4949
puts "Adding THEOplayer-Integration-THEOlive"
50-
s.dependency "THEOplayer-Integration-THEOlive", "~> 10.6"
50+
s.dependency "THEOplayer-Integration-THEOlive", "~> 10.7"
5151

5252
# Feature based integration dependencies
5353
if theofeatures.include?("GOOGLE_IMA")
5454
puts "Adding THEOplayer-Integration-GoogleIMA"
55-
s.dependency "THEOplayer-Integration-GoogleIMA", "~> 10.6"
55+
s.dependency "THEOplayer-Integration-GoogleIMA", "~> 10.7"
5656
end
5757

5858
if theofeatures.include?("CHROMECAST")
5959
puts "Adding THEOplayer-Integration-GoogleCast"
60-
s.ios.dependency "THEOplayer-Integration-GoogleCast", "~> 10.6"
60+
s.ios.dependency "THEOplayer-Integration-GoogleCast", "~> 10.7"
6161
end
6262

6363
if theofeatures.include?("THEO_ADS")
6464
puts "Adding THEOplayer-Integration-THEOads"
65-
s.dependency "THEOplayer-Integration-THEOads", "~> 10.6"
65+
s.dependency "THEOplayer-Integration-THEOads", "~> 10.7"
6666
end
6767

6868
if theofeatures.include?("MILLICAST")
6969
puts "Adding THEOplayer-Integration-Millicast"
70-
s.dependency "THEOplayer-Integration-Millicast", "~> 10.6"
70+
s.dependency "THEOplayer-Integration-Millicast", "~> 10.7"
7171
end
7272

7373
# Feature based connector dependencies
7474
if theofeatures.include?("SIDELOADED_TEXTTRACKS")
7575
puts "Adding THEOplayer-Connector-SideloadedSubtitle"
76-
s.dependency "THEOplayer-Connector-SideloadedSubtitle", "~> 10.6"
76+
s.dependency "THEOplayer-Connector-SideloadedSubtitle", "~> 10.7"
7777
end
7878

7979
end

src/api/theolive/TheoLiveEndpoint.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import { WebrtcOptions } from "./WebrtcOptions";
2+
13
export interface EndpointMillicastSource {
24
name: string;
35
accountId: string;
46
subscriberToken?: string;
57
directorUrl?: string;
8+
webrtc?: WebrtcOptions
69
}
710

811
/**

src/api/theolive/TheoLiveSource.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { SourceIntegrationId, TypedSource } from 'react-native-theoplayer';
2+
import { WebrtcOptions } from './WebrtcOptions';
23

34
/**
45
* Represents a source for the THEOlive integration.
@@ -21,4 +22,9 @@ export interface TheoLiveSource extends TypedSource {
2122
* The profile identifier is included as a query parameter in the discovery request to obtain a response specific to that profile.
2223
*/
2324
profile?: string;
25+
26+
/**
27+
* WebRTC configuration for a THEOlive Millicast source.
28+
*/
29+
webrtc?: WebrtcOptions;
2430
}

src/api/theolive/WebrtcOptions.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
/**
3+
* Webrtc playout delay configuration.
4+
*
5+
* This is used to configure the playout delay for a Millicast Source. This hints Webrtc
6+
* to increase the jitter buffer size.
7+
*
8+
* @category THEOlive
9+
* @remark This is a hint, and factors like network jitter and audio/video sync latency affect the actual delay applied.
10+
* @public
11+
*/
12+
export interface WebrtcPlayoutDelay {
13+
minimum: number;
14+
maximum: number;
15+
}
16+
17+
/**
18+
* WebRTC configuration for a THEOlive Millicast source.
19+
*
20+
* @category THEOlive
21+
* @public
22+
*/
23+
export interface WebrtcOptions {
24+
/**
25+
* Webrtc playout delay configuration for the Webrtc media.
26+
*/
27+
playoutDelayMs?: WebrtcPlayoutDelay;
28+
}

0 commit comments

Comments
 (0)