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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:36:05