Flutter中获取指定格式语音输入并通过API传输的方法求助
Flutter语音录制转Base64并传递API的可行方案
核心思路
目标是录制语音后转成Base64编码字符串(即你示例中的格式),再通过API传递。推荐使用record包处理录音(稳定性优于你之前尝试的部分包),配合http发送请求,path_provider管理临时文件。
步骤实现
1. 添加依赖
在pubspec.yaml中加入以下依赖:
dependencies: flutter: sdk: flutter record: ^4.4.4 # 专业录音包,支持多平台 http: ^1.1.0 # 处理API请求 path_provider: ^2.1.1 # 获取临时文件路径
2. 配置权限
- Android:在
android/app/src/main/AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- iOS:在
ios/Runner/Info.plist中添加麦克风权限说明:
<key>NSMicrophoneUsageDescription</key> <string>需要使用麦克风录制语音</string>
3. 完整代码示例
import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:record/record.dart'; import 'package:http/http.dart' as http; import 'package:path_provider/path_provider.dart'; class VoiceToApiPage extends StatefulWidget { const VoiceToApiPage({super.key}); @override State<VoiceToApiPage> createState() => _VoiceToApiPageState(); } class _VoiceToApiPageState extends State<VoiceToApiPage> { final AudioRecorder _recorder = AudioRecorder(); bool _isRecording = false; String? _audioFile; // 启动录音 Future<void> startRecording() async { final hasPerm = await _recorder.hasPermission(); if (!hasPerm) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('请开启麦克风权限')), ); return; } await _recorder.start( const RecordConfig(encoder: AudioEncoder.wav), // 按需选编码(mp3/wav等) path: await _getTempPath(), ); setState(() => _isRecording = true); } // 停止录音并处理数据 Future<void> stopRecording() async { final path = await _recorder.stop(); setState(() { _isRecording = false; _audioFile = path; }); if (_audioFile != null) await sendToApi(_audioFile!); } // 获取临时音频文件路径 Future<String> _getTempPath() async { final tempDir = await getTemporaryDirectory(); return '${tempDir.path}/voice_recording.wav'; } // 转Base64并发送API Future<void> sendToApi(String filePath) async { final bytes = await File(filePath).readAsBytes(); final base64Str = base64Encode(bytes); try { final response = await http.post( Uri.parse('https://your-api-url.com/voice'), body: {'voice_data': base64Str}, // 按API要求传参 ); if (response.statusCode == 200) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('语音数据发送成功')), ); // 可选:删除临时文件 await File(filePath).delete(); } else { throw Exception('请求失败,状态码:${response.statusCode}'); } } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('发送失败:${e.toString()}')), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('语音转API')), body: Center( child: ElevatedButton( onPressed: _isRecording ? stopRecording : startRecording, child: Text(_isRecording ? '停止录制' : '开始录制'), ), ), ); } }
关键注意事项
- 确认API支持的音频编码格式,比如如果API要求mp3,就把
AudioEncoder.wav改成AudioEncoder.aacLc(对应mp3) - 录制完成后可以删除临时文件,避免占用设备存储空间
- 权限判断必须放在录音前,否则会直接录制失败
- 如果API需要其他参数,直接在
http.post的body中添加即可
内容的提问来源于stack exchange,提问作者Udit Sharma
相关产品推荐
相关产品推荐

