[英]How to avoid "HTMLMediaElement already connected previously to a different MediaElementSourceNode" in the AudioContext Interface?
[英]How can I solve "HTMLMediaElement already connected previously to a different MediaElementSourceNode" problem using React functional component
我在使用 create-react-app 创建的应用程序中使用 React 功能组件,因此会自动启用React.StrictMode 。 我不想禁用它,因为它可以帮助我发现正在开发的潜在问题。 麻烦的是它使组件渲染两次,这会产生错误:
未捕获的 DOMException:无法在“AudioContext”上执行“createMediaElementSource”:HTMLMediaElement 之前已经连接到不同的 MediaElementSourceNode ,因为 HTMLMediaElement 在第一次渲染中连接。 我想知道,有没有办法将 HTMLMediaElement 与以前的 MediaElementSourceNode 断开连接......也许将其设置为null
或其他东西,以便它可以获得新的连接?
下面是我的引发错误的代码:
import React, { useEffect, useRef } from "react";
const Canvas = () => {
const audioRef = useRef(null);
const filUploadRef = useRef(null);
const canvasRef = useRef(null);
let audioSource;
let analyser;
let dataArray;
useEffect(() => {
const audioElement = audioRef.current;
const canvas = canvasRef.current;
const fileUploadField = filUploadRef.current;
fileUploadField.addEventListener("change", () => {
const audioContext = new AudioContext();
const files = fileUploadField.files;
audioElement.src = URL.createObjectURL(files[0]);
audioElement.load();
audioElement.play();
audioSource = audioContext.createMediaElementSource(audioElement);
analyser = audioContext.createAnalyser();
audioSource.connect(analyser);
analyser.connect(audioContext.destination);
dataArray = new Uint8Array(analyser.frequencyBinCount);
});
}, []);
const handleTogglePlayPause = () => {
//TODO: Implement toggle Play/Pause when the button is clicked.
};
return (
<>
<canvas ref={canvasRef} />
<audio controls ref={audioRef} />
<input type="file" id="file-upload" accept="audio/*" ref={filUploadRef} />
<button onClick={handleTogglePlayPause} type="button">
{/* ^ This button element is related to handleTogglePlayPause function for a different stage*/}
Play/Pause
</button>
</>
);
};
export default Canvas;
您可以检查audioSource
是否已经有源,如果有,您可以尝试避免创建新的媒体元素源。 此外,您无需创建新的分析器并连接它。
将此 if 检查添加到您的代码中,它应该可以解决问题。
// ..
audioElement.play();
if (!audioSource) {
audioSource = audioContext.createMediaElementSource(audioElement);
analyser = audioContext.createAnalyser();
audioSource.connect(analyser);
analyser.connect(audioContext.destination);
}
//..
好吧,react strict 模式有助于识别问题,但同时它也会产生新问题。 因此,您可能会考虑完全关闭严格模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.