Search code examples
firebaseflutterdartfirebase-storagetext-to-speech

Is there any way to save flutter_tts file to firebase storage?


I am working on a flutter project in which user is supposed to create some scripts and by typing them in text and then flutter_tts library is supposed to convert them to audio file which works fine for that time being but I want to save that file into firebase storage for later user. I have tried the following code but it just saves blank audio file in the firebase storage. Any kind of help will be appreciated.

The code I have tried is:

final FlutterTts _flutterTts = FlutterTts();
late var fileName;
/// creation of audio script
Future createAudioScript(
  String name,
  String script,
  String firebasepath,
) async {
  await _flutterTts.setLanguage("en-US");
  await _flutterTts.setSpeechRate(1.0);
  await _flutterTts.setVolume(1.0);
  await _flutterTts.setPitch(1.0);
  await _flutterTts.setVoice(
    {"name": "en-us-x-tpf-local", "locale": "en-US"},
  );
  await _flutterTts.speak(script);
  fileName = GetPlatform.isAndroid ? '$name.wav' : '$name.caf';
  print('FileName: $fileName');

  var directoryPath =
      "${(await getApplicationDocumentsDirectory()).path}/audio/";
  var directory = Directory(directoryPath);
  if (!await directory.exists()) {
    await directory.create();
    print('[INFO] Created the directory');
  }

  var path =
      "${(await getApplicationDocumentsDirectory()).path}/audio/$fileName";
  print('[INFO] path: $path');
  var file = File(path);
  if (!await file.exists()) {
    await file.create();
    print('[INFO] Created the file');
  }

  await _flutterTts.synthesizeToFile(script, fileName).then((value) async {
    if (value == 1) {
      print('generated');
      var file = File(
        '/storage/emulated/0/Android/data/com.solution.thriving/files/$fileName',
      );
      print(file);
      moveFile(file, path, '$firebasepath/$fileName').then((value) {
        print('move file: $value');
        _app.link.value = value;
        print('link: ${_app.link.value}');
      });
    }
  });
}

/// move file from temporary to local storage and save to firebase
Future<String> moveFile(
  File sourceFile,
  String newPath,
  String firebasePath,
) async {
  String audioLink = '';
  print('moved');
  await sourceFile.copy(newPath).then((value) async {
    print('value: $value');
    await appStorage.uploadAudio(value, fileName, firebasePath).then((audio) {
      print(audio);
      audioLink = audio;
      return audioLink;
    });
  }).whenComplete(() async {
    customToast(message: 'Audio has been generated successfully.');
  });
  return audioLink;
}

Solution

  • After spending whole day and with the help of a friend, I finally managed to figure out the issue which was being caused because I was using synthesizeToFile() and speak() functions at the same time, which I managed to resolved the issue by changing my code to the following code snippet.

    final FlutterTts _flutterTts = FlutterTts();
    late var fileName;
    /// converting text to speech
    Future createAudioScript(
      String name,
      String script,
      String firebasepath,
    ) async {
      await _flutterTts.setLanguage("en-US");
      await _flutterTts.setSpeechRate(1.0);
      await _flutterTts.setVolume(1.0);
      await _flutterTts.setPitch(1.0);
      await _flutterTts.setVoice(
        {"name": "en-us-x-tpf-local", "locale": "en-US"},
      );
      if (GetPlatform.isIOS) _flutterTts.setSharedInstance(true);
      // await _flutterTts.speak(script);
      fileName = GetPlatform.isAndroid ? '$name.wav' : '$name.caf';
      log('FileName: $fileName');
    
      await _flutterTts.synthesizeToFile(script, fileName).then((value) async {
        if (value == 1) {
          log('Value $value');
          log('generated');
        }
      });
      final externalDirectory = await getExternalStorageDirectory();
      var path = '${externalDirectory!.path}/$fileName';
      log(path);
      saveToFirebase(path, fileName, firebasPath: '$firebasepath/$name')
          .then((value) => {log('Received Audio Link: $value')});
    }
    /// saving converted audio file to firebase
    Future<String> saveToFirebase(String path, String name,
        {required String firebasPath}) async {
      final firebaseStorage = FirebaseStorage.instance;
      SettableMetadata metadata = SettableMetadata(
        contentType: 'audio/mpeg',
        customMetadata: <String, String>{
          'userid': _app.userid.value,
          'name': _app.name.value,
          'filename': name,
        },
      );
      var snapshot = await firebaseStorage
          .ref()
          .child(firebasPath)
          .putFile(File(path), metadata);
      var downloadUrl = await snapshot.ref.getDownloadURL();
      print(downloadUrl + " saved url");
      return downloadUrl;
    }