Skip to content

fix(llc)!: make Call.setAudioBitrateProfile async and report a failed switch - #1561

Open
renefloor wants to merge 4 commits into
v2from
renefloor/flu-1176-async-audio-bitrate-profile
Open

renefloor wants to merge 4 commits into
v2from
renefloor/flu-1176-async-audio-bitrate-profile

Conversation

@renefloor

@renefloor renefloor commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Resolves FLU-1176. Follow-up from the review of #1559.

What changed

  • Call.setAudioBitrateProfile returns Future<Result<None>>. It awaits the audio processing toggle, the iOS stereo playout preference and the microphone recapture, and returns the recapture's result.
  • RtcManager.changeDefaultAudioConstraints and RtcPublisher.restartLiveAudioTracks return a Result. They fail when a live microphone could not be captured again and was reported muted. A microphone published again during the switch is not a failure.

Behaviour

  • When the microphone could not be captured again, the call keeps the new profile. The new default constraints are already set, so the next unmute captures with them.
  • Only the microphone recapture fails the switch. A failed audio processing toggle (e.g. no noise cancellation permission) or iOS stereo preference is logged as a warning.
  • Switches run one at a time, in the order they were made, so two quick switches can't leave the call state and the microphone constraints out of sync.

Breaking (v2)

The return type of Call.setAudioBitrateProfile changes. Changelog line under ### ⚠️ Breaking.

Testing

  • call_audio_processing_test.dart: existing tests await the result; new tests for the stereo and mono constraints, a failed audio processing toggle being only logged, two quick switches applying in order, and a failed recapture keeping the new profile.
  • rtc_manager_audio_constraints_test.dart: asserts the result, including the failure case.
  • Not tried on a device.

🤖 Generated with Claude Code

… switch

setAudioBitrateProfile now awaits the audio processing toggle, the iOS
stereo playout preference and the microphone recapture, and fails when
the microphone could not be captured again. The call keeps the new
profile then; the microphone is reported muted and picks the new
constraints up when it is unmuted.

RtcManager.changeDefaultAudioConstraints and
RtcPublisher.restartLiveAudioTracks return a Result.

Refs FLU-1176

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 17c119ac-9fdb-4af1-ac2d-c41b033e4d9b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions github-actions Bot added the v2 label Nov 4, 2026
renefloor and others added 2 commits November 4, 2026 15:43
Two quick switches could finish out of order, because stopping audio
processing waits on the SFU while starting it can fail at once. The call
state then said voice while the microphone captured in stereo without
voice processing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@renefloor
renefloor marked this pull request as ready for review November 4, 2026 14:46
@renefloor
renefloor requested a review from a team as a code owner November 4, 2026 14:46
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

📊 Cognitive Complexity Analysis

Net Delta: +10 | Added: 2 | Increased: 1 | Improved: 1 | Removed: 0 | Violations: 0

Status Declaration Location Delta Score
🟡 RtcPublisher.restartLiveAudioTracks packages/stream_video/lib/src/webrtc/publisher/rtc_publisher.dart:L163-213 +3 10 -> 13
🔵 Call._switchAudioBitrateProfile packages/stream_video/lib/src/call/call.dart:L1545-1585 +10 new -> 10
🔵 Call._notifySfu packages/stream_video/lib/src/call/call.dart:L1445-1456 +3 new -> 3
🟢 Call.setAudioBitrateProfile packages/stream_video/lib/src/call/call.dart:L1525-1543 -6 7 -> 1

@codecov

codecov Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.62%. Comparing base (a81a9aa) to head (ea604e8).
⚠️ Report is 33 commits behind head on v2.

Files with missing lines Patch % Lines
packages/stream_video/lib/src/call/call.dart 75.00% 4 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##               v2    #1561   +/-   ##
=======================================
  Coverage   55.61%   55.62%           
=======================================
  Files         484      484           
  Lines       33077    33087   +10     
=======================================
+ Hits        18396    18404    +8     
- Misses      14681    14683    +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@renefloor renefloor added the ready Pull request ready to be reviewed label Nov 4, 2026
final stereo = profile == SfuAudioBitrateProfile.musicHighQuality;

if (_host.isAudioProcessorConfigured()) {
final processing = stereo

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awaiting this now puts an SFU round trip in front of the mic recapture: startAudioProcessing / stopAudioProcessing await _session?.notifyNoiseCancellationStarted/Stopped(), which is an SFU request. Before, it was unawaited and ran alongside the recapture. Now the recapture, and any switch queued behind _audioBitrateProfileLock, waits on it, so a slow SFU or a reconnect in progress stalls the profile switch until that request times out.

Since the toggle's result is only logged anyway, could we keep it off the critical path, e.g. leave it unawaited as before, or run it concurrently with the recapture (Future.wait) and log its failure afterwards?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed in 94aa5dd. I didn't go back to an unawaited toggle, because two quick switches could then run start/stop out of order. Instead, startAudioProcessing / stopAudioProcessing still await the local setAudioProcessingEnabled call and the state update, then send the SFU notification without awaiting it and log a failure. The switch keeps start/stop in order under the lock, and the SFU request is no longer on the critical path. I added a test where the SFU notification never completes: both switches still finish and recapture in order.

@github-actions github-actions Bot added pending Review comments waiting to be addressed and removed ready Pull request ready to be reviewed labels Nov 10, 2026
Audio processing start/stop now notify the SFU without awaiting it, so
the microphone recapture and queued profile switches no longer stall on
a slow SFU request. A failed notification is logged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

SDK Size

title v2 branch diff status
android_stream_video 15.14 MB 15.14 MB 0 KB 🟢
android_stream_video_flutter 17.48 MB 17.48 MB 0 KB 🟢
pub_stream_video 1.0 MB 1.0 MB 0 KB 🟢
pub_stream_video_filters 0.04 MB 0.04 MB 0 KB 🟢
pub_stream_video_flutter 1.0 MB 1.0 MB 0 KB 🟢
pub_stream_video_noise_cancellation 0.05 MB 0.05 MB 0 KB 🟢
pub_stream_video_push_notification 0.36 MB 0.36 MB 0 KB 🟢
pub_stream_video_screen_sharing 0.01 MB 0.01 MB 0 KB 🟢

Measured on 94aa5dd.

@github-actions

Copy link
Copy Markdown

Size Breakdown

What each SDK adds to an empty release app, per Dart package and native library. Dart sizes are uncompressed symbol sizes. Open the sdk-size-analysis artifacts of this run in the DevTools App Size tool to drill down further.

This run does not measure ios.

Measured on 94aa5dd.

android · stream_video: 15.1 MB (0)
Component Size Δ vs v2
native:libjingle_peerconnection_so.so 11.96 MB 0
package:stream_video 1.11 MB -0.0 KB
classes.dex 261.9 KB 0
dart:@unknown 260.1 KB +0.0 KB
dart:_http 154.1 KB 0
package:protobuf 146.0 KB 0
dart:mixin_deduplication 143.8 KB -0.0 KB
native:libdartjni.so 121.7 KB 0
dart:io 99.3 KB 0
dart:async 75.6 KB 0
package:stream_core 69.5 KB 0
package:stream_webrtc_flutter 55.3 KB 0
package:rxdart 54.3 KB 0
package:dio 53.2 KB 0
dart:core 52.2 KB 0
other (71) 537.7 KB +0.0 KB
android · stream_video_flutter: 17.41 MB (0)
Component Size Δ vs v2
native:libjingle_peerconnection_so.so 11.96 MB 0
package:stream_video 1.16 MB -0.0 KB
package:flutter 699.1 KB +0.0 KB
classes.dex 454.8 KB 0
dart:@unknown 434.9 KB +0.0 KB
dart:mixin_deduplication 362.7 KB 0
package:stream_video_flutter 205.7 KB 0
dart:_http 154.1 KB 0
package:protobuf 145.2 KB 0
dart:io 136.5 KB 0
package:stream_core_flutter 124.2 KB 0
native:libdartjni.so 121.7 KB 0
assets 118.5 KB 0
package:hive_ce 99.2 KB 0
dart:@shared 84.2 KB -0.0 KB
other (99) 1.22 MB 0

@renefloor renefloor added ready Pull request ready to be reviewed and removed pending Review comments waiting to be addressed labels Nov 11, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready Pull request ready to be reviewed v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants