Flutter macOS录音生成空文件无声音问题求助
macOS下Flutter录音后播放无声音问题解决
问题现象
在macOS系统中使用Flutter开发录音功能,采用record包实现录音、audioplayers包实现音频播放,但录制生成的音频文件播放时无声音,如同空文件。
使用依赖包
- 录音:record
- 播放:audioplayers
问题根源分析
- 录音路径初始化异步问题:
Recorder组件的getDir()是异步方法,在initState中直接调用但未等待其完成,导致调用_start()录音时,path可能仍为null,录音文件被写入空路径或无效位置,最终生成空文件。 - macOS麦克风权限缺失:未在项目中配置麦克风使用权限,导致录音功能无法正常获取音频输入。
- 编码器支持检查的打印错误:
_isEncoderSupported方法中循环打印支持的编码器时,错误使用了传入的encoder.name而非当前遍历的e.name,无法正确输出支持的编码器列表。
修复方案
1. 修复录音路径初始化逻辑
修改Recorder组件的初始化逻辑,确保录音路径在使用前已正确初始化:
@override void initState() { super.initState(); _audioRecorder = AudioRecorder(); // 在帧渲染完成后初始化路径,确保异步操作完成 WidgetsBinding.instance.addPostFrameCallback((_) async { await getDir(); }); _recordSub = _audioRecorder.onStateChanged().listen((recordState) { _updateRecordState(recordState); }); _amplitudeSub = _audioRecorder .onAmplitudeChanged(const Duration(milliseconds: 300)) .listen((amp) { setState(() => _amplitude = amp); }); } // 同时在_start方法中增加路径检查,确保路径有效 Future<void> _start() async { setState(() => recordingDone = false); try { if (await _audioRecorder.hasPermission()) { // 确保路径已初始化 if (path == null) { await getDir(); } const encoder = AudioEncoder.aacLc; if (!await _isEncoderSupported(encoder)) { return; } final devs = await _audioRecorder.listInputDevices(); debugPrint(devs.toString()); const config = RecordConfig(encoder: encoder, numChannels: 1); _audioRecorder.start(config, path: path ?? ''); _recordDuration = 0; _startTimer(); } } catch (e) { if (kDebugMode) { print(e); } } }
2. 添加macOS麦克风权限
在项目的macOS/Runner/Info.plist文件中添加麦克风权限描述:
<key>NSMicrophoneUsageDescription</key> <string>需要使用麦克风进行录音</string>
3. 修正编码器支持检查的打印错误
修改_isEncoderSupported方法中的打印逻辑:
Future<bool> _isEncoderSupported(AudioEncoder encoder) async { final isSupported = await _audioRecorder.isEncoderSupported( encoder, ); if (!isSupported) { debugPrint('${encoder.name} is not supported on this platform.'); debugPrint('Supported encoders are:'); for (final e in AudioEncoder.values) { if (await _audioRecorder.isEncoderSupported(e)) { // 修正为e.name debugPrint('- ${e.name}'); } } } return isSupported; }
4. 验证音频文件有效性
在_stop方法中添加文件大小检查,确认录音文件已正确生成:
Future<void> _stop() async { path = await _audioRecorder.stop(); if (path != null) { final file = File(path!); if (await file.exists()) { final size = await file.length(); debugPrint('录音文件大小:$size 字节'); if (size == 0) { debugPrint('警告:生成的录音文件为空'); } } widget.onStop(path!); setState(() { recordingDone = true; }); } }
验证步骤
- 重新运行项目,确保麦克风权限请求弹窗正常弹出并授权。
- 录制一段音频,查看控制台输出的录音文件路径和大小,确认文件非空。
- 使用audioplayers播放录制的音频,验证声音正常输出。
内容的提问来源于stack exchange,提问作者Shruti Ramnandan Sharma
相关产品推荐
相关产品推荐

