Flutter使用assets_audio_player实现音频进度滑块与拖拽跳转功能
基于assets_audio_player的音频进度滑块实现方案
核心实现逻辑
整体通过监听播放器的实时进度流绑定滑块展示值,同时增加拖拽状态标记避免播放更新和用户操作冲突,拖拽结束后调用播放器的seek接口完成进度跳转。
1. 核心变量声明
final AssetsAudioPlayer _audioPlayer = AssetsAudioPlayer(); // 标记滑块是否处于拖拽状态,避免播放进度流更新干扰拖拽操作 bool _isDragging = false; // 存储滑块当前进度值,范围0~1 double _currentSliderValue = 0.0;
2. 播放进度监听
在初始化音频播放器的逻辑中,添加进度流监听,非拖拽状态下自动同步滑块值:
// 监听实时播放进度 _audioPlayer.currentPosition.listen((playPosition) { if (!_isDragging && _audioPlayer.current.value != null) { final totalDuration = _audioPlayer.current.value!.audio.duration; if (totalDuration.inMilliseconds > 0) { _currentSliderValue = playPosition.inMilliseconds / totalDuration.inMilliseconds; } } });
3. 滑块组件实现
直接使用Flutter原生Slider组件,绑定拖拽回调逻辑:
StreamBuilder<Duration>( stream: _audioPlayer.currentPosition, builder: (context, snapshot) { final totalDuration = _audioPlayer.current.valueOrNull?.audio.duration ?? Duration.zero; final currentPosition = snapshot.data ?? Duration.zero; return Column( children: [ Slider( value: _currentSliderValue.clamp(0.0, 1.0), min: 0.0, max: 1.0, // 拖拽过程中更新临时进度 onChanged: (value) { _isDragging = true; _currentSliderValue = value; }, // 开始拖拽时标记状态 onChangeStart: (value) => _isDragging = true, // 拖拽结束时跳转播放进度 onChangeEnd: (value) { _isDragging = false; final targetPos = Duration( milliseconds: (value * totalDuration.inMilliseconds).toInt(), ); _audioPlayer.seek(targetPos); }, ), // 可选:展示进度文本 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(_formatDuration(currentPosition)), Text(_formatDuration(totalDuration)), ], ) ], ); } )
4. 辅助时长格式化方法
String _formatDuration(Duration duration) { String twoDigits(int num) => num.toString().padLeft(2, "0"); final minutes = twoDigits(duration.inMinutes.remainder(60)); final seconds = twoDigits(duration.inSeconds.remainder(60)); return "$minutes:$seconds"; }
注意事项
- 页面销毁时必须调用
_audioPlayer.dispose()释放资源,避免内存泄漏 - 音频未完成加载时,可以将Slider的
onChanged赋值为null设置为禁用状态,避免空指针异常
内容的提问来源于stack exchange,提问作者Sara Amine
相关产品推荐
相关产品推荐

