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

使用just_audio和audio_service的HLS流音频播放器暂停超1分钟后无响应

解决方案

根因说明

故障由HLS流的原生特性触发:HLS服务端返回的分片通常带有有效期限制,暂停时间超过已缓冲时长后,已缓存的分片以及播放列表地址会过期失效,just_audio默认不会自动重新拉取最新的播放资源,直接进入idle状态,同时上层audio_service未处理该异常场景,导致锁屏控件无响应。

修复步骤

  • 调整播放器缓冲配置,增加过期分片容错时长
    修改AudioPlayer初始化参数,适配你的HLS分片有效时长:
final audioPlayer = AudioPlayer(
  bufferConfiguration: BufferConfiguration(
    // 按实际业务的HLS分片有效期调整,建议设置为分片有效期的1.5倍
    maxStale: const Duration(seconds: 300),
  ),
);
  • 监听播放器状态,异常进入idle时自动恢复
    增加processingState监听,区分用户主动停止和异常失效场景,自动重新加载音频源:
// 自行维护标记位,用户主动调用stop/ dispose时设为true
bool isUserInitiatedStop = false;

audioPlayer.processingStateStream.listen((state) async {
  if (state == ProcessingState.idle 
      && audioPlayer.audioSource != null 
      && !isUserInitiatedStop) {
    // 保存当前播放进度
    final lastPosition = audioPlayer.position;
    // 重新加载最新的音频源,注意此处要拉取最新的未过期HLS地址,不要复用缓存的旧URL
    await audioPlayer.setAudioSource(
      HlsAudioSource(Uri.parse(yourLatestHlsUrl)),
      initialPosition: lastPosition,
    );
    // 若当前处于待播放状态,自动触发播放
    if (audioPlayer.playing) {
      await audioPlayer.play();
    }
  }
});
  • 适配audio_service的播放回调逻辑
    在自定义AudioHandler的play方法中增加idle状态兼容,避免锁屏点击无响应:
class MyAudioHandler extends BaseAudioHandler {
  @override
  Future<void> play() async {
    if (audioPlayer.processingState == ProcessingState.idle) {
      // 复用上述的音频源重新加载逻辑
      final lastPosition = audioPlayer.position;
      await audioPlayer.setAudioSource(
        HlsAudioSource(Uri.parse(yourLatestHlsUrl)),
        initialPosition: lastPosition,
      );
    }
    await audioPlayer.play();
    super.play();
  }
}

日志排查补充

上层just_audio未捕获日志是因为报错由底层播放器抛出,可直接查看底层日志定位其他潜在问题:

  • 安卓端执行adb logcat | grep ExoPlayer查看ExoPlayer报错信息
  • iOS端通过Xcode控制台查看AVPlayer相关报错信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:09:03