-
Notifications
You must be signed in to change notification settings - Fork 46
Open
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
Metadata
Metadata
Assignees
Labels
No labels