Flutter调用ElevenLabs API获取并播放MPEG音频的问题与解决
Flutter中播放ElevenLabs API返回的MPEG音频问题及解决方法
点击悬浮按钮后,尝试在Flutter中使用AudioPlayer库播放ElevenLabs语音API返回的音频,已成功收到API响应,但不知道如何临时保存并播放MPEG格式音频,原代码无法正常运行:
原代码片段
floatingActionButton: Align( alignment: Alignment.bottomRight, child: FloatingActionButton( onPressed: _playOutput , child: const Icon(Icons.volume_up), ),
void _playOutput() async { await playTextToSpeech(_outputController.text); }
// 文本转语音方法 Future<void> playTextToSpeech(String text) async { // String apiKey = 'YOUR_API_KEY'; String apiKey = 'MY-API-KEY'; String url = 'https://api.elevenlabs.io/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM'; final response = await http.post( Uri.parse(url), headers: { 'accept': 'audio/mpeg', 'xi-api-key': '$apiKey', 'Content-Type': 'application/json', // 'Authorization': 'Bearer $apiKey', }, body: json.encode({ "text": text, "voice_settings": { "stability": 0, "similarity_boost": 1 } }), ); if (response.statusCode == 200) { print("////////// In tts"); print(response.headers); print('headers >>> ${response.headers}'); print('body bytes >>> ${response.bodyBytes}'); print("//////// IN TTS"); final bytes = response.bodyBytes; await player.play(bytes as Source); } else { throw Exception('Failed to load audio'); } }
API响应内容
返回的响应包含headers和bodyBytes字段,输出如下:
{access-control-allow-headers: *, alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000, date: Sat, 25 Feb 2023 04:22:34 GMT, access-control-allow-origin: *, access-control-allow-methods: POST, OPTIONS, DELETE, GET, content-length: 12538, via: 1.1 google, content-type: audio/mpeg, server: uvicorn}
[255, 251, 80, 196, 0, 0, 5, 160, 1, 51, 128, 132, 96, 33, 90, 22, 166, 48, 193, 138, 32, 104, 184, 90, 110, 117, 80, 49, 69, 6, 18, 133, 13, 62, 228, 101, 192, 131, 121, 205, 78, 201, 249, 119, 242, 25, 126, 167, 95, 255, 137, 255, 47, 237, 168, 230, 183, 203, 255, 169, 202, 113, 242, 148, 35, 144, 83, 75, 101, 109, 116, 210, 43, 80, 26, 141, 64, 68, 200, 108, 120, 95, 186, 17, 88, 89, 9, 193, 40, 166, 168, 223, 28, 109, 28, 4, 142, 9, 231, 3, 192, 112, 187, 214, 50, 105, 79, 38, 137, 126, 173, 102, 187, 148, 207, 179, 33, 104, 219, 209, 235, 28, 56, 205, 152, 94, 105, 2, 204, 175, 245, 239, 74, 197, 8, 32, 42, 139, 28, 69, 136, 76, 232, 9, 196, 108, 120, 178, 198, 223, 21, 214, 245, 118, 79, 246, 142, 72, 218, 40, 2, 156, 178, 84, 30, 174, 65, 30, 12, 1, 185, 36, 252, 34, 33, 153, 14, 98, 181, 49, 38, 134, 10, 171, 146, 173, 145, 132, 37, 61, 171, 199, 64, 200, 145, 75, 93, 76, 170, 72, 33, 39, 86, 113, 64, 34, 40, 149, 255, 251, 82, 196, 27, 128, 11, 48, 113, 51, 166, 24, 110, 193, 117, 43,...]
解决方案
使用just_audio包即可实现播放,完整代码如下:
import 'package:just_audio/just_audio.dart'; ... class _ChatGPTPageState extends State<ChatGPTPage> { .... // 文本转语音方法 Future<void> playTextToSpeech(String text) async { // 请求等待时显示加载图标 setState(() { _isLoadingVoice = true; // 进度指示器 }); // String apiKey = 'YOUR_API_KEY'; String url = 'https://api.elevenlabs.io/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM'; final response = await http.post( Uri.parse(url), headers: { 'accept': 'audio/mpeg', 'xi-api-key': apiKey, 'Content-Type': 'application/json', }, body: json.encode({ "text": text, "voice_settings": { "stability": .2, "similarity_boost": .8 } }), ); if (response.statusCode == 200) { final bytes = response.bodyBytes; // 获取ElevenLabs返回的音频字节 await player.setAudioSource(MyCustomSource(bytes)); // 将字节传入JustAudio库处理 player.play(); // 播放音频 } else { throw Exception('Failed to load audio'); } } }//_ChatGPTPageState类 // 自定义音频源,用于传入字节流到播放器 class MyCustomSource extends StreamAudioSource { final List<int> bytes; MyCustomSource(this.bytes); @override Future<StreamAudioResponse> request([int? start, int? end]) async { start ??= 0; end ??= bytes.length; return StreamAudioResponse( sourceLength: bytes.length, contentLength: end - start, offset: start, stream: Stream.value(bytes.sublist(start, end)), contentType: 'audio/mpeg', ); } }
内容的提问来源于stack exchange,提问作者Noah Velasco
相关产品推荐
相关产品推荐

