如何将flutter_tts生成的音频文件保存至Firebase Storage?
问题原因及修复方案
我们逐个梳理代码中导致空白音频的核心问题,对应修改即可解决:
1. 核心逻辑错误
- 你在调用合成文件接口前先执行了
await _flutterTts.speak(script);,这会占用TTS引擎的独占资源,导致后续合成任务没有被正确执行,直接生成空白文件。如果不需要提前播放,直接删除这行代码即可。 - 提前手动创建了空的目标文件:你在调用合成接口前就用
await file.create()创建了同名空文件,如果后续合成的文件没有正确覆盖这个空文件,最终上传的就是你自己生成的空白文件,删除这段提前创建空文件的逻辑。 - 硬编码Android临时文件路径:
/storage/emulated/0/Android/data/com.solution.thriving/files/$fileName这个路径不通用,不同包名、不同系统版本、iOS设备都会找不到文件,直接导致你读了不存在的文件,上传空白占位。
2. 异步时序问题
你混合使用await和then嵌套,没有正确等待异步任务执行完成,经常出现文件还没写完合成的音频内容,就触发了上传逻辑,最终上传的是还没写入内容的空白文件。
修正后的参考代码
final FlutterTts _flutterTts = FlutterTts(); /// 音频脚本生成 Future<String?> createAudioScript( String name, String script, String firebasepath, ) async { // 初始化TTS配置 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"}, ); // 生成文件名和存储路径 final fileName = GetPlatform.isAndroid ? '$name.wav' : '$name.caf'; final appDocDir = await getApplicationDocumentsDirectory(); final audioDir = Directory('${appDocDir.path}/audio/'); if (!await audioDir.exists()) { await audioDir.create(recursive: true); } final targetPath = '${audioDir.path}/$fileName'; // 直接合成到目标路径,不需要后续移动文件 final synthesizeResult = await _flutterTts.synthesizeToFile(script, targetPath); if (synthesizeResult != 1) { customToast(message: '音频合成失败'); return null; } // 先校验合成的文件是否有效 final audioFile = File(targetPath); if (!await audioFile.exists() || await audioFile.length() == 0) { customToast(message: '音频文件生成失败'); return null; } // 上传到Firebase Storage final audioLink = await appStorage.uploadAudio(audioFile, fileName, '$firebasepath/$fileName'); _app.link.value = audioLink; customToast(message: 'Audio has been generated successfully.'); return audioLink; }
额外注意事项
- 确认
flutter_tts的权限配置:Android需要添加WRITE_EXTERNAL_STORAGE、READ_EXTERNAL_STORAGE权限,iOS需要开启音频相关权限,避免合成的时候没有写入权限生成空文件。 - 确认你Firebase上传的代码是正确等待文件读取完成再上传的,不要读取未关闭的文件流。
- 部分TTS引擎不支持后台合成,合成过程中不要杀掉APP页面,避免合成中断。
内容的提问来源于stack exchange,提问作者Ayesha Iftikhar
相关产品推荐
相关产品推荐

