gpt4 book ai didi

javascript - React HTMLAudioElement 不会暂停

转载 作者:行者123 更新时间:2023-12-03 00:23:24 34 4
gpt4 key购买 nike

我在 React 中有一个组件,它接受一个 URL 并显示一个让用户停止/暂停音频文件的按钮。该组件在页面上多次使用。
按钮启动音频就好了,但是它 audio.pause()不会停止流。
我正在使用 Next.js,但是我正在像这样导入组件:

const HistoryRow = dynamic(() => import('../components/HistoryRow'), { ssr: false });
有人知道为什么这不会停止流吗?我可以确认它正在输入 if 语句就好了。
import { useState } from 'react';
import m from 'moment';
import path from 'path';

function HistoryRow({ data }) {
const [playing, setPlaying] = useState(false);
const audio = new Audio(`${window.location.origin}/audio-responses/${data.timestamp}.wav`);

audio.onended = function () {
setPlaying(false);
};

audio.onpause = function () {
setPlaying(false);
};

audio.onplay = function () {
setPlaying(true);
};

audio.onerror = function () {
setPlaying(false);
};

function execute() {
if (playing) {
audio.pause();
} else {
audio.play();
}
}

const stopSvg = (
<svg> /** svg data ** / </svg>
);

const playSvg = (
<svg> /** svg data ** / </svg>
);

return (
<div className="text-base flex leading-5 font-medium text-blue-600 truncate" onClick={() => execute()}>
{data.type === 'command' ? (playing ? stopSvg : playSvg) : null}
</div>
);
}

export default HistoryRow;

最佳答案

每当您声明更改时,都会重新渲染整个组件。这意味着组件中的每个变量都被重写。所以你创建一个 Audio实例,然后开始播放,组件重新渲染和新的 Audio实例被创建 en 因此你失去了与前一个实例的绑定(bind)。
您可以使用 useRef Hook 以创建对 Audio 的引用在组件的整个生命周期中持续存在的实例。所以它永远不会改变,除非你明确告诉它。您可以使用 current 访问实例返回 useRef 上的属性值(value)。
由于 React 是状态驱动的,我建议使用 useEffect 钩子(Hook)监听 playing 的变化状态并根据 playing 的值开始或停止播放状态,这与您目前的情况相反。

function HistoryRow({ data }) {
const [playing, setPlaying] = useState(false);
const [hasError, setHasError] = useState(false);
const audio = useRef(new Audio(`${window.location.origin}/audio-responses/${data.timestamp}.wav`));

audio.current.onended = function () {
setPlaying(false);
};

audio.current.onplay = function () {
setHasError(false);
};

const handleClick = () => {
setPlaying(playing => !playing);
});

useEffect(() => {
if (playing) {
audio.current.play().then(() => {
// Audio is playing.
}).catch(error => {
setHasError(true);
});
} else if (!hasError) {
audio.current.pause();
}
}, [playing, hasError]);

const stopSvg = (
<svg> /* svg data */ </svg>
);

const playSvg = (
<svg> /* svg data */ </svg>
);

return (
<div
className="text-base flex leading-5 font-medium text-blue-600 truncate"
onClick={handleClick}>
{data.type === 'command' ? (playing ? stopSvg : playSvg) : null}
</div>
);
}

关于javascript - React HTMLAudioElement 不会暂停,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64033436/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com