我正在开发一个 flutter 项目,其中用户应该创建一些脚本并通过在文本中输入它们,然后
flutter_tts
库应该将它们转换为音频文件,暂时可以正常工作,但我想保存它文件到 firebase 存储中供以后用户使用。我已尝试以下代码,但它只是将空白音频文件保存在 firebase 存储中。任何形式的帮助将不胜感激。
我尝试过的代码是:
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;
}
花了一整天的时间,在朋友的帮助下,我终于找到了由于我同时使用
synthesizeToFile()
和 speak()
功能而引起的问题,我成功地解决了这个问题将我的代码更改为以下代码片段。
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;
}
当我调用 _flutterTts.synthesizeToFile 函数时,出现以下错误,我尝试授予所有权限但没有成功,如何将音频文件保存到内存中?
E/TextToSpeech(7291): 打开文件 name1 失败 E/TextToSpeech(7291):java.io.FileNotFoundException:打开失败:EROFS(只读文件系统) E / TextToSpeech(7291):在android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:344) E / TextToSpeech(7291):在android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:231) E / TextToSpeech(7291):在android.speech.tts.TextToSpeech.synthesizeToFile(TextToSpeech.java:1843) E / TextToSpeech(7291):在com.tundralabs.fluttertts.FlutterTtsPlugin.synthesizeToFile(FlutterTtsPlugin.kt:615) E / TextToSpeech(7291):在com.tundralabs.fluttertts.FlutterTtsPlugin.onMethodCall(FlutterTtsPlugin.kt:308) E / TextToSpeech(7291):在io.flutter.plugin.common.MethodChannel $IncomingMethodCallHandler.onMessage(MethodChannel.java:258) E / TextToSpeech(7291):在io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295) E / TextToSpeech(7291):在io.flutter.embedding.engine.dart.DartMessenger.lambda $dispatchMessageToQueue $0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:322) E/TextToSpeech(7291):位于 io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(来源未知:12) E / TextToSpeech(7291):在android.os.Handler.handleCallback(Handler.java:938) E / TextToSpeech(7291):在android.os.Handler.dispatchMessage(Handler.java:99) E / TextToSpeech(7291):在android.os.Looper.loop(Looper.java:223) E / TextToSpeech(7291):在android.app.ActivityThread.main(ActivityThread.java:7656) E / TextToSpeech(7291):在java.lang.reflect.Method.invoke(本机方法) E / TextToSpeech(7291):在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:592) E / TextToSpeech(7291):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)