Flutter使用audioplayers库时Android设备无法获取音频时长及播放进度问题
针对audioplayers 0.16.1版本无法获取音频时长/进度的排查修复方案
- 修正事件监听写法
0.16.1版本的时长、进度回调依赖专属stream,需在初始化AudioPlayer实例后立即注册监听,不可延迟到播放触发后再注册,正确示例如下:
final AudioPlayer audioPlayer = AudioPlayer(); // 监听音频总时长回调 audioPlayer.onDurationChanged.listen((Duration d) { // 此处拿到总时长,赋值给Slider的max参数 totalDuration = d; }); // 监听实时播放进度回调 audioPlayer.onAudioPositionChanged.listen((Duration p) { // 此处拿到当前播放进度,更新Slider的value参数 currentPosition = p; });
注意:不要混用废弃的旧回调方法名,0.16.1版本的回调名称固定为onDurationChanged和onAudioPositionChanged
- 调整音频加载逻辑
0.16.1版本默认不会预加载音频元数据,直接调用play()方法会出现播放已启动但时长还未返回的问题,需调整加载顺序:
- 先调用
audioPlayer.setUrl(你的音频地址, isLocal: 本地文件传true/远程文件传false) - 等待
onDurationChanged回调拿到总时长后,再初始化Slider组件、开放播放操作入口
如果是本地音频文件,需确认文件路径格式正确,安卓端需添加读取存储权限,iOS端需将本地文件加入工程资源目录。
- 修复Slider拖拽seek、暂停后续播异常问题
这个版本存在两个已知原生层bug,需按如下方式规避:
- Slider拖拽seek时,不要直接在
onChanged实时回调中调用seek方法,要在onChangeEnd拖拽结束后再执行seek操作,避免频繁触发原生请求导致进度错乱,示例:
Slider( value: currentPosition.inMilliseconds.toDouble(), max: totalDuration.inMilliseconds.toDouble(), onChanged: (v) { // 仅更新UI,不执行seek currentPosition = Duration(milliseconds: v.round()); }, onChangeEnd: (v) async { // 拖拽结束后执行seek await audioPlayer.seek(Duration(milliseconds: v.round())); }, )
- 暂停后续播无响应的问题,需在暂停时记录当前播放进度,调用播放方法时主动传入进度参数:
// 暂停时记录进度 Duration _lastPosition; await audioPlayer.pause(); _lastPosition = currentPosition; // 续播时传入记录的进度 await audioPlayer.play(你的音频地址, position: _lastPosition);
- 适配兼容特殊机型
部分安卓6.0及以下机型存在进度流不回调的问题,可以在音频处于播放状态时,启动一个间隔为500ms的定时器,主动调用await audioPlayer.getCurrentPosition()获取实时进度更新UI,播放暂停/结束时销毁定时器即可。
内容的提问来源于stack exchange,提问作者user17496927
相关产品推荐
相关产品推荐

