如何 link 音频上下文中的当前时间输入类型=范围?

How can I link the current time in the audio context to input type=range?

我正在使用 React.js 和网络音频 API 创建一个播放音乐的应用程序。
Demo

你能告诉我如何 link 正在播放的音乐的输入类型=范围吗?
通过移动 input type=range,我想更改正在播放的音乐的当前时间。


源码如下

let audioCtx, audioBuffer, source;
const audioURL = "/piano.mp3";

const App = () => {
  const [load, setLoad] = useState(true);
  const [playing, setPlaying] = useState(false);
  const [total, setTotal] = useState(0);
  const [current, setCurrent] = useState(0);

  const audioLoad = async () => {
    const response = await fetch(audioURL);
    const arrayBuffer = await response.arrayBuffer();
    if (arrayBuffer) {
      audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
      setTotal(audioBuffer.duration);
    }
    setLoad(false);
  };
  useEffect(() => {
    audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    audioLoad();
    return () => {
      audioCtx.close();
      audioCtx = null;
    };
  }, []);

  const playAudio = () => {
    if (!playing) {
      source = audioCtx.createBufferSource();
      source.buffer = audioBuffer;
      source.connect(audioCtx.destination);
      source.start();
      setPlaying(true);
      return;
    }
    source.stop();
    setCurrent(0);
    setPlaying(false);
  };

  const changeSeek = (e) => {
    setCurrent(e.target.value);
    audioCtx.currentTime = current;
    console.log(audioCtx.currentTime);
  };

  return (
    <>
      <p>Total time {total}</p>
      <p>Current time {current}</p>
      <button onClick={playAudio} disabled={load ? true : false}>
        {playing ? "stop" : "play"}
      </button>
      <input
        onChange={changeSeek}
        value={current}
        type="range"
        max={total}
        style={inputStyle}
      />
    </>
  );
};

音频上下文有一个 currentTime 属性,我想我可以通过将 input type=range 的值分配给这个 属性 来更改音乐的当前时间,但我做不到这样做。

此外,我不知道如何自动移动 input type=range 以匹配音乐的当前时间。

BaseAudioContext.currentTime 是不可变的。它代表 HW 音频时钟,因此您不能随意设置以及时移动事物。如果您希望能够通过 AudioBuffer 进行搜索,您将通过创建具有所需 AudioBufferAudioBufferSourcNode 并适当地调用 start(startTime, offset, duration) 来实现搜索(可能省略 duration 参数)。

或者使用 MediaElementAudioSourceNode 并适当设置 src,因为 MediaElement 支持搜索。这不会是准确的示例,但对于您的用例来说也许没问题。