[mirotalk] - refactoring get audio constraints, update dep

This commit is contained in:
Miroslav Pejic
2026-02-11 03:31:38 +01:00
parent 778fbd94e0
commit 2ce00b10b6
7 changed files with 49 additions and 29 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# ====================================================
# MiroTalk P2P v.1.7.25 - Environment Configuration
# MiroTalk P2P v.1.7.26 - Environment Configuration
# ====================================================
# App environment
+1 -1
View File
@@ -2,7 +2,7 @@
/**
* ==============================================
* MiroTalk P2P v.1.7.25 - Configuration File
* MiroTalk P2P v.1.7.26 - Configuration File
* ==============================================
*
* Branding and customizations require a license:
+1 -1
View File
@@ -45,7 +45,7 @@ dependencies: {
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.7.25
* @version 1.7.26
*
*/
+6 -6
View File
@@ -1,12 +1,12 @@
{
"name": "mirotalk",
"version": "1.7.25",
"version": "1.7.26",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mirotalk",
"version": "1.7.25",
"version": "1.7.26",
"license": "AGPL-3.0",
"dependencies": {
"@mattermost/client": "11.3.0",
@@ -30,7 +30,7 @@
"jsdom": "^28.0.0",
"jsonwebtoken": "^9.0.3",
"nodemailer": "^8.0.1",
"openai": "^6.18.0",
"openai": "^6.21.0",
"qs": "^6.14.1",
"socket.io": "^4.8.3",
"swagger-ui-express": "^5.0.1",
@@ -5074,9 +5074,9 @@
}
},
"node_modules/openai": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-6.18.0.tgz",
"integrity": "sha512-odLRYyz9rlzz6g8gKn61RM2oP5UUm428sE2zOxZqS9MzVfD5/XW8UoEjpnRkzTuScXP7ZbP/m7fC+bl8jCOZZw==",
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/openai/-/openai-6.21.0.tgz",
"integrity": "sha512-26dQFi76dB8IiN/WKGQOV+yKKTTlRCxQjoi2WLt0kMcH8pvxVyvfdBDkld5GTl7W1qvBpwVOtFcsqktj3fBRpA==",
"license": "Apache-2.0",
"bin": {
"openai": "bin/cli"
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "mirotalk",
"version": "1.7.25",
"version": "1.7.26",
"description": "A free WebRTC browser-based video call",
"main": "server.js",
"scripts": {
@@ -62,7 +62,7 @@
"jsdom": "^28.0.0",
"jsonwebtoken": "^9.0.3",
"nodemailer": "^8.0.1",
"openai": "^6.18.0",
"openai": "^6.21.0",
"qs": "^6.14.1",
"socket.io": "^4.8.3",
"swagger-ui-express": "^5.0.1",
+1 -1
View File
@@ -79,7 +79,7 @@ let brand = {
},
about: {
imageUrl: '../images/mirotalk-logo.gif',
title: 'WebRTC P2P v1.7.25',
title: 'WebRTC P2P v1.7.26',
html: `
<button
id="support-button"
+37 -17
View File
@@ -15,7 +15,7 @@
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
* @version 1.7.25
* @version 1.7.26
*
*/
@@ -127,6 +127,7 @@ const parser = new UAParser(userAgent);
const parserResult = parser.getResult();
const deviceType = parserResult.device.type || 'desktop';
const isMobileDevice = deviceType === 'mobile';
const isMobileSafari = isMobileDevice && parserResult.browser.name.toLowerCase().includes('safari');
const isTabletDevice = deviceType === 'tablet';
const isIPadDevice = parserResult.device.model?.toLowerCase() === 'ipad';
const isDesktopDevice = deviceType === 'desktop';
@@ -7301,13 +7302,21 @@ function getAudioConstraints(deviceId = null) {
echoCancellation: true, // Prevents echo/feedback
autoGainControl: true, // Automatically adjusts microphone volume
noiseSuppression: false, // Use RNNoise instead
sampleRate: 48000, // High-quality audio sample rate
channelCount: 2, // Stereo for better audio quality
};
// Add device ID if specified
/*
deviceId handling is platform-dependent:
- iOS Safari: routing is OS-controlled; ignore deviceId.
- Mobile (Android): best-effort with `ideal`.
- Desktop: `exact` is reliable.
*/
if (deviceId) {
audioConstraints.deviceId = { exact: deviceId };
if (isMobileSafari) {
// ignore
} else if (isMobileDevice) {
audioConstraints.deviceId = { ideal: deviceId };
} else {
audioConstraints.deviceId = { exact: deviceId };
}
}
return {
@@ -13659,7 +13668,7 @@ function showAbout() {
Swal.fire({
background: swBg,
position: 'center',
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.7.25',
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.7.26',
imageUrl: brand.about?.imageUrl && brand.about.imageUrl.trim() !== '' ? brand.about.imageUrl : images.about,
customClass: { image: 'img-about' },
html: `
@@ -14560,20 +14569,31 @@ function setupQuickDeviceSwitchDropdowns() {
observer.observe(audioBtn, { attributes: true, attributeFilter: ['class', 'style'] });
// Re-enumerate & refresh lists on hardware changes
if (navigator.mediaDevices && typeof navigator.mediaDevices.addEventListener === 'function') {
if (navigator.mediaDevices) {
let deviceChangeFrame;
navigator.mediaDevices.addEventListener('devicechange', () => {
let lastChangeTime = 0;
navigator.mediaDevices.addEventListener('devicechange', async () => {
const now = Date.now();
// Debounce: ignore rapid-fire changes
if (now - lastChangeTime < 1000) return;
lastChangeTime = now;
if (deviceChangeFrame) cancelAnimationFrame(deviceChangeFrame);
deviceChangeFrame = requestAnimationFrame(async () => {
if (typeof refreshMyAudioVideoDevices === 'function') {
try {
await refreshMyAudioVideoDevices();
} catch (err) {
console.error('Error in devicechange handler:', err);
}
console.log('🔄 Audio devices changed - refreshing...');
// Give OS time to finish routing (especially important on mobile)
await new Promise((resolve) => setTimeout(resolve, isMobileDevice ? 1500 : 500));
try {
await refreshMyAudioVideoDevices();
} catch (err) {
console.warn('Device refresh failed:', err);
}
rebuildVideoMenu();
rebuildAudioMenu();
setTimeout(() => {
rebuildVideoMenu();
rebuildAudioMenu();
}, 50);
});
});
}