fix: track audio autoplay status separately to handle Safari blocking audio while allowing video

This commit is contained in:
Alex P 2025-10-28 15:47:36 +02:00
parent ef86af8afc
commit cd7a098f76
1 changed files with 15 additions and 5 deletions

View File

@ -29,6 +29,7 @@ export default function WebRTCVideo({ hasConnectionIssues }: { hasConnectionIssu
const audioElementsRef = useRef<HTMLAudioElement[]>([]); const audioElementsRef = useRef<HTMLAudioElement[]>([]);
const { mediaStream, peerConnectionState } = useRTCStore(); const { mediaStream, peerConnectionState } = useRTCStore();
const [isPlaying, setIsPlaying] = useState(false); const [isPlaying, setIsPlaying] = useState(false);
const [audioAutoplayBlocked, setAudioAutoplayBlocked] = useState(false);
const [isPointerLockActive, setIsPointerLockActive] = useState(false); const [isPointerLockActive, setIsPointerLockActive] = useState(false);
const [isKeyboardLockActive, setIsKeyboardLockActive] = useState(false); const [isKeyboardLockActive, setIsKeyboardLockActive] = useState(false);
@ -344,8 +345,11 @@ export default function WebRTCVideo({ hasConnectionIssues }: { hasConnectionIssu
document.body.appendChild(audioElm); document.body.appendChild(audioElm);
audioElementsRef.current.push(audioElm); audioElementsRef.current.push(audioElm);
audioElm.play().catch(() => { audioElm.play().then(() => {
setAudioAutoplayBlocked(false);
}).catch(() => {
console.debug("[Audio] Autoplay blocked, will be started by user interaction"); console.debug("[Audio] Autoplay blocked, will be started by user interaction");
setAudioAutoplayBlocked(true);
}); });
} }
}, },
@ -359,6 +363,7 @@ export default function WebRTCVideo({ hasConnectionIssues }: { hasConnectionIssu
audioElm.remove(); audioElm.remove();
}); });
audioElementsRef.current = []; audioElementsRef.current = [];
setAudioAutoplayBlocked(false);
}; };
}, },
[addStreamToVideoElm, peerConnection], [addStreamToVideoElm, peerConnection],
@ -472,11 +477,12 @@ export default function WebRTCVideo({ hasConnectionIssues }: { hasConnectionIssu
const hasNoAutoPlayPermissions = useMemo(() => { const hasNoAutoPlayPermissions = useMemo(() => {
if (peerConnection?.connectionState !== "connected") return false; if (peerConnection?.connectionState !== "connected") return false;
if (isPlaying) return false;
if (hdmiError) return false; if (hdmiError) return false;
if (videoHeight === 0 || videoWidth === 0) return false; if (videoHeight === 0 || videoWidth === 0) return false;
return true; if (!isPlaying) return true;
}, [hdmiError, isPlaying, peerConnection?.connectionState, videoHeight, videoWidth]); if (audioAutoplayBlocked) return true;
return false;
}, [audioAutoplayBlocked, hdmiError, isPlaying, peerConnection?.connectionState, videoHeight, videoWidth]);
const showPointerLockBar = useMemo(() => { const showPointerLockBar = useMemo(() => {
if (settings.mouseMode !== "relative") return false; if (settings.mouseMode !== "relative") return false;
@ -568,7 +574,11 @@ export default function WebRTCVideo({ hasConnectionIssues }: { hasConnectionIssu
show={hasNoAutoPlayPermissions} show={hasNoAutoPlayPermissions}
onPlayClick={() => { onPlayClick={() => {
videoElm.current?.play(); videoElm.current?.play();
audioElementsRef.current.forEach(audioElm => audioElm.play().catch(() => undefined)); audioElementsRef.current.forEach(audioElm => {
audioElm.play().then(() => {
setAudioAutoplayBlocked(false);
}).catch(() => undefined);
});
}} }}
/> />
</div> </div>