Skip to content

Conversation

@Brazol
Copy link
Contributor

@Brazol Brazol commented Aug 13, 2025

Resolves FLU-230

This PR provides an option to configure Android audio configuration when initializing the StreamVideo instance.

Summary by CodeRabbit

  • New Features

    • Android-specific WebRTC audio configuration for SDK initialization and applied when enabling microphone or starting remote audio.
    • New optional Android audio attributes for finer interruption/focus handling.
  • Documentation

    • Changelogs updated to document the Android audio configuration and controls.
  • Chores

    • Bumped WebRTC dependency to a newer patch version.
  • Tests

    • Test setup now ensures Flutter test binding is initialized.

@Brazol Brazol requested a review from a team as a code owner August 13, 2025 10:20
@coderabbitai
Copy link

coderabbitai bot commented Aug 13, 2025

Walkthrough

Adds an Android-specific audio configuration option (StreamVideoOptions.androidAudioConfiguration), wires it into StreamVideo initialization and runtime paths (microphone enabling and remote track start), extends interruption callback signatures for Android audio attributes, and bumps stream_webrtc_flutter dependency and changelogs.

Changes

Cohort / File(s) Summary of changes
Options & initialization
packages/stream_video/lib/src/stream_video.dart
Added StreamVideoOptions.androidAudioConfiguration (public) and, on Android, passes it to rtc.WebRTC.initialize during StreamVideo construction (fire-and-forget).
Microphone enable flow
packages/stream_video/lib/src/call/call.dart
After enabling microphone, on Android and if configured, calls rtc.Helper.setAndroidAudioConfiguration(config) inside try/catch and logs failures.
Remote track start flow
packages/stream_video/lib/src/call/session/call_session.dart
CallSession now stores a StreamVideo reference (constructor updated) and, before starting remote tracks, applies rtc.Helper.setAndroidAudioConfiguration(config) when configured.
Interruption handling API
packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart
handleCallInterruptionCallbacks signature extended with androidAudioAttributesUsageType? and androidAudioAttributesContentType? and forwarded to rtc layer.
Dependency bumps
melos.yaml, packages/*/pubspec.yaml (multiple packages)
Bumped stream_webrtc_flutter from ^1.0.10 to ^1.0.11 across melos and affected package pubspecs.
Changelogs
packages/stream_video/CHANGELOG.md, packages/stream_video_flutter/CHANGELOG.md
Added Unregistered entries documenting the new androidAudioConfiguration option.
Tests
packages/stream_video/test/src/core/client_state_test.dart
Added TestWidgetsFlutterBinding.ensureInitialized() call in test setUp.

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant StreamVideo
  participant WebRTC as rtc.WebRTC
  participant Helper as rtc.Helper

  App->>StreamVideo: new StreamVideo(options)
  alt Android && options.androidAudioConfiguration
    StreamVideo->>WebRTC: initialize({ androidAudioConfiguration })
  else
    StreamVideo->>WebRTC: initialize({})
  end

  App->>StreamVideo: enableMicrophone()
  StreamVideo-->>App: mic enabled
  alt Android && config provided
    StreamVideo->>Helper: setAndroidAudioConfiguration(config)
    Helper-->>StreamVideo: success / throws (logged)
  end
Loading
sequenceDiagram
  participant RemotePeer
  participant CallSession
  participant Helper as rtc.Helper
  participant RemoteTrack

  RemotePeer-->>CallSession: onRemoteTrackReceived(track)
  alt Android && streamVideo.options.androidAudioConfiguration
    CallSession->>Helper: setAndroidAudioConfiguration(config)
  end
  CallSession->>RemoteTrack: start()
Loading
sequenceDiagram
  participant App
  participant Notifier as RtcMediaDeviceNotifier
  participant RTC as rtc

  App->>Notifier: handleCallInterruptionCallbacks(onStart,onEnd, usage?, content?)
  Notifier->>RTC: handleCallInterruptionCallbacks(..., usage?, content?)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective (issue) Addressed Explanation
Allow changing the default Android audio configuration (FLU-230)

Out-of-scope changes

Code Change Explanation
Added test binding initialization in packages/stream_video/test/src/core/client_state_test.dart (setUp) Test hygiene change unrelated to FLU-230's objective of configurable Android audio behavior.

Possibly related PRs

Suggested reviewers

  • renefloor

Poem

"I hop where audio springs anew,
I tune the paths so callers do.
On Android I plant a little key,
So mic and track sing clear and free.
Hooray — a brighter call from me!" 🥕🎧

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 86f8706 and 01f3495.

📒 Files selected for processing (1)
  • packages/stream_video/lib/src/stream_video.dart (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stream_video/lib/src/stream_video.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: analyze_legacy_version
  • GitHub Check: stream_video_noise_cancellation
  • GitHub Check: stream_video_push_notification
  • GitHub Check: stream_video_screen_sharing
  • GitHub Check: stream_video_flutter
  • GitHub Check: stream_video
  • GitHub Check: build
  • GitHub Check: analyze
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/android-audio-configuration

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
packages/stream_video_flutter/CHANGELOG.md (1)

3-5: Wording/capitalization nit in the Added entry

Tweak phrasing to avoid repetition and capitalize Android.

Apply this diff:

-* Added option to configure android audio configuration when initializing `StreamVideo` instance by providing `androidAudioConfiguration` to `StreamVideoOptions`.
+* Added an option to configure Android audio via `androidAudioConfiguration` in `StreamVideoOptions` when initializing a `StreamVideo` instance.
packages/stream_video/CHANGELOG.md (1)

3-5: Wording/capitalization nit in the Added entry

Mirror the improved phrasing here as well.

Apply this diff:

-* Added option to configure android audio configuration when initializing `StreamVideo` instance by providing `androidAudioConfiguration` to `StreamVideoOptions`.
+* Added an option to configure Android audio via `androidAudioConfiguration` in `StreamVideoOptions` when initializing a `StreamVideo` instance.
packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart (1)

35-37: Clarify platform scope in docs for new Android-only parameters

These two parameters are Android-only. Make that explicit in the doc comment to reduce confusion for iOS/Web users.

Apply this diff to the doc lines:

-  /// [androidAudioAttributesUsageType] and [androidAudioAttributesContentType] allow you to specify
-  /// the audio attributes that will be used when requesting audio focus.
+  /// [androidAudioAttributesUsageType] and [androidAudioAttributesContentType] (Android only)
+  /// allow you to specify the audio attributes that will be used when requesting audio focus.
packages/stream_video/lib/src/call/call.dart (1)

2643-2656: Good safety: Android-only, try/catch wrapping for audio configuration

Applying the Android audio configuration after enabling the microphone is reasonable and safely guarded.

Two optional improvements to consider:

  • Order of operations: Depending on stream_webrtc_flutter semantics, setting the audio configuration before enabling the microphone may ensure audio focus/session attributes are active by the time the track is created. Verify with the plugin docs or a quick runtime check.
  • Deduplication: This configuration is also applied in CallSession._onRemoteTrackReceived and during WebRTC initialization. If the plugin treats this configuration as global, centralize to apply once per session/app to avoid redundant calls.

If you want, I can consolidate this into a single application point and open a follow-up PR.

packages/stream_video/lib/src/stream_video.dart (1)

1236-1236: Document the new public option and consider not exposing plugin types in the public API.

  • Add a short doc comment to clarify platform scope and behavior.
  • Architectural suggestion: exposing rtc.AndroidAudioConfiguration in your public API couples this package to the rtc package’s types. Consider defining a StreamVideo-owned DTO (e.g., AndroidAudioConfiguration) and mapping it to rtc types internally to reduce cross-package API coupling and future breakage risks.

Proposed documentation:

-  final rtc.AndroidAudioConfiguration? androidAudioConfiguration;
+  /// Android-only. When provided, configures the underlying WebRTC
+  /// AudioManager behavior (usage/content types, focus, mode, etc.).
+  /// If null, SDK defaults are used.
+  final rtc.AndroidAudioConfiguration? androidAudioConfiguration;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b21cc8d and 574a121.

📒 Files selected for processing (6)
  • packages/stream_video/CHANGELOG.md (1 hunks)
  • packages/stream_video/lib/src/call/call.dart (1 hunks)
  • packages/stream_video/lib/src/call/session/call_session.dart (3 hunks)
  • packages/stream_video/lib/src/stream_video.dart (4 hunks)
  • packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart (2 hunks)
  • packages/stream_video_flutter/CHANGELOG.md (1 hunks)
🔇 Additional comments (5)
packages/stream_video/lib/src/webrtc/rtc_media_device/rtc_media_device_notifier.dart (1)

62-64: LGTM: Optional Android audio attributes are correctly plumbed through

The new optional parameters are added to the public API and forwarded to rtc.handleCallInterruptionCallbacks with named args. Backward compatible and clear.

Also applies to: 69-71

packages/stream_video/lib/src/call/session/call_session.dart (2)

119-119: LGTM: Private field for StreamVideo

Storing the StreamVideo reference for later use is appropriate.


76-77: All CallSession constructors now include streamVideo

  • CallSessionFactory.makeCallSession returns CallSession(..., streamVideo: streamVideo, …).
  • In packages/stream_video/lib/src/call/call.dart, sessionFactory.makeCallSession(…, streamVideo: _streamVideo, …) is present.
  • Tests in call_test_helpers.dart and call_test.dart have been updated to pass or mock the streamVideo: parameter.

No further updates required.

packages/stream_video/lib/src/stream_video.dart (2)

10-10: Import looks correct and scoped via alias.

The new rtc import is used for both initialization and the public type in options. No concerns here.


1207-1208: Constructor parameter addition looks good.

Optional and defaulting to null is appropriate. No functional issues from this change alone.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
packages/stream_video/lib/src/call/session/call_session.dart (1)

894-907: Apply Android audio configuration only once per session to avoid redundant calls

Good platform/audio guards and error handling. However, this still executes on every remote audio track. Apply once per session and short-circuit subsequent calls.

Apply this diff to gate by a one-time flag and set it on success:

-    if (CurrentPlatform.isAndroid &&
-        remoteTrack.isAudioTrack &&
-        _streamVideo.options.androidAudioConfiguration != null) {
+    if (CurrentPlatform.isAndroid &&
+        remoteTrack.isAudioTrack &&
+        !_androidAudioConfigApplied &&
+        _streamVideo.options.androidAudioConfiguration != null) {
       try {
         await rtc.Helper.setAndroidAudioConfiguration(
           _streamVideo.options.androidAudioConfiguration!,
         );
+        _androidAudioConfigApplied = true;
       } catch (e) {
         _logger.w(
           () =>
               '[onRemoteTrackReceived] Failed to apply Android audio configuration: $e',
         );
       }
     }

Add this field to the class (near other fields):

// Tracks whether Android audio configuration has been applied this session.
bool _androidAudioConfigApplied = false;

Optional: Given the config is also applied during WebRTC.initialize and after enabling microphone, consider centralizing to a single application point (if plugin semantics allow) to avoid duplication.

packages/stream_video/lib/src/stream_video.dart (1)

179-187: Guard against null and platform; fix potential null-deref and handle unawaited Future

options.androidAudioConfiguration!.toMap() will throw when the option is null. Also, only initialize with the Android configuration on Android, and capture errors on the unawaited Future.

Apply this diff:

-    unawaited(
-      rtc.WebRTC.initialize(
-        options: {
-          if (CurrentPlatform.isAndroid)
-            'androidAudioConfiguration':
-                options.androidAudioConfiguration!.toMap(),
-        },
-      ),
-    );
+    if (CurrentPlatform.isAndroid && options.androidAudioConfiguration != null) {
+      unawaited(
+        rtc.WebRTC.initialize(
+          options: {
+            'androidAudioConfiguration':
+                options.androidAudioConfiguration!.toMap(),
+          },
+        ).catchError((e, stk) {
+          _logger.w(
+            () =>
+                '[init] WebRTC.initialize(androidAudioConfiguration) failed: $e',
+          );
+        }),
+      );
+    }

Note: This keeps the initialization focused on Android when the option is present and avoids constructor-time crashes.

🧹 Nitpick comments (1)
packages/stream_video/lib/src/stream_video.dart (1)

209-210: Consider documenting the new constructor option

Add a short dartdoc on the parameter to surface it in generated docs (mirroring the field’s doc once added).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 574a121 and 67927df.

📒 Files selected for processing (2)
  • packages/stream_video/lib/src/call/session/call_session.dart (3 hunks)
  • packages/stream_video/lib/src/stream_video.dart (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: stream_video_push_notification
  • GitHub Check: stream_video_noise_cancellation
  • GitHub Check: stream_video
  • GitHub Check: stream_video_screen_sharing
  • GitHub Check: stream_video_flutter
  • GitHub Check: analyze
  • GitHub Check: build
  • GitHub Check: analyze_legacy_version
🔇 Additional comments (4)
packages/stream_video/lib/src/call/session/call_session.dart (1)

76-76: LGTM: Injecting StreamVideo to access options is appropriate

Storing the client reference for session-scoped option lookups is sensible and consistent with the surrounding design.

Also applies to: 119-119

packages/stream_video/lib/src/stream_video.dart (3)

10-10: LGTM: Importing stream_webrtc_flutter for Android audio config API

The alias and import are correct for both WebRTC.initialize and configuration types.


1238-1239: LGTM: New public option is well-typed and scoped

Exposing rtc.AndroidAudioConfiguration? on StreamVideoOptions aligns with the new feature.


179-187: Review Android audio configuration calls for duplication

I found three places where the Android audio configuration is applied:

• packages/stream_video/lib/src/stream_video.dart (≈L179)

  • rtc.WebRTC.initialize(options: { androidAudioConfiguration: … })

• packages/stream_video/lib/src/call/call.dart (≈L2645)

  • rtc.Helper.setAndroidAudioConfiguration after enabling the microphone

• packages/stream_video/lib/src/call/session/call_session.dart (≈L896)

  • rtc.Helper.setAndroidAudioConfiguration before starting remote audio tracks

Please verify against the underlying WebRTC plugin docs whether all three invocations are required. If the plugin only needs a single configuration call (e.g. at initialize), consider consolidating these into one shared helper or removing redundant calls to reduce duplication.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/stream_video_push_notification/pubspec.yaml (1)

27-27: Dependency bump to stream_webrtc_flutter ^1.0.11 looks correct.

Matches the workspace-wide upgrade and aligns with the new Android audio configuration feature.

Consider running melos bootstrap afterwards to refresh lockfiles across the workspace to avoid version drift.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67927df and b70b9f1.

📒 Files selected for processing (6)
  • melos.yaml (1 hunks)
  • packages/stream_video/pubspec.yaml (1 hunks)
  • packages/stream_video_flutter/example/pubspec.yaml (1 hunks)
  • packages/stream_video_flutter/pubspec.yaml (1 hunks)
  • packages/stream_video_noise_cancellation/pubspec.yaml (1 hunks)
  • packages/stream_video_push_notification/pubspec.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/stream_video_noise_cancellation/pubspec.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: analyze
  • GitHub Check: stream_video_noise_cancellation
  • GitHub Check: stream_video_push_notification
  • GitHub Check: build
  • GitHub Check: stream_video_screen_sharing
  • GitHub Check: stream_video_flutter
  • GitHub Check: stream_video
🔇 Additional comments (4)
packages/stream_video/pubspec.yaml (1)

34-34: APIs present in stream_webrtc_flutter ^1.0.11
Verified that version 1.0.11 exposes both the AndroidAudioConfiguration class and the setAndroidAudioConfiguration method.
• lib/src/native/android/audio_configuration.dart – class AndroidAudioConfiguration & its setAndroidAudioConfiguration
• lib/src/helper.dart – Helper.setAndroidAudioConfiguration
• android/src/main/java/.../MethodCallHandlerImpl – handles "setAndroidAudioConfiguration"

No risk of missing-method errors; nothing further required here.

melos.yaml (1)

25-25: All stream_webrtc_flutter versions are consistently set to ^1.0.11
Validation confirms melos.yaml (line 25) and every pubspec.yaml in the repository reference stream_webrtc_flutter: ^1.0.11. No further changes required.

packages/stream_video_flutter/example/pubspec.yaml (1)

33-33: Example app dependency aligned to ^1.0.11.

Keeps the example in sync with workspace versions; good to reduce incompatibility during demos and CI builds.

packages/stream_video_flutter/pubspec.yaml (1)

26-26: UI package dependency bump looks good and consistent.

No additional changes required here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/stream_video/test/src/core/client_state_test.dart (1)

18-19: Optional: Initialize the binding once to avoid redundant calls

You can initialize the binding once per group (or file) rather than per test. It’s idempotent, but this keeps setup lean.

  • Remove the per-test initialization:
-      TestWidgetsFlutterBinding.ensureInitialized();
-
  • Add a one-time init in this group:
setUpAll(() {
  TestWidgetsFlutterBinding.ensureInitialized();
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b70b9f1 and 86f8706.

📒 Files selected for processing (1)
  • packages/stream_video/test/src/core/client_state_test.dart (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: analyze
  • GitHub Check: build
  • GitHub Check: stream_video_push_notification
  • GitHub Check: stream_video_noise_cancellation
  • GitHub Check: stream_video_screen_sharing
  • GitHub Check: stream_video
  • GitHub Check: stream_video_flutter
🔇 Additional comments (1)
packages/stream_video/test/src/core/client_state_test.dart (1)

18-19: Initialize Flutter test binding to prevent platform channel errors — good fix

Calling TestWidgetsFlutterBinding.ensureInitialized() before constructing StreamVideo prevents binding-related errors when platform channels are touched (e.g., during WebRTC/Android audio configuration setup). This aligns with the new Android audio configuration path.

@codecov
Copy link

codecov bot commented Aug 14, 2025

Codecov Report

❌ Patch coverage is 9.09091% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 4.83%. Comparing base (b21cc8d) to head (01f3495).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...tream_video/lib/src/call/session/call_session.dart 0.00% 8 Missing ⚠️
packages/stream_video/lib/src/call/call.dart 14.28% 6 Missing ⚠️
packages/stream_video/lib/src/stream_video.dart 14.28% 6 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff          @@
##            main   #1046   +/-   ##
=====================================
  Coverage   4.83%   4.83%           
=====================================
  Files        577     577           
  Lines      38802   38824   +22     
=====================================
+ Hits        1875    1877    +2     
- Misses     36927   36947   +20     

☔ View full report in Codecov by Sentry.
📢 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.

@Brazol Brazol merged commit a2b51c1 into main Aug 14, 2025
15 checks passed
@Brazol Brazol deleted the feat/android-audio-configuration branch August 14, 2025 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants