Skip to content

Commit 75b3dd7

Browse files
committed
hifi policy
1 parent c87e494 commit 75b3dd7

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

packages/stream_video/lib/src/models/audio_configuration_policy.dart

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc;
2222
///
2323
/// This policy treats the call as **media playback**.
2424
///
25+
/// ### HiFi Policy
26+
/// [AudioConfigurationPolicy.hiFi] is designed for **broadcasting high-fidelity
27+
/// audio**, such as:
28+
/// - Live music streaming
29+
/// - Screen sharing with stereo audio
30+
///
31+
/// This policy bypasses voice processing to enable stereo I/O and
32+
/// treats the session as media on both platforms.
33+
///
2534
/// ## Platform-Specific Differences
2635
///
2736
/// ### Android
@@ -38,6 +47,11 @@ import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc;
3847
/// - Always uses speaker/media output path
3948
/// - Treated as regular media playback
4049
///
50+
/// **HiFi Policy:**
51+
/// - Same audio settings as Viewer Policy (media volume, no processing)
52+
/// - Enables stereo input and output on the Audio Device Module
53+
/// - Optimized for broadcasting high-fidelity / stereo audio
54+
///
4155
/// ### iOS
4256
///
4357
/// **Broadcaster Policy:**
@@ -50,6 +64,11 @@ import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc;
5064
/// - Always uses speaker by default
5165
/// - Optimized for music/media quality
5266
///
67+
/// **HiFi Policy:**
68+
/// - Voice processing **bypassed** for pure, high-fidelity audio
69+
/// - Uses `playAndRecord` category for active microphone use
70+
/// - Always uses speaker by default
71+
///
5372
/// ## Custom Configuration
5473
/// - [AudioConfigurationPolicy.custom] - Full control over platform settings
5574
sealed class AudioConfigurationPolicy {
@@ -59,6 +78,8 @@ sealed class AudioConfigurationPolicy {
5978

6079
const factory AudioConfigurationPolicy.viewer() = ViewerAudioPolicy;
6180

81+
const factory AudioConfigurationPolicy.hiFi() = HiFiAudioPolicy;
82+
6283
/// Custom policy allowing full control over platform-specific settings.
6384
///
6485
/// Use this when you need specific audio configurations that differ from
@@ -180,6 +201,64 @@ class ViewerAudioPolicy extends AudioConfigurationPolicy {
180201
bool get bypassVoiceProcessing => true;
181202
}
182203

204+
/// Audio policy optimized for broadcasting high-fidelity audio.
205+
///
206+
/// Use this policy when users need to **send** high-quality audio such as:
207+
/// - Live music streaming or karaoke hosts
208+
/// - Podcast hosts or professional streamers
209+
/// - Screen sharing with stereo audio content
210+
///
211+
/// This policy bypasses voice processing (echo cancellation, noise suppression)
212+
/// and configures the audio layer for stereo I/O and media-quality output.
213+
///
214+
/// On Android, this enables stereo input and output on the Audio Device Module
215+
/// (ADM), which is required for capturing and sending stereo audio. Screen share
216+
/// audio also benefits from this — it will be captured in stereo when this
217+
/// policy is active.
218+
///
219+
/// **Requirements for stereo capture on Android:**
220+
/// 1. The call type must have HiFi audio enabled (Stream Dashboard)
221+
/// 2. The audio bitrate profile must be set to `musicHighQuality`
222+
/// 3. This policy (or any policy with `bypassVoiceProcessing: true`) must be set
223+
///
224+
/// See [AudioConfigurationPolicy] for detailed platform-specific behavior.
225+
class HiFiAudioPolicy extends AudioConfigurationPolicy {
226+
const HiFiAudioPolicy();
227+
228+
@override
229+
rtc.AppleAudioConfiguration getAppleConfiguration({
230+
bool defaultToSpeaker = false,
231+
}) {
232+
return rtc.AppleAudioConfiguration(
233+
appleAudioMode: rtc.AppleAudioMode.default_,
234+
appleAudioCategory: rtc.AppleAudioCategory.playAndRecord,
235+
appleAudioCategoryOptions: const {
236+
rtc.AppleAudioCategoryOption.defaultToSpeaker,
237+
rtc.AppleAudioCategoryOption.mixWithOthers,
238+
rtc.AppleAudioCategoryOption.allowBluetoothA2DP,
239+
rtc.AppleAudioCategoryOption.allowAirPlay,
240+
},
241+
);
242+
}
243+
244+
@override
245+
rtc.AndroidAudioConfiguration getAndroidConfiguration() {
246+
return rtc.AndroidAudioConfiguration(
247+
androidAudioMode: rtc.AndroidAudioMode.normal,
248+
androidAudioStreamType: rtc.AndroidAudioStreamType.music,
249+
androidAudioAttributesUsageType:
250+
rtc.AndroidAudioAttributesUsageType.media,
251+
androidAudioAttributesContentType:
252+
rtc.AndroidAudioAttributesContentType.music,
253+
androidAudioFocusMode: rtc.AndroidAudioFocusMode.gain,
254+
forceHandleAudioRouting: false,
255+
);
256+
}
257+
258+
@override
259+
bool get bypassVoiceProcessing => true;
260+
}
261+
183262
/// Custom audio policy with full control over platform settings.
184263
class CustomAudioPolicy extends AudioConfigurationPolicy {
185264
/// At least one of [appleConfiguration] or [androidConfiguration] should be

0 commit comments

Comments
 (0)