diff --git a/app/src/RtmpStreamer.js b/app/src/RtmpStreamer.js index 16756b90..681a964b 100644 --- a/app/src/RtmpStreamer.js +++ b/app/src/RtmpStreamer.js @@ -24,7 +24,6 @@ class RtmpStreamer { this.ffmpegStream = ffmpeg() .input(this.stream) .inputOptions('-re') - .inputFormat('webm') .videoCodec('libx264') .videoBitrate('3000k') .size('1280x720') diff --git a/app/src/Server.js b/app/src/Server.js index 18e08a1f..426d4b5c 100644 --- a/app/src/Server.js +++ b/app/src/Server.js @@ -44,7 +44,7 @@ dependencies: { * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.4.87 + * @version 1.4.88 * */ diff --git a/package.json b/package.json index d1713cd3..33067ae5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mirotalksfu", - "version": "1.4.87", + "version": "1.4.88", "description": "WebRTC SFU browser-based video calls", "main": "Server.js", "scripts": { diff --git a/public/js/Room.js b/public/js/Room.js index 514b200c..9f3bfc6f 100644 --- a/public/js/Room.js +++ b/public/js/Room.js @@ -11,7 +11,7 @@ if (location.href.substr(0, 5) !== 'https') location.href = 'https' + location.h * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.4.87 + * @version 1.4.88 * */ @@ -4092,7 +4092,7 @@ function showAbout() { imageUrl: image.about, customClass: { image: 'img-about' }, position: 'center', - title: 'WebRTC SFU v1.4.87', + title: 'WebRTC SFU v1.4.88', html: `
diff --git a/public/js/RoomClient.js b/public/js/RoomClient.js index 83ba1c00..de104f05 100644 --- a/public/js/RoomClient.js +++ b/public/js/RoomClient.js @@ -9,7 +9,7 @@ * @license For commercial or closed source, contact us at license.mirotalk@gmail.com or purchase directly via CodeCanyon * @license CodeCanyon: https://codecanyon.net/item/mirotalk-sfu-webrtc-realtime-video-conferences/40769970 * @author Miroslav Pejic - miroslav.pejic.85@gmail.com - * @version 1.4.87 + * @version 1.4.88 * */ diff --git a/public/js/RtmpStreamer.js b/public/js/RtmpStreamer.js index ba956a3f..048683ab 100644 --- a/public/js/RtmpStreamer.js +++ b/public/js/RtmpStreamer.js @@ -54,33 +54,6 @@ function showError(message) { showPopup(message, 'error'); } -function isChromeBased() { - const parser = new UAParser(); - const browser = parser.getBrowser(); - const browserName = browser.name.toLowerCase(); - - // List of known Chrome-based browser names - const chromeBasedBrowsers = ['chrome', 'chromium', 'opera', 'edge', 'brave', 'samsung internet']; - - return chromeBasedBrowsers.includes(browserName); -} - -function checkBrowserSupport() { - const userAgent = navigator.userAgent.toLowerCase(); - - console.log('UserAgent', userAgent); - - if (isChromeBased()) { - console.log('Browser is Chrome-based. Proceed with functionality.'); - } else { - toggleButtons(true); - alert( - 'This application requires a Chrome-based browser (Chrome, Edge Chromium, etc.). Please switch to a supported browser.', - ); - // window.open('about:blank', '_self').close(); - } -} - function checkRTMPEnabled() { axios .get('/rtmpEnabled') @@ -97,10 +70,7 @@ function checkRTMPEnabled() { }); } -window.onload = function () { - checkBrowserSupport(); - checkRTMPEnabled(); -}; +window.onload = checkRTMPEnabled; async function startCapture(constraints) { try { @@ -219,6 +189,13 @@ function stopStreaming() { stopButton.disabled = true; } +function getSupportedMimeTypes() { + const possibleTypes = ['video/webm;codecs=vp8,opus', 'video/mp4']; + return possibleTypes.filter((mimeType) => { + return MediaRecorder.isTypeSupported(mimeType); + }); +} + async function startStreaming(stream) { if (!stream) return; @@ -228,7 +205,9 @@ async function startStreaming(stream) { return; } - mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp8,opus' }); + const supportedMimeTypes = getSupportedMimeTypes(); + console.log('MediaRecorder supported options', supportedMimeTypes); + mediaRecorder = new MediaRecorder(stream, { mimeType: supportedMimeTypes[0] }); mediaRecorder.ondataavailable = async (event) => { if (event.data.size > 0) { diff --git a/public/views/RtmpStreamer.html b/public/views/RtmpStreamer.html index f507563e..7d31d78c 100644 --- a/public/views/RtmpStreamer.html +++ b/public/views/RtmpStreamer.html @@ -49,9 +49,6 @@ - - - diff --git a/rtmpServers/demo/client-server-axios/client/client.js b/rtmpServers/demo/client-server-axios/client/client.js index 0bc1df8c..51d95eb3 100644 --- a/rtmpServers/demo/client-server-axios/client/client.js +++ b/rtmpServers/demo/client-server-axios/client/client.js @@ -45,18 +45,6 @@ function showError(message) { showPopup(message, 'error'); } -function checkBrowserSupport() { - const userAgent = navigator.userAgent.toLowerCase(); - if (userAgent.includes('chrome') && !userAgent.includes('edge') && !userAgent.includes('opr')) { - console.log('Browser is Chrome-based. Proceed with functionality.'); - } else { - showError( - 'This application requires a Chrome-based browser (Chrome, Edge Chromium, etc.). Please switch to a supported browser.', - ); - toggleButtons(true); - } -} - function checkRTMPEnabled() { axios .get('/rtmpEnabled') @@ -73,15 +61,12 @@ function checkRTMPEnabled() { }); } -window.onload = function () { - checkBrowserSupport(); - checkRTMPEnabled(); -}; +window.onload = checkRTMPEnabled; async function startCapture(constraints) { try { const stream = await navigator.mediaDevices.getUserMedia(constraints); - videoElement.srcObject = stream; + attachMediaStream(stream); return stream; } catch (err) { console.error('Error accessing media devices.', err); @@ -92,7 +77,7 @@ async function startCapture(constraints) { async function startScreenCapture(constraints) { try { const stream = await navigator.mediaDevices.getDisplayMedia(constraints); - videoElement.srcObject = stream; + attachMediaStream(stream); return stream; } catch (err) { console.error('Error accessing screen media.', err); @@ -100,6 +85,15 @@ async function startScreenCapture(constraints) { } } +function attachMediaStream(stream) { + videoElement.srcObject = stream; + videoElement.playsInline = true; + videoElement.autoplay = true; + videoElement.muted = true; + videoElement.volume = 0; + videoElement.controls = false; +} + async function initRTMP(stream) { const apiSecret = apiSecretInput.value; try { @@ -190,6 +184,13 @@ function stopStreaming() { stopButton.disabled = true; } +function getSupportedMimeTypes() { + const possibleTypes = ['video/webm;codecs=vp8,opus', 'video/mp4']; + return possibleTypes.filter((mimeType) => { + return MediaRecorder.isTypeSupported(mimeType); + }); +} + async function startStreaming(stream) { if (!stream) return; @@ -199,7 +200,9 @@ async function startStreaming(stream) { return; } - mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp8,opus' }); + const supportedMimeTypes = getSupportedMimeTypes(); + console.log('MediaRecorder supported options', supportedMimeTypes); + mediaRecorder = new MediaRecorder(stream, { mimeType: supportedMimeTypes[0] }); mediaRecorder.ondataavailable = async (event) => { if (event.data.size > 0) { diff --git a/rtmpServers/demo/client-server-axios/server/RtmpStreamer.js b/rtmpServers/demo/client-server-axios/server/RtmpStreamer.js index bd8a46e4..cfefebb9 100644 --- a/rtmpServers/demo/client-server-axios/server/RtmpStreamer.js +++ b/rtmpServers/demo/client-server-axios/server/RtmpStreamer.js @@ -19,7 +19,6 @@ class RtmpStreamer { this.ffmpegStream = ffmpeg() .input(this.stream) .inputOptions('-re') - .inputFormat('webm') .videoCodec('libx264') .videoBitrate('3000k') .size('1280x720') diff --git a/rtmpServers/demo/client-server-socket/client/client.js b/rtmpServers/demo/client-server-socket/client/client.js index 50be7169..9c96aac2 100644 --- a/rtmpServers/demo/client-server-socket/client/client.js +++ b/rtmpServers/demo/client-server-socket/client/client.js @@ -46,24 +46,10 @@ function showError(message) { showPopup(message, 'error'); } -function checkBrowserSupport() { - const userAgent = navigator.userAgent.toLowerCase(); - if (userAgent.includes('chrome') && !userAgent.includes('edge') && !userAgent.includes('opr')) { - console.log('Browser is Chrome-based. Proceed with functionality.'); - } else { - showError( - 'This application requires a Chrome-based browser (Chrome, Edge Chromium, etc.). Please switch to a supported browser.', - ); - toggleButtons(true); - } -} - -window.onload = checkBrowserSupport; - async function startCapture(constraints) { try { const stream = await navigator.mediaDevices.getUserMedia(constraints); - videoElement.srcObject = stream; + attachMediaStream(stream); return stream; } catch (err) { console.error('Error accessing media devices.', err); @@ -74,7 +60,7 @@ async function startCapture(constraints) { async function startScreenCapture(constraints) { try { const stream = await navigator.mediaDevices.getDisplayMedia(constraints); - videoElement.srcObject = stream; + attachMediaStream(stream); return stream; } catch (err) { console.error('Error accessing screen media.', err); @@ -82,6 +68,15 @@ async function startScreenCapture(constraints) { } } +function attachMediaStream(stream) { + videoElement.srcObject = stream; + videoElement.playsInline = true; + videoElement.autoplay = true; + videoElement.muted = true; + videoElement.volume = 0; + videoElement.controls = false; +} + async function initRTMP() { const apiSecret = apiSecretInput.value; socket.emit('initRTMP', { apiSecret }); @@ -154,10 +149,19 @@ async function startStreaming(stream) { } } +function getSupportedMimeTypes() { + const possibleTypes = ['video/webm;codecs=vp8,opus', 'video/mp4']; + return possibleTypes.filter((mimeType) => { + return MediaRecorder.isTypeSupported(mimeType); + }); +} + async function startMediaRecorder(stream) { if (!stream) return; - mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp8,opus' }); + const supportedMimeTypes = getSupportedMimeTypes(); + console.log('MediaRecorder supported options', supportedMimeTypes); + mediaRecorder = new MediaRecorder(stream, { mimeType: supportedMimeTypes[0] }); mediaRecorder.ondataavailable = async (event) => { if (event.data.size > 0) { diff --git a/rtmpServers/demo/client-server-socket/server/RtmpStreamer.js b/rtmpServers/demo/client-server-socket/server/RtmpStreamer.js index 0c33916f..3d4aa4af 100644 --- a/rtmpServers/demo/client-server-socket/server/RtmpStreamer.js +++ b/rtmpServers/demo/client-server-socket/server/RtmpStreamer.js @@ -19,7 +19,6 @@ class RtmpStreamer { this.ffmpegStream = ffmpeg() .input(this.stream) .inputOptions('-re') - .inputFormat('webm') .videoCodec('libx264') .videoBitrate('3000k') .size('1280x720')