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

Flutter just_audio自定义MP3流播放卡顿问题求助

解决just_audio流式播放MP3卡顿、仅播放片段的问题

你当前的核心问题是每次收到HTTP流的分片数据就重新创建并设置音频源,相当于播放器每次只播放刚收到的一小段字节,自然只能听到片段且产生卡顿。下面是正确的实现方案:

1. 实现支持动态追加字节的自定义音频源

需要创建一个能持续积累字节、响应播放器数据请求的自定义源,而不是每次都生成新的源:

class StreamingMp3Source extends StreamAudioSource {
  final _accumulatedBytes = <int>[];
  final _newBytesController = StreamController<List<int>>.broadcast();

  // 向源中追加新收到的流数据
  void appendBytes(List<int> bytes) {
    _accumulatedBytes.addAll(bytes);
    _newBytesController.add(bytes);
  }

  // 流数据接收完成后关闭控制器,避免内存泄漏
  void finishStream() {
    _newBytesController.close();
  }

  @override
  Future<StreamAudioResponse> request([int? start, int? end]) async {
    start ??= 0;
    end ??= _accumulatedBytes.length;

    // 如果播放器请求的范围超过当前已积累的字节,等待新数据到来
    while (end > _accumulatedBytes.length) {
      await _newBytesController.stream.first;
      end = end! > _accumulatedBytes.length ? _accumulatedBytes.length : end;
    }

    return StreamAudioResponse(
      sourceLength: null, // 流式MP3无法提前获取总长度,设为null即可
      contentLength: end - start,
      offset: start,
      stream: Stream.value(_accumulatedBytes.sublist(start, end)),
      contentType: 'audio/mpeg',
    );
  }
}

2. 修改HTTP请求与播放器逻辑

只需要初始化一次音频源,之后持续向这个源喂流数据即可:

// 初始化自定义源和播放器
final streamingSource = StreamingMp3Source();
await japlayer.setAudioSource(streamingSource, preload: false);
await japlayer.play();

// 发送POST请求并处理流式响应
final request = http.Request(
  'POST',
  Uri.parse("你的API地址"),
);
request.bodyFields = {'xyz': 'abc'};
final streamedResponse = await request.send();

// 监听流数据,持续追加到自定义源
streamedResponse.stream.listen(
  (data) => streamingSource.appendBytes(data),
  onDone: () {
    streamingSource.finishStream();
    // 可选:播放完成后停止播放器
    // japlayer.stop();
  },
  onError: (error) {
    streamingSource.finishStream();
    // 这里可以添加错误处理逻辑,比如提示用户播放失败
  },
);

关键注意点

  • 仅设置一次音频源:避免反复调用setAudioSource打断播放流程
  • 字节累加逻辑:通过维护一个全局字节列表,让播放器能读取到完整的流数据
  • 等待新数据机制:当播放器请求的范围超出当前已积累的字节时,等待新数据到来再返回,保证播放连续性
  • 流关闭处理:在HTTP流完成或出错时关闭控制器,防止内存泄漏

内容的提问来源于stack exchange,提问作者Chandan S Gowda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 19:31:18