fix(webapp): prime remote live streams before viewing
This commit is contained in:
@@ -98,6 +98,7 @@ let clientVideoElement = null;
|
|||||||
|
|
||||||
const peerConnections = new Map();
|
const peerConnections = new Map();
|
||||||
const remoteStreams = new Map();
|
const remoteStreams = new Map();
|
||||||
|
const hiddenClientStreamElements = new Map();
|
||||||
const pendingCandidatesMap = new Map();
|
const pendingCandidatesMap = new Map();
|
||||||
const streamTimers = new Map();
|
const streamTimers = new Map();
|
||||||
const connectedPeers = new Set();
|
const connectedPeers = new Set();
|
||||||
@@ -536,6 +537,33 @@ const attachClientStreamToElement = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const primeClientStreamPlayback = (streamSessionId, stream) => {
|
||||||
|
if (!streamSessionId || !stream) return;
|
||||||
|
|
||||||
|
let hiddenVideoElement = hiddenClientStreamElements.get(streamSessionId);
|
||||||
|
if (!hiddenVideoElement && typeof document !== 'undefined') {
|
||||||
|
hiddenVideoElement = document.createElement('video');
|
||||||
|
hiddenVideoElement.muted = true;
|
||||||
|
hiddenVideoElement.autoplay = true;
|
||||||
|
hiddenVideoElement.playsInline = true;
|
||||||
|
hiddenVideoElement.style.position = 'fixed';
|
||||||
|
hiddenVideoElement.style.width = '1px';
|
||||||
|
hiddenVideoElement.style.height = '1px';
|
||||||
|
hiddenVideoElement.style.opacity = '0';
|
||||||
|
hiddenVideoElement.style.pointerEvents = 'none';
|
||||||
|
hiddenVideoElement.style.left = '-9999px';
|
||||||
|
hiddenVideoElement.style.top = '-9999px';
|
||||||
|
document.body.appendChild(hiddenVideoElement);
|
||||||
|
hiddenClientStreamElements.set(streamSessionId, hiddenVideoElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hiddenVideoElement) return;
|
||||||
|
if (hiddenVideoElement.srcObject !== stream) {
|
||||||
|
hiddenVideoElement.srcObject = stream;
|
||||||
|
}
|
||||||
|
void hiddenVideoElement.play().catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
const startCameraPreview = async (cameraInputId = getAppState().selectedCameraInputId) => {
|
const startCameraPreview = async (cameraInputId = getAppState().selectedCameraInputId) => {
|
||||||
if (!navigator.mediaDevices?.getUserMedia) {
|
if (!navigator.mediaDevices?.getUserMedia) {
|
||||||
pushToast('Camera API is not available in this browser', 'error');
|
pushToast('Camera API is not available in this browser', 'error');
|
||||||
@@ -1121,6 +1149,12 @@ const teardownPeerConnection = (streamSessionId) => {
|
|||||||
}
|
}
|
||||||
peerConnections.clear();
|
peerConnections.clear();
|
||||||
remoteStreams.clear();
|
remoteStreams.clear();
|
||||||
|
for (const hiddenVideoElement of hiddenClientStreamElements.values()) {
|
||||||
|
hiddenVideoElement.pause();
|
||||||
|
hiddenVideoElement.srcObject = null;
|
||||||
|
hiddenVideoElement.remove();
|
||||||
|
}
|
||||||
|
hiddenClientStreamElements.clear();
|
||||||
pendingCandidatesMap.clear();
|
pendingCandidatesMap.clear();
|
||||||
connectedPeers.clear();
|
connectedPeers.clear();
|
||||||
setConnectedStreamSessionIds();
|
setConnectedStreamSessionIds();
|
||||||
@@ -1134,6 +1168,15 @@ const teardownPeerConnection = (streamSessionId) => {
|
|||||||
peerConnections.delete(streamSessionId);
|
peerConnections.delete(streamSessionId);
|
||||||
}
|
}
|
||||||
remoteStreams.delete(streamSessionId);
|
remoteStreams.delete(streamSessionId);
|
||||||
|
if (hiddenClientStreamElements.has(streamSessionId)) {
|
||||||
|
const hiddenVideoElement = hiddenClientStreamElements.get(streamSessionId);
|
||||||
|
hiddenVideoElement?.pause();
|
||||||
|
if (hiddenVideoElement) {
|
||||||
|
hiddenVideoElement.srcObject = null;
|
||||||
|
hiddenVideoElement.remove();
|
||||||
|
}
|
||||||
|
hiddenClientStreamElements.delete(streamSessionId);
|
||||||
|
}
|
||||||
pendingCandidatesMap.delete(streamSessionId);
|
pendingCandidatesMap.delete(streamSessionId);
|
||||||
connectedPeers.delete(streamSessionId);
|
connectedPeers.delete(streamSessionId);
|
||||||
setConnectedStreamSessionIds();
|
setConnectedStreamSessionIds();
|
||||||
@@ -1236,7 +1279,10 @@ const ensurePeerConnection = async ({ streamSessionId, targetDeviceId, asCamera
|
|||||||
if (getAppState().activeStreamSessionId === streamSessionId) {
|
if (getAppState().activeStreamSessionId === streamSessionId) {
|
||||||
attachClientStreamToElement();
|
attachClientStreamToElement();
|
||||||
setClientStreamMode('video');
|
setClientStreamMode('video');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
primeClientStreamPlayback(streamSessionId, stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (asCamera) {
|
if (asCamera) {
|
||||||
|
|||||||
Reference in New Issue
Block a user