反应:尝试从音频元素创建媒体元素源时出现 InvalidStateError

React: InvalidStateError when trying to create a Media Element Source from an Audio element

我正在使用 React v17.0.1。

在一个组件中,组件 A,我有一个音频元素。 JSX 看起来像:

<audio ref={handleAudioRef} hidden={true} preload="auto" id={`audio-ref-id-${pk}`} key={pk}>
  <source src={audio} />
</audio>

其中 handleAudioRef 看起来像:

 const handleAudioRef = (r) => {
      audioRef.current = r;
  }

请注意 audioRef 是一个 context 作为 audioRef = useRef(null); 初始化

在另一个组件中,我想访问同一个音频元素并向其附加 Analyzer Node

所以我在组件B中尝试了以下内容:

    const audioCtx =  new AudioContext();
    const analyser = audioCtx.createAnalyser();
    const source = audioCtx.createMediaElementSource(audioRef.current);

注意 audioRef 与 Component A 中的 context 相同,但我收到以下错误:

InvalidStateError: Failed to execute 'createMediaElementSource' on 'AudioContext': HTMLMediaElement already connected previously to a different MediaElementSourceNode. how to obtain media element source node

现在我明白这是一个长期存在的问题,see here。但我特别想知道在 React 中,最好的解决方法是什么(如果有的话)。

我的假设是,在某些时候,React/Javascript 从原始音频元素创建了一个 MediaElementSourceNode,并且它存在于 Javascript-land 的某处。有什么方法可以访问这个创建的 MediaElementSourceNode 吗?或者是否有更好的方法来完成此操作?

如果可能,我想使用 音频元素 保留 组件 A,而不是使用 重写它]AudioContext.

SO 上发布了针对此问题的解决方案。但是在不同的上下文中询问。我把原来的link输给了解决方案。 但它归结为 createMediaElementSource 需要在 audioRef 事件之后声明 canplaythrough 它没有媒体元素是否在不同的组件中呈现很重要。

如:

audioRef.current.addEventListener('canplaythrough', function(){ 
  const audioCtx =  new AudioContext();
  const analyser = audioCtx.createAnalyser();
  const source = audioCtx.createMediaElementSource(audioRef.current);
}