Skip to content

Commit 57504cb

Browse files
[mirotalk] - fix(audio): prevent audio dropout and echo on page clicks during call
1 parent be3c2a2 commit 57504cb

7 files changed

Lines changed: 25 additions & 19 deletions

File tree

.env.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# ====================================================
2-
# MiroTalk P2P v.1.8.56 - Environment Configuration
2+
# MiroTalk P2P v.1.8.57 - Environment Configuration
33
# ====================================================
44

55
# App environment

app/src/config.template.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/**
44
* ==============================================
5-
* MiroTalk P2P v.1.8.56 - Configuration File
5+
* MiroTalk P2P v.1.8.57 - Configuration File
66
* ==============================================
77
*
88
* This file is the central configuration source.

app/src/server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ dependencies: {
4545
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
4646
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
4747
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
48-
* @version 1.8.56
48+
* @version 1.8.57
4949
*
5050
*/
5151

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mirotalk",
3-
"version": "1.8.56",
3+
"version": "1.8.57",
44
"description": "A free WebRTC browser-based video call",
55
"main": "server.js",
66
"scripts": {
@@ -64,7 +64,7 @@
6464
"js-yaml": "^4.1.1",
6565
"jsdom": "^29.1.1",
6666
"jsonwebtoken": "^9.0.3",
67-
"nodemailer": "^8.0.9",
67+
"nodemailer": "^8.0.10",
6868
"openai": "^6.39.1",
6969
"qs": "^6.15.2",
7070
"socket.io": "^4.8.3",

public/js/brand.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ let brand = {
109109
},
110110
about: {
111111
imageUrl: '../images/mirotalk-logo.gif',
112-
title: 'WebRTC P2P v1.8.56',
112+
title: 'WebRTC P2P v1.8.57',
113113
html: `
114114
<button
115115
id="support-button"

public/js/client.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
1616
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
1717
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
18-
* @version 1.8.56
18+
* @version 1.8.57
1919
*
2020
*/
2121

@@ -5110,7 +5110,7 @@ async function loadRemoteMediaStream(stream, peers, peer_id, kind) {
51105110
// Change audio output if supported and audioOutputSelect is present
51115111
if (sinkId && audioOutputSelect && audioOutputSelect.value) {
51125112
try {
5113-
await changeAudioDestination(remoteAudioMedia);
5113+
await changeAudioDestination(remoteAudioMedia, false);
51145114
} catch (e) {
51155115
console.warn('[AUDIO] changeAudioDestination failed for ' + peer_name, e);
51165116
}
@@ -8272,19 +8272,19 @@ async function setLocalVideoQuality() {
82728272
/**
82738273
* Change audio output (Speaker)
82748274
*/
8275-
async function changeAudioDestination(audioElement = false) {
8275+
async function changeAudioDestination(audioElement = false, deferUntilUserActivation = true) {
82768276
const audioDestination = audioOutputSelect.value;
82778277
if (audioElement) {
82788278
// change audio output to specified participant audio
8279-
await attachSinkId(audioElement, audioDestination);
8279+
await attachSinkId(audioElement, audioDestination, deferUntilUserActivation);
82808280
} else {
82818281
const audioElements = audioMediaContainer.querySelectorAll('audio');
82828282
// change audio output for all participants audio
82838283
const promises = [];
82848284
audioElements.forEach((audioElement) => {
82858285
// discard my own audio on this device, so I won't hear myself.
82868286
if (audioElement.id != 'myAudio') {
8287-
promises.push(attachSinkId(audioElement, audioDestination));
8287+
promises.push(attachSinkId(audioElement, audioDestination, deferUntilUserActivation));
82888288
}
82898289
});
82908290
// Wait for all audio outputs to be changed
@@ -8296,8 +8296,9 @@ async function changeAudioDestination(audioElement = false) {
82968296
* Attach audio output device to audio element using device/sink ID.
82978297
* @param {object} element audio element to attach the audio output
82988298
* @param {string} sinkId uuid audio output device
8299+
* @param {boolean} deferUntilUserActivation when true, defer applying setSinkId() until the next user gesture if no user activation is present
82998300
*/
8300-
async function attachSinkId(element, sinkId) {
8301+
async function attachSinkId(element, sinkId, deferUntilUserActivation = true) {
83018302
if (typeof element.sinkId === 'undefined') {
83028303
console.warn('Browser does not support output device selection.');
83038304
return;
@@ -8333,6 +8334,11 @@ async function attachSinkId(element, sinkId) {
83338334
// If a user gesture is required (Chrome policy), defer until the next interaction
83348335
const needsUserGesture = !!(navigator.userActivation && !navigator.userActivation.isActive);
83358336
if (needsUserGesture) {
8337+
// Automatic calls (e.g. on new audio consumer) must NOT register a global
8338+
// user-activation listener: applying setSinkId() on an unrelated click resets
8339+
// the audio pipeline and breaks echo cancellation. The selected speaker is
8340+
// re-applied the next time the user explicitly interacts with the speaker select.
8341+
if (!deferUntilUserActivation) return;
83368342
// Show a single notification prompting the user to click
83378343
if (!window.__sinkGestureNotified) {
83388344
window.__sinkGestureNotified = true;
@@ -15956,7 +15962,7 @@ function showAbout() {
1595615962
Swal.fire({
1595715963
background: swBg,
1595815964
position: 'center',
15959-
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.8.56',
15965+
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.8.57',
1596015966
imageUrl: brand.about?.imageUrl && brand.about.imageUrl.trim() !== '' ? brand.about.imageUrl : images.about,
1596115967
customClass: { image: 'img-about' },
1596215968
html: renderRoomTemplate('tpl-about-modal', {

0 commit comments

Comments
 (0)