Skip to content

Microfone toggle flickers and doesnt set the correct state #1149

@RazvanTamazlicariu

Description

@RazvanTamazlicariu

Watch video: https://youtube.com/shorts/Ws7Ei5yXblw

Reproducible on Android and iOS:

Flutter doctor:

[✓] Flutter (Channel stable, 3.35.7, on macOS 26.0.1 25A362 darwin-arm64, locale en-RO)
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0)
[✓] Xcode - develop for iOS and macOS (Xcode 26.0.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2025.2)
[✓] Connected device (5 available)
[✓] Network resources 


**Stream versions:**
  stream_video: ^1.2.2
  stream_video_flutter: ^1.2.2
  stream_video_push_notification: ^1.2.2
  stream_chat_flutter: ^9.22.0

Code Sample:

class VideoCallView extends StatefulWidget {
  const VideoCallView({super.key});

  @override
  State<VideoCallView> createState() => _VideoCallViewState();
}

class _VideoCallViewState extends State<VideoCallView> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: LoadingScaffold<VideoCallBloc, VideoCallState>(
        isLoading: (state) => state.isLoading,
        body: BlocBuilder<VideoCallBloc, VideoCallState>(
          builder: (context, state) {
            return state.maybeMap(
              orElse: () => empty,
              started: (value) => StreamCallContainer(
                call: value.call,
                callContentWidgetBuilder: (context, call) {
                  return StreamCallContent(
                    call: call,
                    callAppBarWidgetBuilder: (context, call) => AppBar(
                      title: Text(
                        call.state.valueOrNull?.status.toStatusString() ?? '',
                        style: context.bodyMedium?.bold.setColor(
                          context.theme.appBarTheme.foregroundColor,
                        ),
                      ),
                    ),
                  );
                },
                incomingCallWidgetBuilder: (context, call) {
                  return StreamIncomingCallContent(
                    call: call,
                    onDeclineCallTap: context.read<VideoCallBloc>().endCall,
                  );
                },
              ),
            );
          },
        ),
      ),
    );
  }
}

I copied the Implementation of your microphone button and added a few debug logs and got this

flutter: Local participant change microfone with success
flutter: Local participant change microfone - enabled: true
flutter: Local participant change microfone - enabled: false
flutter: Local participant change microfone - enabled: true
flutter: Local participant change microfone - enabled: false

using this prints:

import 'package:alto_flutter/features/meeting/presentation/videoCall/widgets/call_controls/call_control_option.dart';
import 'package:flutter/material.dart';
import 'package:stream_video_flutter/stream_video_flutter.dart'
    hide CallControlOption;

/// A widget that represents a call control option to toggle if the microphone
/// is on or off.
class ToggleMicrophoneOption extends StatelessWidget {
  /// Creates a new instance of [ToggleMicrophoneOption].
  const ToggleMicrophoneOption({
    super.key,
    required this.call,
    this.enabledMicrophoneIcon = Icons.mic_rounded,
    this.disabledMicrophoneIcon = Icons.mic_off_rounded,
    this.enabledMicrophoneIconColor,
    this.disabledMicrophoneIconColor,
    this.enabledMicrophoneBackgroundColor,
    this.disabledMicrophoneBackgroundColor,
  });

  /// Represents a call.
  final Call call;

  /// The icon that is shown when the microphone is enabled.
  final IconData enabledMicrophoneIcon;

  /// The icon that is shown when the microphone is disabled.
  final IconData disabledMicrophoneIcon;

  /// Color of the icon when microphone is enabled
  final Color? enabledMicrophoneIconColor;

  /// Color of the icon when microphone is disabled
  final Color? disabledMicrophoneIconColor;

  /// Color of the background when microphone is enabled
  final Color? enabledMicrophoneBackgroundColor;

  /// Color of the background when microphone is disabled
  final Color? disabledMicrophoneBackgroundColor;

  @override
  Widget build(BuildContext context) {
    Widget buildContent(bool enabled) {
      return CallControlOption(
        icon: enabled
            ? Icon(enabledMicrophoneIcon)
            : Icon(disabledMicrophoneIcon),
        iconColor: enabled
            ? enabledMicrophoneIconColor
            : disabledMicrophoneIconColor,
        backgroundColor: enabled
            ? enabledMicrophoneBackgroundColor
            : disabledMicrophoneBackgroundColor,
        onPressed: () async {
          final response = await call.setMicrophoneEnabled(enabled: !enabled);
          response.fold(
            success: (success) {
              print('Local participant change microfone with success');
            },
            failure: (failure) {
              print('Local participant microfone error: ${failure.error}');
            },
          );
        },
      );
    }

    return PartialCallStateBuilder(
      call: call,
      selector: (state) => state.localParticipant?.isAudioEnabled ?? false,
      builder: (_, enabled) {
        print('Local participant change microfone - enabled: $enabled');
        return buildContent(enabled);
      },
    );
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions