一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Android播放器进度条功能重构实践:基于语句粒度的音频列表与秒级时间轴精准映射

时间:2026-05-30 15:00:02 编辑:袖梨 来源:一聚教程网

Android播放器进度条改造实践:将句级音频列表映射为秒级时间轴,实现更精准的播放控制。本文详细介绍实现思路与关键代码。

Android 播放器进度条改造实践:句级音频列表映射秒级时间轴

传统音频播放器以秒为单位显示和控制进度,而当前系统采用句为单位显示。由于句子长度差异,导致进度条显示不连贯。需要改造为秒级控制,实现与传统播放器一致的体验。

实现思路

  1. 计算总时长:从数据模型获取每句时长并累加,设置进度条总长度和UI显示。若数据不支持,则需加载音频后计算时长。
//数据获取时累加时长
if (list.get(i) != null && list.get(i).getDuration() > 0) {
   map.put("duration", list.get(i).getDuration() + "");
   long duration = list.get(i).getDuration();
   ConstantFd.durations.add(duration);
   ConstantFd.totalDuration = ConstantFd.totalDuration + duration;
}
//全局变量定义
public static List durations = new ArrayList<>();
public static long totalDuration = 0;
public static int currentPoi = 0;

  1. 进度更新机制:在播放服务中创建Handler每秒发送进度,UI接收后转换并展示。
private static long process = 0;
private static long max = 0;
private final Handler mHandler_tb = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case 0:
                max = ConstantFd.totalDuration;
                long cur = apm.getMediaPlayer().getCurrentPosition();
                process = cur + getPlayProcess();
                PoiToUIMsg.sendMsg(process, max);
                if(ConstantFd.isplay){
                    mHandler_tb.sendEmptyMessageDelayed(0, 1000);
                }
                break;
        }
        return true;
    }
});

  1. 秒句转换:播放过程中实现秒与句的相互转换,处理进度条滑动事件。
mBinding.seekbar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        PoiToPlayMsg.sendMsg(seekBar.getProgress());
    }
});

private void seekToSpecificPoi(long totalPositionMs) {
    long accumulatedDuration = 0l;
    for (int i = 0; i < ConstantFd.durations.size(); i++) {
        long duration = ConstantFd.durations.get(i);
        if (totalPositionMs < accumulatedDuration + duration) {
            readAdapter.mPosSomeTime = i;
            break;
        }
        accumulatedDuration += duration;
    }
}

  1. 服务层处理:根据秒数计算播放指针,处理连续播放时的秒数计算。
private void seekToSpecificPosition(long totalPositionMs) {
    process = totalPositionMs;
    long accumulatedDuration = 0l;
    for (int i = 0; i < ConstantFd.durations.size(); i++) {
        long duration = ConstantFd.durations.get(i);
        if (totalPositionMs < accumulatedDuration + duration) {
            long relativePositionMs = totalPositionMs - accumulatedDuration;
            apm.getMediaPlayer().seekTo(relativePositionMs);
            break;
        }
        accumulatedDuration += duration;
    }
}

核心算法:秒-句转换

包含两种遍历逻辑:

  • 服务层处理:将秒数拆分为句索引和句内偏移量
  • UI层处理:仅计算句索引,用于列表高亮和滚动
示例:总时长9500ms(句0:3000ms + 句1:2500ms + 句2:4000ms)
用户拖动到5500ms:
- 句0累计3000ms
- 句1累计5500ms
- 落在句1内偏移2500ms
边界情况:拖动到9500ms时直接定位最后一句

通过改造实现了句级音频列表到秒级时间轴的精准映射,使Android播放器获得与传统音乐播放器一致的用户体验。核心在于秒句转换算法和实时进度更新机制的设计实现。

热门栏目