I am creating a Flutter plugin. Currently, the code:
When I run the application in Android, it perfectly works. Nevertheless, when I run it on iOS, it does not (assuming relates permissions/restrictions)
await flutterTts
.synthesizeToFile(
"This is my first audio synthesizer in Flutter", audioFileName)
.then((success) => {
if (success == 1)
{
print('Successfully synthesized!!'),
// Gets the path to the generated file depending on the platform
pathFile =
Platform.isAndroid ? pathToFileAndroid : pathToFileIos,
pathFile
.then((pathToAudioFile) => {
print('Path to file: ' + pathToAudioFile),
// Speakers/earpiece
// int result = await player.earpieceOrSpeakersToggle();
// Sets the path to the file
audioPlayer.setUrl(pathToAudioFile),
audioPlayer.setVolume(1.0),
// Gets the duration of the audio file to be reproduced
// Plays the audio file
playLocal(audioPlayer, pathToAudioFile),
}) // pathFile
.catchError((e) {
print('Error: Unable to get the path to the audio file');
}),
}, // success
}) //synthesizeToFile
.catchError((e) {
print('Error during the synthesisation: $e');
});
}
/// Gets the path to the file to be accessed (iOS)
static Future<String> get pathToFileIos async {
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
print('appDocPath: $appDocPath');
return '$appDocPath/$audioFileName';
}
I implemented audioPlayer.onDurationChanged.listen
to confirm that the path to the file is the correct one (it actually gets the duration of the file). Nevertheless, the file is not played.
I am using a simulator to test the application, and this is the path where the file is stored
/localPaty/Devices/deviceID/data/Containers/Data/Application/appID/Documents/temp_audio_cue.caf
I read different questions regarding this topic, but I did not find a solution for my case
I have tried:
Editing Transport security as the documentation recommends
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Using AudioCache
(question)
Anyone has any other suggestion? Do I need to move the file to my local assets and use AudioCache
to reproduce the file?
Update
I have also tried to add the flag isLocal
.
playLocal() async {
int result = await audioPlayer.play(localPath, isLocal: true);
}
According to the documentation is is needed cause
The isLocal flag is required only because iOS and macOS make a difference about it
It returns 1
, so I guess that it means success, but the sound is still not triggered. Could be the simulator failing?
"iOS => call startHeadlessService, playerId ID"
"iOS => call setUrl, playerId ID"
"iOS => call setVolume, playerId ID"
"iOS => call play, playerId ID"
2021-02-03 11:59:33.149925+0100 Runner[61496:850044] flutter: Played successfully?: 1
I have also tested to call playLocal()
with a wrong path. It keeps returning 1
but after it it displays the following error:
FigFileForkOpenMainByCFURL signalled err=2 (errno) (open failed)
Nevertheless, the error is not triggered with calling the method with the correct localPath
so I assume it should be playing it correctly.
Note
If instead of calling playLocal()
, I call flutter_tts.speak('test')
, it works. Therefore, the error should probably be related to audioplayers
.
The versions that I am using are flutter_tts ^2.1.0
and audioplayers: ^0.17.3
final AudioContext audioContext = AudioContext(
iOS: AudioContextIOS(
defaultToSpeaker: true,
category: AVAudioSessionCategory.ambient,
options: [
AVAudioSessionOptions.defaultToSpeaker,
AVAudioSessionOptions.mixWithOthers,
],
),
android: AudioContextAndroid(
isSpeakerphoneOn: true,
stayAwake: true,
contentType: AndroidContentType.sonification,
usageType: AndroidUsageType.assistanceSonification,
audioFocus: AndroidAudioFocus.none,
),
);
AudioPlayer.global.setGlobalAudioContext(audioContext);
Add this in you main.dart file before this runApp(App());