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

如何修复音频播放器暂停时拖动进度条后剩余时间显示异常问题

问题原因
  • 核心原因是HTMLMediaElement的currentTime属性赋值为异步生效,你在mouseup事件里刚给au.currentTime赋值完就立即读取该属性,此时取到的还是赋值前的旧值。如果赋值前音频暂停在0s位置,那au.duration - 旧currentTime就等于总时长,完全符合你遇到的现象。
  • 还有两个隐性问题可能会引发其他异常:
    1. mousedown里的paused变量没有加声明关键字,会泄露为全局变量
    2. 每次点击播放按钮如果未加载文件,都会重复给文件选择框绑定input事件,会导致上传逻辑多次触发
修复方案

直接用已经解析好的进度条值计算剩余时长,不要依赖异步更新的au.currentTime,同时修复上述隐性问题即可。
需要修改的代码片段如下:

  1. 修改mouseup事件逻辑
tj.addEventListener("mouseup", ()=>{
  tj.removeEventListener("input", imput);
  // 提前解析好目标进度值,后续直接复用
  const targetTime = JSON.parse(tj.value);
  au.currentTime = targetTime;
  if(!paused){
    au.play();
    iv = setInterval(()=>{
      ts.value = au.currentTime;
      tj.value = au.currentTime;
      tt.value = math("-", [au.duration, au.currentTime]);
    }, 1);
    pp.innerText = "⏸️"
  }else{
    pp.innerText = "️▶️";
    ts.value = targetTime;
    // 直接用解析好的目标时间计算,不需要等currentTime异步更新
    tt.value = math("-", [au.duration, targetTime]);
  }
});
  1. 给paused变量加声明,避免全局污染
tj.addEventListener("mousedown", ()=>{
  // 加let声明,防止变量泄露
  let paused = au.paused;
  au.pause();
  pp.innerText = "️↔️";
  try{
    clearInterval(iv);
  }catch(USLISERROOR){}
  tj.addEventListener("input", imput);
});
  1. 把文件选择框的监听逻辑移到初始化阶段,避免重复绑定
    将原本写在播放按钮点击逻辑里的fi.addEventListener部分,移到文件选择框初始化代码之后,只绑定一次:
fi = document.createElement("input");
fi.type = "file";
// 文件选择监听移到此处,全局只绑定一次
fi.addEventListener("input", ()=>{
  fl = fi.files[0];
  bt.innerText = "checking file type...";
  if(fl.type.startsWith("audio/")){
    bt.innerText = "reading file...";
    rd = new FileReader();
    rd.readAsBinaryString(fl);
    rd.addEventListener("loadend", ()=>{
      au.src = "data:"+fl.type+";base64,"+btoa(rd.result);
      bt.innerText = "reconstructing audio ..."
      ts.value = 0;
      tj.hidden = false;
      tj.value = 0;
      sl.disabled = false;
      ly.disabled = false;
      sl.placeholder = "input lyrics";
      au.addEventListener("canplaythrough", ()=>{
        bt.innerText = "";
        tj.max = au.duration;
        tt.value = au.duration;
      })
    });
  }else{
    bt.innerText = "please input audio only.";
    fl = null;
  }
});

然后删除原来播放按钮点击逻辑里重复绑定的监听代码,仅保留触发文件选择的逻辑即可:

}else{
  bt.innerText = "waiting for input..."
  fi.click();
  // 删除原来此处的fi.addEventListener逻辑
}

内容的提问来源于stack exchange,提问作者TGP1cccul8r

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:15:04