[iOS 15.1+] AVAudioSessionErrorCodeMediaServicesFailed
Flutter Version
My version : 2.10.2
Lib Version
My version : 3.0.4+1
Platform (Android / iOS / web) + version
Platform : iOS 15.1+

Describe the bug
Recently, we've been getting reports from iOS 15.1+ devices, for example
PlatformException(PLAY_ERROR, Cannot play assets/audio/correct_answer.wav, The operation couldn’t be completed. (OSStatus error 1836282486.), null). We're getting the error for multiple audio files. Somehow I can't reproduce it myself (test device is on iOS 15.1+ as well ofcourse)
Apparently the OSStatus is https://developer.apple.com/documentation/coreaudiotypes/avaudiosessionerrorcode/avaudiosessionerrorcodemediaservicesfailed
How we play audio
Our app plays a lot of sound effects,. To make sure that we don't create too many audio players on web, we reuse players whenever we can. Our pages can access this SoundRepository and can just call soundRepository.correctAnswer().
import 'package:assets_audio_player/assets_audio_player.dart';
enum _SoundType {
soundEffect,
music,
}
typedef CreateAudioPlayer = AssetsAudioPlayer Function();
class SoundRepository {
final CreateAudioPlayer createAudioPlayer;
final Map<String, List<AssetsAudioPlayer>> _audioPlayers = {};
static const String _correctAnswer = 'correct_answer.wav';
// more static files here
Future<AssetsAudioPlayer?> correctAnswer() => _play(_correctAnswer);
// more audio functions here
SoundRepository({
required this.createAudioPlayer,
});
factory SoundRepository.create({
required CreateAudioPlayer createAudioPlayer,
}) {
return SoundRepository(
createAudioPlayer: createAudioPlayer,
);
}
Future<AssetsAudioPlayer?> _play(String fileName) {
return _getAudioPlayer(fileName).then((audioPlayer) {
audioPlayer.setVolume(0.5);
audioPlayer.setLoopMode(LoopMode.none);
audioPlayer.play();
return audioPlayer;
});
}
Future<AssetsAudioPlayer> _getAudioPlayer(String fileName) {
if (_audioPlayers.containsKey(fileName)) {
final AssetsAudioPlayer? availablePlayer = _audioPlayers[fileName]!.firstWhereOrNull(
(audioPlayer) => !audioPlayer.isPlaying.value,
);
if (availablePlayer != null) {
return Future.value(availablePlayer);
}
} else {
_audioPlayers[fileName] = [];
}
final AssetsAudioPlayer audioPlayer = createAudioPlayer();
_audioPlayers[fileName]!.add(audioPlayer);
return audioPlayer
.open(
Audio('assets/audio/$fileName'),
autoStart: false,
volume: 0.5,
headPhoneStrategy: HeadPhoneStrategy.none,
audioFocusStrategy: AudioFocusStrategy.none(),
)
.then((value) => audioPlayer);
}
}