mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
unmute me
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -78,7 +78,7 @@
|
||||
<script defer src="https://analytics.otter.land/script.js" data-website-id="82dd56a5-db44-4279-bd1e-a4d9fee39af7" data-domains="rover.otter.land"></script>
|
||||
<script defer src="https://analytics.otter.land/recorder.js" data-website-id="82dd56a5-db44-4279-bd1e-a4d9fee39af7" data-domains="rover.otter.land" data-sample-rate="0.15" data-mask-level="moderate" data-max-duration="300000"></script>
|
||||
<title>Roomba Rover</title>
|
||||
<script type="module" crossorigin src="/assets/index-DM5rqxP4.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-C_Ron8xr.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DwpUkSbG.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { isFeatureEnabled } from '../../lib/features.js';
|
||||
import { innerFlowClass } from './constants.js';
|
||||
|
||||
const PTZ_CAMERA_ID = 'ptz-camera';
|
||||
const PTZ_AUDIO_RETRY_MS = 1000;
|
||||
|
||||
function formatRemaining(deadline) {
|
||||
const remaining = Math.max(0, Math.ceil((Number(deadline || 0) - Date.now()) / 1000));
|
||||
@@ -81,6 +82,7 @@ function PtzLiveVideo({ enabled }) {
|
||||
const videoRef = useRef(null);
|
||||
const playerRef = useRef(null);
|
||||
const retryTimerRef = useRef(null);
|
||||
const playTimerRef = useRef(null);
|
||||
const [status, setStatus] = useState('idle');
|
||||
const [retryVersion, setRetryVersion] = useState(0);
|
||||
const sources = useVideoRequests(
|
||||
@@ -114,6 +116,7 @@ function PtzLiveVideo({ enabled }) {
|
||||
url: source.url,
|
||||
token: source.token,
|
||||
video: videoRef.current,
|
||||
startMuted: false,
|
||||
onStatus: (nextStatus) => {
|
||||
setStatus(nextStatus);
|
||||
if (['error', 'failed', 'disconnected', 'closed'].includes(String(nextStatus || '').toLowerCase())) {
|
||||
@@ -132,12 +135,45 @@ function PtzLiveVideo({ enabled }) {
|
||||
};
|
||||
}, [enabled, scheduleRetry, source?.token, source?.url]);
|
||||
|
||||
useEffect(() => {
|
||||
const video = videoRef.current;
|
||||
if (!enabled || !source?.url || !video) {
|
||||
if (playTimerRef.current) clearInterval(playTimerRef.current);
|
||||
playTimerRef.current = null;
|
||||
return undefined;
|
||||
}
|
||||
/*
|
||||
The server now publishes inline Opus audio on the PTZ WHEP stream. The
|
||||
shared WHEP helper starts playback once, but browsers can still reject or
|
||||
pause audible media depending on the exact timing of the fullscreen/user
|
||||
gesture. Retry the same element with muted=false so unmuting is not a
|
||||
manual DevTools-only operation.
|
||||
*/
|
||||
const attemptPlay = () => {
|
||||
const target = videoRef.current;
|
||||
if (!target) return;
|
||||
target.muted = false;
|
||||
if (!target.paused && !target.ended) return;
|
||||
target.play().catch(() => {});
|
||||
};
|
||||
attemptPlay();
|
||||
playTimerRef.current = setInterval(attemptPlay, PTZ_AUDIO_RETRY_MS);
|
||||
return () => {
|
||||
if (playTimerRef.current) clearInterval(playTimerRef.current);
|
||||
playTimerRef.current = null;
|
||||
};
|
||||
}, [enabled, source?.url, status]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (retryTimerRef.current) {
|
||||
clearTimeout(retryTimerRef.current);
|
||||
retryTimerRef.current = null;
|
||||
}
|
||||
if (playTimerRef.current) {
|
||||
clearInterval(playTimerRef.current);
|
||||
playTimerRef.current = null;
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -29,12 +29,19 @@ function buildAuthHeader(token) {
|
||||
}
|
||||
|
||||
export class WhepPlayer {
|
||||
constructor({ url, token, video, onStatus, audioOnly = false, receiveAudio = true }) {
|
||||
constructor({ url, token, video, onStatus, audioOnly = false, receiveAudio = true, startMuted = null }) {
|
||||
this.url = url;
|
||||
this.token = token;
|
||||
this.video = video;
|
||||
this.audioOnly = audioOnly;
|
||||
this.receiveAudio = receiveAudio;
|
||||
/*
|
||||
Browser autoplay usually requires normal video streams to start muted,
|
||||
while audio-only streams need to start audible. Keep that historical
|
||||
default, but allow a caller that is already behind a user gesture, such as
|
||||
the PTZ fullscreen controller, to request audible inline audio.
|
||||
*/
|
||||
this.startMuted = startMuted === null ? !audioOnly : Boolean(startMuted);
|
||||
this.pc = null;
|
||||
this.abortController = null;
|
||||
this.onStatus = onStatus;
|
||||
@@ -50,7 +57,7 @@ export class WhepPlayer {
|
||||
if (!this.video) return;
|
||||
this.video.playsInline = true;
|
||||
this.video.autoplay = true;
|
||||
this.video.muted = this.audioOnly ? false : true;
|
||||
this.video.muted = this.startMuted;
|
||||
if (typeof this.video.disableRemotePlayback !== 'undefined') {
|
||||
this.video.disableRemotePlayback = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user