switch audio outputs functionality
Added switch audio output device functionality
Hi @zombie6888
Apologies for the delay, it has taken a while to find time to give this a thorough review.
The 4 switch methods can be cleanly extracted out and relocated into the main AudioSession class, and that part of the API looks relatively future proof. The additional abstractions over the top of the existing devices API, i.e. Speaker, Bluetooth, Earpiece, probably need more time and consideration, and don't need to be part of this initial PR.
We can monitor the convenience aspect of this and see whether at some later time it is feasible to introduce a unified device abstraction. However, the initial design philosophy of audio_session was to unify methods where possible, but to keep all the data structures distinct per platform so that the app developer is aware of platform differences, and so that the API is more resilient to the dictates of the various future platform APIs we may need to support.
Hi, thank you for review!
That's not a problem to extract those methods. First reason i've added AudioOutputsManager is that it was already used in our project. The second reason is that main class is too big already and it's just another responsibility for him to switch outputs. Anyway this change will be easy.
But regarding additional abstractions, it seems to me that there should be some way to distinguish one device output type from another. Otherwise, I don't know how to use this functionality and reflect in example, because it is not entirely clear what type of output is currently active. Alternatively, we can add some "outputType" field to existing abstractions.
Looking forward for your feedback and suggestions
What I'm thinking is that something cheap could be implemented in the example app itself, listening to devicesChangedEventStream, then the app could define its own mapping between AudioDeviceType to the app's own abstraction, whatever that needs to be.
By the way, I just tested on Android, and when I click on the speaker button, it sounds like a weaker sound, as if it's coming from the earpiece at a boosted volume rather than getting the full sound coming out of the speakers.
Ok, I will take your suggestions into account.
By the way, I just tested on Android, and when I click on the speaker button, it sounds like a weaker sound, as if it's coming from the earpiece at a boosted volume rather than getting the full sound coming out of the speakers.
That's odd. I checked and couldn't reproduce this issue.
done
I've managed to implement switching between the earpiece and the speaker, but when I try to change the volume with the earpiece, nothing happens. It only changes the volume when the speaker is active.
Can you tell me if I'm missing a parameter or should I wait for this PR to be implemented?
Future<void> configureAudioSession({required bool earpieceEnabled}) async {
final session = await AudioSession.instance;
if (earpieceEnabled) {
await session.configure(AudioSessionConfiguration(
avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
avAudioSessionMode: AVAudioSessionMode.voiceChat,
androidAudioAttributes: const AndroidAudioAttributes(
contentType: AndroidAudioContentType.speech,
usage: AndroidAudioUsage.voiceCommunication,
),
));
} else {
await session.configure(AudioSessionConfiguration(
avAudioSessionCategory: AVAudioSessionCategory.playback,
avAudioSessionMode: AVAudioSessionMode.defaultMode,
androidAudioAttributes: const AndroidAudioAttributes(
contentType: AndroidAudioContentType.music,
usage: AndroidAudioUsage.media,
),
));
}
await session.setActive(true);
}
I've managed to implement switching between the earpiece and the speaker, but when I try to change the volume with the earpiece, nothing happens. It only changes the volume when the speaker is active.
I've checked your configuration in example app and it works for both configs, at least on my device. Are you tring to change volume programatically or using hardware volume buttons? Which platform are you trying on: ios , android or both? You can share an example, maybe i or someone else will be able to reproduce your issue
Hey, thanks for replying so quickly.
I'll give you a little more context. I'm not using the PR, and it's primarily an issue that only affects Android.
I've tested it on a Samsung Galaxy M15 5G with Android 14, but I've also tested it on other devices with different versions of Android, and the same thing happens.
As you can see in the video, you can hear the sound coming through the earpiece, but when I turn the volume up or down, it doesn't change. When I turn the volume all the way down, it tries to turn it up but then stays at the same level.
https://github.com/user-attachments/assets/99a7da2c-062e-4317-98ba-bc6e7f519856
The way I have implemented it is this, I use directly on example/main.dart
...
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
_audioHandler.configureAudioSession(earpieceEnabled: true);
print("--> set earpiece");
return MaterialApp(
title: 'Audio Service Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const MainScreen(),
);
}
}
...
class AudioPlayerHandler extends BaseAudioHandler with SeekHandler {
...
Future<void> configureAudioSession({required bool earpieceEnabled}) async {
final session = await AudioSession.instance;
if (earpieceEnabled) {
await session.configure(const AudioSessionConfiguration(
avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
avAudioSessionMode: AVAudioSessionMode.voiceChat,
androidAudioAttributes: AndroidAudioAttributes(
contentType: AndroidAudioContentType.speech,
usage: AndroidAudioUsage.voiceCommunication,
),
));
} else {
await session.configure(const AudioSessionConfiguration(
avAudioSessionCategory: AVAudioSessionCategory.playback,
avAudioSessionMode: AVAudioSessionMode.defaultMode,
androidAudioAttributes: AndroidAudioAttributes(
contentType: AndroidAudioContentType.music,
usage: AndroidAudioUsage.media,
),
));
}
await session.setActive(true);
}
}
I think it's not PR related, and probably you should create separate issue, but anyway i've just changed this line with your config in example app from this branch and it works for me:
Sorry for the delay. Of course, this isn't related to the PR. I just wanted to see if you could help me with this.
Unfortunately, I've tried every possible method on different devices, and it doesn't work correctly when raising and lowering the audio volume in earpiece mode.
On a Xiaomi device, I was able to see that when switching from speaker to earpiece mode, two audio bars appear, one for the speaker and one for the earpiece. However, when I press the volume buttons on the device, they move the speaker bar, not the earpiece.
Anyway, when I have time, I'll create an example and open an issue.
Thanks a lot for the help.