React中<audio>组件无法从指定时间播放的问题求助
React音频从指定时间点播放问题修复
你的问题核心在于:组件初始挂载时yesChecker为false,<audio>元素还没被渲染,导致你写的空依赖useEffect无法获取到有效的audioRef,自然没法设置播放起始时间。而且当yesChecker变为true后,这个空依赖的useEffect也不会重新执行,所以音频始终从0秒开始。
修复方案:
调整useEffect的依赖项,让它在yesChecker变为true时触发,同时处理音频加载状态,确保设置currentTime时音频元数据已加载完成。
修改后的代码:
import { useState, useEffect, useRef } from "react"; import "./App.css"; import audioFile from "./assets/Everybody.mp3"; export default function App() { const [noIdx, setNoIdx] = useState(0); const [yesChecker, setYesChecker] = useState(false); const yesSize = noIdx * 20 + 16; const audioRef = useRef<HTMLAudioElement | null>(null); // ... 其他代码保持不变 // 调整后的useEffect,依赖yesChecker useEffect(() => { // 只有当yesChecker为true且audio元素存在时才执行 if (!yesChecker || !audioRef.current) return; const audio = audioRef.current; // 处理音频播放的逻辑 const startAudioAt13s = () => { audio.currentTime = 13; // 处理浏览器自动播放限制,需要catch错误 audio.play().catch(err => { console.error("音频播放失败:", err); }); }; // 如果音频已经加载了元数据,直接执行 if (audio.readyState >= 2) { // HAVE_CURRENT_DATA 状态表示已获取到足够的元数据 startAudioAt13s(); } else { // 否则监听loadedmetadata事件,加载完成后执行 audio.addEventListener("loadedmetadata", startAudioAt13s); } // 清理函数,移除事件监听 return () => { audio.removeEventListener("loadedmetadata", startAudioAt13s); }; }, [yesChecker]); // 依赖yesChecker,状态变化时重新执行 const handleNoClick = () => { setNoIdx(noIdx + 1); createHeart(); const noText = getNoText(); if (noText === "está bien") { setYesChecker(true); } }; // ... 其他代码保持不变 return ( <div className="flex flex-col items-center justify-center"> {yesChecker ? ( <> <div className="flex flex-col items-center"> <img className="h-[300px] mx-auto" src="https://media.tenor.com/BNcELzaiMDkAAAAi/happy-valentines-day-my-love.gif" alt="Happy Valentine's Day" /> {/* 移除autoPlay,由代码控制播放 */} <audio ref={audioRef} src={audioFile} /> <h1 className="text-4xl my-4 text-center"> XFIN! :3</h1> </div> </> ) : ( // ... 原来的其他内容 )} </div> ); }
关键改动说明:
- 更新
useEffect依赖:加入yesChecker,确保当状态变为true时,代码能触发执行,此时<audio>元素已经渲染到DOM中,audioRef能获取到有效实例。 - 移除
autoPlay属性:避免浏览器自动从0秒开始播放,完全由代码控制播放时机和起始位置。 - 判断音频加载状态:直接检查
readyState,如果音频已经加载完成,无需等待loadedmetadata事件,提升响应速度。 - 处理播放错误:调用
play()时添加catch,处理浏览器的自动播放限制(比如用户未交互时无法自动播放的情况)。
内容的提问来源于stack exchange,提问作者Padax39
相关产品推荐
相关产品推荐

