High Fidelity Audio

For scenarios like live music, podcasts, or professional streaming, you may want to deliver audio that sounds natural and unprocessed. Our SDK provides APIs that let you tune the audio pipeline for higher fidelity.

HiFi Mode

HiFi mode provides an enhanced audio experience by doing two things under the hood:

  1. Studio quality bitrate – switches to a high-quality bitrate (128 kbps) for audio publishing.
  2. Disables audio processing – echo cancellation, noise suppression, and automatic gain control are turned off.

The SDK supports three audio bitrate profiles:

  • SfuAudioBitrateProfile.voiceStandard – SDK default profile for standard voice calls with audio processing enabled (64 kbps)
  • SfuAudioBitrateProfile.voiceHighQuality – High-quality voice profile with audio processing enabled (128 kbps)
  • SfuAudioBitrateProfile.musicHighQuality – HiFi mode for music and professional audio with audio processing disabled (128 kbps)

Allow HiFi Audio on the Call Type

The fastest way to enable high-quality audio is by turning on HiFi mode. HiFi mode is a one-step toggle that:

  • Enables stereo capture (your app records and transmits two audio channels)
  • Uses studio-quality music bitrate
  • Disables all audio processing (echo cancellation, noise suppression, and automatic gain control)

HiFi audio is allowed by default for the livestream call type.

To enable HiFi audio for other call types, go to the Stream Dashboard and toggle the Allow HiFi audio setting for your call type. This option is available under Video & Audio > Call Types > [call type] > Settings > Allow HiFi audio.

Setting the Audio Bitrate Profile

To enable HiFi audio, set the audio bitrate profile to musicHighQuality before joining the call:

// Enable HiFi audio before joining
call.setAudioBitrateProfile(SfuAudioBitrateProfile.musicHighQuality);

// Join the call after setting the profile
await call.join();

The audio bitrate profile must be set before joining the call. Once the call is joined, changes to the audio bitrate profile will be ignored.

Enabling Stereo Playout in the SDK

The SDK offers two ways to enable stereo audio playback, allowing users to experience true stereo sound:

Using Audio Configuration Policies

The SDK provides built-in audio configuration policies that automatically configure stereo playout based on the user's role:

ViewerAudioPolicy

Use ViewerAudioPolicy for passive consumption of audio/video content. This policy:

  • Enables stereo playout
  • Disables voice processing (echo cancellation, noise suppression)
  • Optimizes for music/media quality
StreamVideo(
  apiKey,
  user: user,
  options: StreamVideoOptions(
    audioConfigurationPolicy: const AudioConfigurationPolicy.viewer(),
  ),
  // ... other parameters
);

BroadcasterAudioPolicy

Use BroadcasterAudioPolicy (the default) for active participation in calls. This policy:

  • Uses mono playout
  • Enables voice processing (echo cancellation, noise suppression)
  • Optimizes for voice clarity
StreamVideo(
  apiKey,
  user: user,
  options: StreamVideoOptions(
    audioConfigurationPolicy: const AudioConfigurationPolicy.broadcaster(),
  ),
  // ... other parameters
);

Platform-Specific Behavior

Android

PolicyVolume ControlAudio ProcessingStereo
BroadcasterAudioPolicyCall volumeEnabled (echo cancellation, noise suppression)No
ViewerAudioPolicyMedia volumeDisabled (higher fidelity)Yes
HiFiAudioPolicyMedia volumeDisabled (higher fidelity)Yes

iOS

PolicyVoice ProcessingAudio Output
BroadcasterAudioPolicyEnabledOptimized for voice
ViewerAudioPolicyBypassedAlways speaker, optimized for media
HiFiAudioPolicyBypassedAlways speaker, optimized for media

On iOS, stereo playout is only supported when the microphone is not active. This is due to a WebRTC limitation in the underlying AVAudioUnit implementation. When the microphone activates, the audio unit gets configured for mono output to support microphone input. Muting the microphone won't restore stereo playout – the only way to restore it is to leave and rejoin the call.

Use ViewerAudioPolicy only for participants who don't have (and won't be granted) the sendAudio capability.

Custom Audio Configuration

For more control over audio settings, use AudioConfigurationPolicy.custom(). You can provide only the configuration for the platform you want to customize, the other platform falls back to the base policy.

import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc;

StreamVideo(
  apiKey,
  user: user,
  options: StreamVideoOptions(
    audioConfigurationPolicy: AudioConfigurationPolicy.custom(
      basePolicy: const BroadcasterAudioPolicy(),
      bypassVoiceProcessing: true,
      androidConfiguration: rtc.AndroidAudioConfiguration(
        androidAudioMode: rtc.AndroidAudioMode.normal,
        androidAudioStreamType: rtc.AndroidAudioStreamType.music,
        androidAudioAttributesUsageType: rtc.AndroidAudioAttributesUsageType.media,
        androidAudioAttributesContentType: rtc.AndroidAudioAttributesContentType.music,
        androidAudioFocusMode: rtc.AndroidAudioFocusMode.gain,
        forceHandleAudioRouting: false,
      ),
      appleConfiguration: ({bool defaultToSpeaker = false}) => rtc.AppleAudioConfiguration(
        appleAudioMode: rtc.AppleAudioMode.default_,
        appleAudioCategory: rtc.AppleAudioCategory.playAndRecord,
        appleAudioCategoryOptions: {
          if (defaultToSpeaker) rtc.AppleAudioCategoryOption.defaultToSpeaker,
          rtc.AppleAudioCategoryOption.mixWithOthers,
          rtc.AppleAudioCategoryOption.allowBluetoothA2DP,
          rtc.AppleAudioCategoryOption.allowAirPlay,
        },
      ),
    ),
  ),
  // ... other parameters
);

Changing Audio Configuration at Runtime

To change the audio configuration after the SDK has been initialized, use RtcMediaDeviceNotifier:

This method should only be called before starting a call, not during an active call. Calling reinitializeAudioConfiguration during an active call will close and dispose all existing tracks and peer connections, effectively disrupting the ongoing session.

import 'package:stream_video/stream_video.dart';

// Switch to viewer mode for stereo playout
await RtcMediaDeviceNotifier.instance.reinitializeAudioConfiguration(
  const AudioConfigurationPolicy.viewer(),
);

// Switch back to broadcaster mode
await RtcMediaDeviceNotifier.instance.reinitializeAudioConfiguration(
  const AudioConfigurationPolicy.broadcaster(),
);

Stereo Capture on Android

While stereo playout is about hearing incoming audio in stereo, stereo capture is about sending stereo audio to other participants. On Android, three things must be in place for stereo capture to work:

  1. HiFi audio enabled on the call type – Toggle Allow HiFi audio in the Stream Dashboard for the call type you are using.

  2. Audio bitrate profile set to musicHighQuality – This must be set before joining the call. It switches to a 128 kbps bitrate and disables echo cancellation, noise suppression, and automatic gain control.

  3. Audio configuration policy with bypassVoiceProcessing: true – This configures the Android Audio Device Module (ADM) for stereo input and output. The SDK provides HiFiAudioPolicy as a preconfigured policy for this purpose.

All three conditions must be met. If any one is missing, audio will fall back to mono.

Using HiFiAudioPolicy

The SDK provides HiFiAudioPolicy, a preconfigured policy designed for broadcasting high-fidelity stereo audio. It bypasses voice processing and configures the Android audio layer for media-quality stereo I/O:

// Initialize StreamVideo with HiFi policy
final streamVideo = StreamVideo(
  apiKey,
  user: user,
  options: const StreamVideoOptions(
    audioConfigurationPolicy: AudioConfigurationPolicy.hiFi(),
  ),
  // ... other parameters
);

// Create a call (the call type must have HiFi audio enabled)
final call = streamVideo.call(callType: 'livestream', callId: 'my-stream');

// Set the music profile before joining
call.setAudioBitrateProfile(SfuAudioBitrateProfile.musicHighQuality);

// Join the call
await call.join();

HiFiAudioPolicy shares the same platform-level audio settings as ViewerAudioPolicy. The difference is semantic — HiFiAudioPolicy is intended for senders of high-fidelity audio (hosts, streamers), while ViewerAudioPolicy is intended for passive listeners.

Screen Share Audio

Screen share audio on Android also benefits from stereo capture. When the ADM is configured for stereo (via HiFiAudioPolicy or any policy with bypassVoiceProcessing: true), screen audio is captured in stereo as well. This means that if you screen share a video with stereo audio, remote participants will hear it in stereo.

No additional configuration is required — screen share audio automatically matches the ADM's channel configuration.

Complete Example: Livestream with HiFi Audio

Here's a complete example showing how to set up a livestream host with HiFi stereo audio:

// Initialize StreamVideo with HiFi policy for stereo capture
final streamVideo = StreamVideo(
  apiKey,
  user: host,
  options: const StreamVideoOptions(
    audioConfigurationPolicy: AudioConfigurationPolicy.hiFi(),
  ),
);

// Create a livestream call (HiFi audio must be enabled on the call type)
final call = streamVideo.call(callType: 'livestream', callId: 'my-stream');

// Set HiFi audio profile before joining
call.setAudioBitrateProfile(SfuAudioBitrateProfile.musicHighQuality);

// Join as a host — audio will be captured and sent in stereo
await call.join();

And for a viewer watching the livestream with stereo playout:

// Initialize StreamVideo with viewer policy for stereo
final streamVideo = StreamVideo(
  apiKey,
  user: viewer,
  options: const StreamVideoOptions(
    audioConfigurationPolicy: AudioConfigurationPolicy.viewer(),
  ),
);

// Join the livestream as a viewer
final call = streamVideo.call(callType: 'livestream', callId: 'my-stream');
await call.join();

When to Use Each Configuration

Use CaseAudio Bitrate ProfileAudio Configuration Policy
Standard voice callvoiceStandard (default)BroadcasterAudioPolicy (default)
High-quality podcastvoiceHighQualityBroadcasterAudioPolicy
Live music streaming (host)musicHighQualityHiFiAudioPolicy
Screen sharing with stereo audiomusicHighQualityHiFiAudioPolicy
Livestream viewerN/AViewerAudioPolicy

Interaction with Noise Cancellation

When using musicHighQuality profile, the SDK automatically handles noise cancellation:

  • If noise cancellation is configured, it will be automatically disabled when switching to musicHighQuality profile
  • When switching back to a voice profile, noise cancellation will be re-enabled if it was configured

This ensures that HiFi audio mode delivers unprocessed, natural sound without any interference from audio processing features.