React中无法获取react-h5-audio-player的currentTime属性问题
解决react-h5-audio-player currentTime无法实时更新的问题
你的代码里有两个核心问题导致播放时间无法实时更新:
- 用
useEffect依赖playTime来触发时间更新是逻辑错误,这只会在playTime变化时执行一次,而音频播放时的时间变化不会主动触发这个逻辑,反而可能引发不必要的循环。 - 没有监听音频原生的
timeupdate事件,这才是获取实时播放时间的正确方式。
方案一:使用组件自带的onTimeUpdate回调
react-h5-audio-player封装了原生音频的事件,直接用它提供的onTimeUpdate回调就能拿到实时时间:
import { useEffect, useState, useRef } from "react"; import "./styles.css"; import AudioPlayer from "react-h5-audio-player"; import "react-h5-audio-player/lib/styles.css"; import Button from "./components/Button"; export default function App() { const [file, setFile] = useState(); const [playTime, setCurrentTime] = useState(0); const inputFileRef = useRef(null); function clickHandle(e) { const filename = URL.createObjectURL(inputFileRef.current.files[0]); setFile(filename); } // 直接用组件的onTimeUpdate回调更新时间 const handleTimeUpdate = (e) => { setCurrentTime(e.target.currentTime); }; return ( <div> <Button refs={inputFileRef} clickHandle={clickHandle}/> <p>Current time: {playTime.toFixed(2)}</p> <AudioPlayer autoPlay src={file} onPlay={(e) => console.log("playing")} onTimeUpdate={handleTimeUpdate} // 这里添加回调 /> </div> ); }
方案二:手动监听原生audio元素的timeupdate事件
如果需要用ref操作原生音频元素,可以在useEffect里添加事件监听,记得组件卸载时清理:
import { useEffect, useState, useRef } from "react"; import "./styles.css"; import AudioPlayer from "react-h5-audio-player"; import "react-h5-audio-player/lib/styles.css"; import Button from "./components/Button"; export default function App() { const [file, setFile] = useState(); const [playTime, setCurrentTime] = useState(0); const inputFileRef = useRef(null); const audioRef = useRef(null); function clickHandle(e) { const filename = URL.createObjectURL(inputFileRef.current.files[0]); setFile(filename); } const handleTimeUpdate = () => { if (audioRef.current?.audio.current) { setCurrentTime(audioRef.current.audio.current.currentTime); } }; useEffect(() => { const audioElement = audioRef.current?.audio.current; if (audioElement) { // 添加时间更新监听 audioElement.addEventListener('timeupdate', handleTimeUpdate); // 组件卸载时移除监听,避免内存泄漏 return () => { audioElement.removeEventListener('timeupdate', handleTimeUpdate); }; } }, [file]); // 当file变化时,重新获取音频元素并添加监听 return ( <div> <Button refs={inputFileRef} clickHandle={clickHandle}/> <p>Current time: {playTime.toFixed(2)}</p> <AudioPlayer autoPlay src={file} onPlay={(e) => console.log("playing")} ref={audioRef} /> </div> ); }
两种方案都能实现实时更新播放时间,推荐用方案一,更符合组件的封装设计,代码更简洁。
内容的提问来源于stack exchange,提问作者Preet Singh
相关产品推荐
相关产品推荐

