Skip to content

Commit

Permalink
[mirotalkbro] - #10 improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
miroslavpejic85 committed Jan 20, 2025
1 parent 646ec37 commit ba8bc08
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 44 deletions.
2 changes: 1 addition & 1 deletion app/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* @license For open source under AGPL-3.0
* @license For private project or commercial purposes contact us at: [email protected]
* @author Miroslav Pejic - [email protected]
* @version 1.1.16
* @version 1.1.17
*/

require('dotenv').config();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mirotalkbro",
"version": "1.1.16",
"version": "1.1.17",
"description": "P2P WebRTC audio, video and screen live broadcast",
"main": "app/server.js",
"scripts": {
Expand Down
80 changes: 38 additions & 42 deletions public/js/broadcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -1023,52 +1023,48 @@ videoSelect.onchange = getStream;
getStream().then(getDevices).then(gotDevices);

function getStream() {
try {
videoOff.style.visibility = 'hidden';

videoQualitySelect.selectedIndex = localStorage.videoQualitySelectedIndex
? localStorage.videoQualitySelectedIndex
: 0;
videoFpsSelect.selectedIndex = localStorage.videoFpsSelectedIndex ? localStorage.videoFpsSelectedIndex : 0;
videoBtn.style.color = getMode === 'dark' ? 'white' : 'black';

const audioSource = audioSelect.value;
const videoSource = videoSelect.value;

const screenConstraints = { audio: true, video: true };
const cameraConstraints = {
audio: { deviceId: audioSource ? { exact: audioSource } : undefined },
video: { deviceId: videoSource ? { exact: videoSource } : undefined },
};
const constraints = screenShareEnabled ? screenConstraints : cameraConstraints;

if (screenShareEnabled) {
stopVideoTrack(broadcastStream);

video.classList.remove('mirror');
isVideoMirrored = false;
return navigator.mediaDevices
.getDisplayMedia(constraints)
.then(gotScreenStream)
.then(applyVideoConstraints)
.catch(handleError);
}
videoOff.style.visibility = 'hidden';

if (isDesktopDevice && !isVideoMirrored) {
video.className = 'mirror';
isVideoMirrored = true;
}
videoQualitySelect.selectedIndex = localStorage.videoQualitySelectedIndex
? localStorage.videoQualitySelectedIndex
: 0;
videoFpsSelect.selectedIndex = localStorage.videoFpsSelectedIndex ? localStorage.videoFpsSelectedIndex : 0;
videoBtn.style.color = getMode === 'dark' ? 'white' : 'black';

stopTracks(broadcastStream);
const audioSource = audioSelect.value;
const videoSource = videoSelect.value;

const screenConstraints = { audio: true, video: true };
const cameraConstraints = {
audio: { deviceId: audioSource ? { exact: audioSource } : undefined },
video: { deviceId: videoSource ? { exact: videoSource } : undefined },
};
const constraints = screenShareEnabled ? screenConstraints : cameraConstraints;

if (screenShareEnabled) {
stopVideoTrack(broadcastStream);

video.classList.remove('mirror');
isVideoMirrored = false;
return navigator.mediaDevices
.getUserMedia(constraints)
.then(gotStream)
.getDisplayMedia(constraints)
.then(gotScreenStream)
.then(applyVideoConstraints)
.catch(handleError);
} catch (error) {
handleError("Can't get stream, make sure you are in a secure TLS context (HTTPS) and try again");
.catch(handleMediaDeviceError);
}

if (isDesktopDevice && !isVideoMirrored) {
video.className = 'mirror';
isVideoMirrored = true;
}

stopTracks(broadcastStream);

return navigator.mediaDevices
.getUserMedia(constraints)
.then(gotStream)
.then(applyVideoConstraints)
.catch(handleMediaDeviceError);
}

function gotStream(stream) {
Expand Down Expand Up @@ -1107,12 +1103,12 @@ function attachStream(stream) {
video.controls = false;
}

function handleError(error) {
function handleMediaDeviceError(error) {
console.error('Error', error);
if (screenShareEnabled) {
toggleScreen();
} else {
popupMessage('warning', 'Ops', error);
handleMediaStreamError('Audio/Video', error);
}
}

Expand Down
48 changes: 48 additions & 0 deletions public/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,54 @@ function stopVideoTrack(mediaStream) {
}
}

function handleMediaStreamError(mediaStreamType, error) {
let errorMessage = error;
let shouldHandleGetUserMediaError = true;

switch (error.name) {
case 'NotFoundError':
case 'DevicesNotFoundError':
errorMessage = 'Required track is missing';
break;
case 'NotReadableError':
case 'TrackStartError':
errorMessage = 'Already in use';
break;
case 'OverconstrainedError':
case 'ConstraintNotSatisfiedError':
errorMessage = 'Constraints cannot be satisfied by available devices';
break;
case 'NotAllowedError':
case 'PermissionDeniedError':
errorMessage = 'Permission denied in browser';
break;
default:
errorMessage = "Can't get stream, make sure you are in a secure TLS context (HTTPS) and try again";
shouldHandleGetUserMediaError = false;
break;
}

let popupContent = `
<ul style="text-align: left">
<li>Media type: ${mediaStreamType}</li>
<li>Error name: ${error.name}</li>
<li>
<p>Error message:</p>
<p style="color: red">${errorMessage}</p>
</li>`;

if (shouldHandleGetUserMediaError) {
popupContent += `
<li>Common: <a href="https://blog.addpipe.com/common-getusermedia-errors" target="_blank">getUserMedia errors</a></li>`;
}

popupContent += `
</ul>
`;

popupMessage('warning', 'Access denied', popupContent, 'center');
}

function saveDataToFile(dataURL, fileName) {
const a = document.createElement('a');
a.style.display = 'none';
Expand Down
1 change: 1 addition & 0 deletions public/js/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ async function getStream() {
})
.catch((error) => {
console.error('Error accessing media devices', error.message);
handleMediaStreamError('Audio/Video', error);
hideVideoAudioButtons();
return null;
});
Expand Down

0 comments on commit ba8bc08

Please sign in to comment.