-
Notifications
You must be signed in to change notification settings - Fork 46
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Using triggeriOSAudioRouteSelectionUI from RtcMediaDeviceNotifier.instance seems to be unable to update audioOutputDevice from call.state.valueOrNull.audioOutputDevice
This is how we trigger audio output changes:
/// Toggle Outputs devices.
/// I.e: Switch outputs (listenable) to Speaker, headphones, earpieces, etc...
///
/// @params: [Call]
FutureOr<void> onToggleSpeaker(Call call) async {
// state = call;
final callState = call.state.valueOrNull;
if (callState == null) {
return;
}
// If current device is IOS, we want to delegate to system auto audio routing
if (CurrentPlatform.isIos) {
await _deviceNotifier.triggeriOSAudioRouteSelectionUI();
return;
}
// If current device is Android, we want to display a list of availabes
// audio outputs and let user choose from them.
await _showAvaialbeOutputsDevices(
call: call,
onDevicePressed: (output, input) async {
await call.setAudioOutputDevice(output);
await call.setAudioInputDevice(input);
},
);
}This is the log that we try to implement a native call to get current selected audio outputs
![]()
Code Example:
Future<void> _observeiOSAudioChanges(MethodCall method) async {
if (method.method == 'onAudioRouteChange') {
final Map<dynamic, dynamic> deviceInfo =
method.arguments as Map<dynamic, dynamic>;
final String label = deviceInfo['label'] as String;
final String deviceId = deviceInfo['deviceId'] as String;
final String kindAlias = deviceInfo['kind'] as String;
// Use the provided factory method for safe enum conversion
final RtcMediaDeviceKind kind = RtcMediaDeviceKind.fromAlias(kindAlias);
// Map the incoming data to an RtcMediaDevice object
final RtcMediaDevice newDevice = RtcMediaDevice(
label: label,
id: deviceId,
kind: kind,
);
dev.log(
"Audio route changed to RtcMediaDevice: ${newDevice.toString()})");
// Now you can use this `newDevice` object to update your CallState or RtcMediaDeviceNotifier
// Example (adjust based on your actual state management):
// _deviceNotifier.setActiveOutputDevice(newDevice);
// if (state != null) {
// // Access internal logic of the SDK to update the audio state if possible
// }
} else {
throw PlatformException(
code: 'Unrecognized method',
message: 'Method ${method.method} not recognized');
}
}This is the log from the UI, when we try to retrieve current audioOutputDevice from the callState
return BetterStreamBuilder(
stream: call.state.valueStream,
builder: (context, callState) {
log('AUDIO OUTPUT UIUI: ${callState.audioOutputDevice}');
return StreamCallContent(
call: call,
pictureInPictureConfiguration: const PictureInPictureConfiguration(
enablePictureInPicture: false,
disablePictureInPictureWhenScreenSharing: true,
),
callAppBarWidgetBuilder: (context, call) {
final isTeam = callState.callType.value == CallType.team.type;
CustomLog.info('CASADAS: ${callState.custom}');
final groupTeam =
(callState.custom['channel_name'] as String? ?? '').isEmpty
? callState.custom['callee_name'] as String? ?? ''
: callState.custom['channel_name'] as String? ?? '';
return CallAppBar(
call: call,
elevation: 0,
showLeaveCallAction: true,
backgroundColor: AppColor.darkPrimaryColor,
title: const SizedBox.shrink(),
leadingWidth: MediaQuery.sizeOf(context).width * 0.8,
leading: Row(
children: [
IconButton(
icon: const Icon(
Icons.arrow_back_ios_new_rounded,
color: Colors.white,
),
onPressed: () => GoRouter.of(context).pop(),
),
if (isTeam)
Expanded(
child: Text(
groupTeam,
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
),
],
),
actions: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Consumer(
builder: (context, ref, child) {
final isLocalCameraOn =
callState.localParticipant?.isVideoEnabled ?? false;
if (!isLocalCameraOn) {
return const SizedBox.shrink();
}
return InkWell(
onTap: () async => await ref
.read(incompanyCallProvider.notifier)
.onFlipCamera(call),
child: SvgPicture.asset(
'assets/icons/camera-switch.svg',
colorFilter: const ColorFilter.mode(
Colors.white,
BlendMode.srcIn,
),
),
);
},
),
),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Badge.count(
count: callState.participantCount,
isLabelVisible: isTeam,
child: SvgPicture.asset(
call.type.value == CallType.inCompany.type
? 'assets/icons/user-round.svg'
: 'assets/icons/users-round.svg',
colorFilter: const ColorFilter.mode(
Colors.white,
BlendMode.srcIn,
),
),
),
),
],
);
},
callParticipantsWidgetBuilder: (context, call) {
return CallInCompanyParticipants(
call: call,
callState: callState,
);
},
callControlsWidgetBuilder: (context, call) {
final cs = call.state.valueOrNull;
log('AUDIO OUTPUT Call COntrols: ${cs?.audioOutputDevice}');
return DecoratedBox(
decoration: BoxDecoration(color: AppColor.darkPrimaryColor),
child: Padding(
padding:
const EdgeInsets.only(bottom: kBottomNavigationBarHeight),
child: CallInCompanyCallControls(
call: call,
callState: callState,
),
),
);
},
);
});SDK's version:
stream_video: ^0.11.2
stream_video_flutter: ^0.11.2
stream_video_push_notification: ^0.11.2
stream_video_screen_sharing: ^0.11.2
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working