Fixed cases of no Media Content, and swapping Media failing.

This commit is contained in:
2026-04-26 00:14:47 -04:00
parent c4dfb07627
commit 9a3e435dd4

View File

@@ -11,23 +11,46 @@ const Media = {
const cameraSelect = document.getElementById("cameraSelect");
const micSelect = document.getElementById("micSelect");
if (!cameraSelect || !micSelect) return;
const selectedCamera = cameraSelect.value;
const selectedMic = micSelect.value;
cameraSelect.innerHTML = "";
micSelect.innerHTML = "";
const noCamera = document.createElement("option");
noCamera.value = "";
noCamera.textContent = "No camera / audio only";
cameraSelect.appendChild(noCamera);
const defaultMic = document.createElement("option");
defaultMic.value = "";
defaultMic.textContent = "Default microphone";
micSelect.appendChild(defaultMic);
for (const camera of cameras) {
const option = document.createElement("option");
option.value = camera.deviceId;
option.textContent = camera.label || `Camera ${cameraSelect.length + 1}`;
option.textContent = camera.label || `Camera ${cameraSelect.length}`;
cameraSelect.appendChild(option);
}
for (const mic of mics) {
const option = document.createElement("option");
option.value = mic.deviceId;
option.textContent = mic.label || `Microphone ${micSelect.length + 1}`;
option.textContent = mic.label || `Microphone ${micSelect.length}`;
micSelect.appendChild(option);
}
cameraSelect.value = [...cameraSelect.options].some(o => o.value === selectedCamera)
? selectedCamera
: "";
micSelect.value = [...micSelect.options].some(o => o.value === selectedMic)
? selectedMic
: "";
LogMessage(`Loaded devices: ${cameras.length} cameras, ${mics.length} mics`);
},
@@ -39,8 +62,8 @@ const Media = {
return localStream;
}
const audioDeviceId = micSelect?.value;
const videoDeviceId = cameraSelect?.value;
const audioDeviceId = micSelect?.value || "";
const videoDeviceId = cameraSelect?.value || "";
const constraints = {
audio: audioDeviceId
@@ -48,12 +71,14 @@ const Media = {
: true,
video: videoDeviceId
? { deviceId: { exact: videoDeviceId } }
: true
: false
};
try {
localStream = await navigator.mediaDevices.getUserMedia(constraints);
} catch {
} catch (err) {
LogMessage("Selected media failed: " + err);
localStream = await navigator.mediaDevices.getUserMedia({
audio: audioDeviceId
? { deviceId: { exact: audioDeviceId } }
@@ -75,13 +100,13 @@ const Media = {
const localMediaStatus = document.getElementById("localMediaStatus");
const localVideoStatus = document.getElementById("localVideoStatus");
if (localVideo) {
localVideo.srcObject = stream;
}
const audioTracks = stream.getAudioTracks();
const videoTracks = stream.getVideoTracks();
if (localVideo) {
localVideo.srcObject = videoTracks.length > 0 ? stream : null;
}
if (localMediaStatus) {
localMediaStatus.textContent =
audioTracks.length > 0
@@ -97,6 +122,19 @@ const Media = {
}
},
async restartLocalMedia() {
if (localStream) {
localStream.getTracks().forEach(track => track.stop());
localStream = null;
}
await this.ensureLocalMedia();
if (window.RelayRtc?.applyLocalStreamToAllPeerConnections) {
await window.RelayRtc.applyLocalStreamToAllPeerConnections();
}
},
async refreshDevicesAndPreview() {
if (localStream) {
localStream.getTracks().forEach(track => track.stop());
@@ -113,7 +151,6 @@ const Media = {
async applyLocalStreamToPeerConnection(pc, username) {
const stream = await this.ensureLocalMedia();
const existingSenders = pc.getSenders();
for (const track of stream.getTracks()) {
@@ -123,11 +160,11 @@ const Media = {
if (existingSender) {
await existingSender.replaceTrack(track);
LogMessage(`Replaced local ${track.kind} track for ${username}`);
} else {
pc.addTrack(track, stream);
LogMessage(`Added local ${track.kind} track for ${username}`);
}
LogMessage(`Added local ${track.kind} track for ${username}`);
}
},
@@ -146,21 +183,25 @@ const Media = {
const video = tile.querySelector("video");
const status = tile.querySelector(".remote-media-status");
video.srcObject = stream;
if (video) {
video.srcObject = stream;
}
const audioTracks = stream.getAudioTracks();
const videoTracks = stream.getVideoTracks();
status.textContent =
`${audioTracks.length > 0 ? "Audio" : "No audio"} / ` +
`${videoTracks.length > 0 ? "Video" : "No video"}`;
if (status) {
status.textContent =
`${audioTracks.length > 0 ? "Audio" : "No audio"} / ` +
`${videoTracks.length > 0 ? "Video" : "No video"}`;
}
},
ensureRemoteTile(username) {
const container = document.getElementById("remoteMediaContainer");
if (!container) return null;
let tile = document.getElementById(`remote-tile-${username}`);
if (tile) return tile;
tile = document.createElement("div");
@@ -204,14 +245,14 @@ const Media = {
if (cameraSelect) {
cameraSelect.addEventListener("change", async () => {
LogMessage("Camera changed");
await this.refreshDevicesAndPreview();
await this.restartLocalMedia();
});
}
if (micSelect) {
micSelect.addEventListener("change", async () => {
LogMessage("Microphone changed");
await this.refreshDevicesAndPreview();
await this.restartLocalMedia();
});
}
}