You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何实现ChatGPT流式音频回答?

Flutter实现ChatGPT流式音频回答方案

OpenAI API支持情况

目前OpenAI没有提供直接将ChatGPT流式回答实时转为音频的原生API。官方的Text to Speech(TTS)API仅支持传入完整文本生成音频,无法对接ChatGPT的流式文本输出。

实现流式音频回答的具体方案

要实现类似官方ChatGPT的流式音频效果,需要结合ChatGPT流式文本接口和本地TTS工具,分三步处理:

1. 调用ChatGPT流式接口获取逐段文本

使用OpenAI的Chat Completions API时,设置stream: true参数,接口会以SSE(Server-Sent Events)的形式逐块返回回答内容。每一块数据包含部分生成的文本,无需等待完整回答生成。

在Flutter中,可以通过http包处理流式响应,实时解析每一块返回的文本片段。

2. 优化文本分块,避免音频断句混乱

直接将每个小文本块单独转音频会导致播放时频繁断句,影响体验。需要做以下处理:

  • 维护一个文本缓存,将流式返回的片段逐步拼接
  • 按语义分割点(句号、感叹号、换行符等)分割缓存文本,积累到完整的短语或句子后,再送入TTS工具

3. 音频播放的无缝衔接

使用flutter_tts包的播放状态监听功能,当前一段音频播放完成后,自动处理队列中的下一段文本。也可以提前预加载下一段音频,减少播放间隙。

简化代码示例

import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:flutter_tts/flutter_tts.dart';
import 'dart:collection';

Future<void> streamChatAndSpeak(String userPrompt) async {
  final apiKey = 'YOUR_OPENAI_API_KEY';
  final flutterTts = FlutterTts();
  final audioQueue = Queue<String>();
  String textBuffer = '';
  bool isPlaying = false;

  // 发起流式ChatGPT请求
  final request = http.Request('POST', Uri.parse('https://api.openai.com/v1/chat/completions'))
    ..headers['Authorization'] = 'Bearer $apiKey'
    ..headers['Content-Type'] = 'application/json'
    ..body = jsonEncode({
      'model': 'gpt-3.5-turbo',
      'messages': [{'role': 'user', 'content': userPrompt}],
      'stream': true,
    });

  final response = await request.send();
  final stream = response.stream.transform(utf8.decoder);

  // 监听流式返回的文本块
  await for (final chunk in stream) {
    final lines = chunk.split('\n').where((line) => line.startsWith('data: ') && line != 'data: [DONE]');
    for (final line in lines) {
      final data = jsonDecode(line.substring(6));
      final content = data['choices'][0]['delta']['content'] ?? '';
      textBuffer += content;

      // 按句号/换行分割,积累完整语义单元
      if (textBuffer.contains('.') || textBuffer.contains('\n')) {
        final parts = textBuffer.split(RegExp(r'(?<=\.)|(?<=\n)'));
        for (final part in parts) {
          if (part.trim().isNotEmpty) {
            audioQueue.add(part.trim());
          }
        }
        textBuffer = parts.last.trim();
      }

      // 启动播放队列
      if (!isPlaying && audioQueue.isNotEmpty) {
        isPlaying = true;
        _playQueue(flutterTts, audioQueue, () => isPlaying = false);
      }
    }
  }

  // 处理剩余的文本缓存
  if (textBuffer.trim().isNotEmpty) {
    audioQueue.add(textBuffer.trim());
    if (!isPlaying) {
      _playQueue(flutterTts, audioQueue, () => isPlaying = false);
    }
  }
}

Future<void> _playQueue(FlutterTts tts, Queue<String> queue, VoidCallback onQueueEmpty) async {
  if (queue.isEmpty) {
    onQueueEmpty();
    return;
  }
  final text = queue.removeFirst();
  await tts.speak(text);
  tts.setCompletionHandler(() => _playQueue(tts, queue, onQueueEmpty));
}

内容的提问来源于stack exchange,提问作者Hyejung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:27:29