Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/bright-bitrates-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"client-sdk-android": minor
---

Add `Room.setPublisherInitialVideoBitrate` to configure the publisher PeerConnection's current and maximum video bitrate after connecting.
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,26 @@ internal constructor(
return SenderTransceiverHandle(publisher, transceiver, sessionState)
}

/**
* Sets the publisher PeerConnection's initial video bitrate.
*/
internal suspend fun setPublisherInitialVideoBitrate(
initialBitrateBps: Int,
maxBitrateBps: Int,
): Boolean {
require(initialBitrateBps > 0)
require(maxBitrateBps >= initialBitrateBps)

val publisherTransport = publisher ?: return false
return publisherTransport.withPeerConnection {
setBitrate(
null,
initialBitrateBps,
maxBitrateBps,
)
} == true
}

fun updateSubscriptionPermissions(
allParticipants: Boolean,
participantTrackPermissions: List<ParticipantTrackPermission>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1623,6 +1623,31 @@ constructor(
*/
fun getPublisherRTCStats(callback: RTCStatsCollectorCallback) = engine.getPublisherRTCStats(callback)

/**
* Sets the local publisher's initial video bitrate.
*
* Call this after the room has connected and before or immediately after publishing video.
* For example:
* ```
* room.setPublisherInitialVideoBitrate(
* initialBitrateBps = 1_500_000,
* maxBitrateBps = 3_500_000,
* )
* ```
*
* @return `true` when WebRTC accepts the bitrate configuration, otherwise `false`.
* @throws IllegalArgumentException if either bitrate is invalid.
*/
suspend fun setPublisherInitialVideoBitrate(
initialBitrateBps: Int,
maxBitrateBps: Int,
): Boolean {
return engine.setPublisherInitialVideoBitrate(
initialBitrateBps = initialBitrateBps,
maxBitrateBps = maxBitrateBps,
)
}

/**
* Get stats for the subscriber peer connection.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class MockPeerConnection(
private var closed = false
var localDesc: SessionDescription? = null
var remoteDesc: SessionDescription? = null
var lastBitrateSettings: Triple<Int?, Int?, Int?>? = null

private val signalStateMachine = SignalStateMachine { newState ->
observer?.onSignalingChange(newState)
Expand Down Expand Up @@ -210,6 +211,7 @@ class MockPeerConnection(
}

override fun setBitrate(min: Int?, current: Int?, max: Int?): Boolean {
lastBitrateSettings = Triple(min, current, max)
return true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,22 @@ class RTCEngineMockE2ETest : MockE2ETest() {
)
}

@Test
fun setPublisherInitialVideoBitrate() = runTest {
connect()

val applied = room.setPublisherInitialVideoBitrate(
initialBitrateBps = 1_500_000,
maxBitrateBps = 3_500_000,
)

assertTrue(applied)
assertEquals(
Triple(null, 1_500_000, 3_500_000),
getPublisherPeerConnection().lastBitrateSettings,
)
}

@Test
fun iceSubscriberConnect() = runTest {
connect()
Expand Down