Flutter使用audioplayers播放长音频触发Slider参数越界报错如何解决
问题原因
- 核心触发逻辑:Flutter Slider组件要求传入的
value必须满足min ≤ value ≤ max的强制校验,你的代码中Slider的value取的是当前播放进度position的秒数,max取的是音频总时长musicLength的秒数,当position大于musicLength时就会抛出这个错误。 - 长音频才报错的原因:短音频加载速度快,
audioplayers的durationHandler能在播放启动前就拿到准确的总时长赋值给musicLength;而长音频加载慢,播放启动后进度position已经开始更新,但总时长还未完成解析,musicLength还是初始的0秒,或者解析出来的总时长存在偏差,就会出现position > musicLength的越界情况。
修复方案
1. 给Slider的值增加边界限制(最直接的修复)
直接修改你slider()方法里Slider的属性,用clamp方法强制把值限制在合法范围内,哪怕出现进度越界也会被自动修正:
Widget slider() { return Container( width: 300.0, child: Slider.adaptive( activeColor: Colors.amber[800], inactiveColor: Colors.grey[350], // 增加clamp限制值的范围,避免越界;总时长为0时默认返回0 value: position.inSeconds.toDouble().clamp(0.0, musicLength.inSeconds.toDouble() > 0 ? musicLength.inSeconds.toDouble() : 1.0), min: 0.0, // 总时长为0时临时给个默认max,避免min等于max的报错 max: musicLength.inSeconds.toDouble() > 0 ? musicLength.inSeconds.toDouble() : 1.0, onChanged: (value) { if(musicLength.inSeconds > 0) { // 总时长没拿到时禁止拖动 seekToSec(value.toInt()); } }), ); }
2. 优化进度回调逻辑
修改positionHandler的回调,避免无效的越界进度更新,同时增加mounted判断避免页面销毁后调用setState报错:
_player.positionHandler = (p) { if (!mounted) return; // 总时长未解析完成、或者进度未超过总时长时才更新状态 if (musicLength.inSeconds <= 0 || p.inSeconds <= musicLength.inSeconds) { setState(() { position = p; }); } };
3. 可选优化
如果上述修改后还存在长音频总时长解析错误的问题,可以升级audioplayers到最新正式版,旧版本的audioplayers对长音频、部分编码格式的音频时长解析存在已知bug。
内容的提问来源于stack exchange,提问作者mark anthony
相关产品推荐
相关产品推荐

