Fixed cases of no Media Content, and swapping Media failing.
This commit is contained in:
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user