瀏覽代碼

fix(conference) Fix different bugs with startMuted policy. (#2777)

* fix(conference) Fix different bugs with startMuted policy.
If the user changes mute state after joining the call and before the other participats join the call, make sure those state changes are honored.

* feat(startMuted) Ignore startMuted in Jingle from focus.
Apply startMuted policy based on startMuted setting in room meta data.
Moderator settings and AV moderation settings will now be propagated to new endpoints joining the call through room meta data.
Advertise a new capability 'start-muted-room-metadata' to Jicofo for feature detection.
dev0
Jaya Allamsetty 6 月之前
父節點
當前提交
b9a9ac03c3

+ 31
- 60
JitsiConference.js 查看文件

187
     this.dtmfManager = null;
187
     this.dtmfManager = null;
188
     this.somebodySupportsDTMF = false;
188
     this.somebodySupportsDTMF = false;
189
     this.authEnabled = false;
189
     this.authEnabled = false;
190
-    this.startAudioMuted = false;
191
-    this.startVideoMuted = false;
192
     this.startMutedPolicy = {
190
     this.startMutedPolicy = {
193
         audio: false,
191
         audio: false,
194
         video: false
192
         video: false
1229
     this.eventEmitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track, actorParticipant);
1227
     this.eventEmitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track, actorParticipant);
1230
 };
1228
 };
1231
 
1229
 
1232
-/**
1233
- * Returns the list of local tracks that need to be added to the peerconnection on join.
1234
- * This takes the startAudioMuted/startVideoMuted flags into consideration since we do not
1235
- * want to add the tracks if the user joins the call audio/video muted. The tracks will be
1236
- * added when the user unmutes for the first time.
1237
- * @returns {Array<JitsiLocalTrack>} - list of local tracks that are unmuted.
1238
- */
1239
-JitsiConference.prototype._getInitialLocalTracks = function() {
1240
-    // Always add the audio track on certain platforms:
1241
-    //  * Safari / WebKit: because of a known issue where audio playout doesn't happen
1242
-    //    if the user joins audio and video muted.
1243
-    //  * React Native: after iOS 15, if a user joins muted they won't be able to unmute.
1244
-    return this.getLocalTracks()
1245
-        .filter(track => {
1246
-            const trackType = track.getType();
1247
-
1248
-            if (trackType === MediaType.AUDIO
1249
-                    && (!(this.isStartAudioMuted() || this.startMutedPolicy.audio)
1250
-                    || browser.isWebKitBased()
1251
-                    || browser.isReactNative())) {
1252
-                return true;
1253
-            } else if (trackType === MediaType.VIDEO && !this.isStartVideoMuted() && !this.startMutedPolicy.video) {
1254
-                return true;
1255
-            }
1256
-
1257
-            // Remove the track from the conference.
1258
-            this.onLocalTrackRemoved(track);
1259
-
1260
-            return false;
1261
-        });
1262
-};
1263
-
1264
 /**
1230
 /**
1265
  * Clear JitsiLocalTrack properties and listeners.
1231
  * Clear JitsiLocalTrack properties and listeners.
1266
  * @param track the JitsiLocalTrack object.
1232
  * @param track the JitsiLocalTrack object.
1825
     }
1791
     }
1826
 
1792
 
1827
     this._maybeSetSITimeout();
1793
     this._maybeSetSITimeout();
1794
+    const { startAudioMuted, startVideoMuted } = this.options.config;
1795
+
1796
+    // Ignore startAudio/startVideoMuted settings if the media session has already been established.
1797
+    // Apply the policy if the number of participants exceeds the startMuted thresholds.
1798
+    if ((this.jvbJingleSession && this.getActiveMediaSession() === this.jvbJingleSession)
1799
+        || ((typeof startAudioMuted === 'undefined' || startAudioMuted === -1)
1800
+            && (typeof startVideoMuted === 'undefined' || startVideoMuted === -1))) {
1801
+        return;
1802
+    }
1803
+
1804
+    let audioMuted = false;
1805
+    let videoMuted = false;
1806
+    const numberOfParticipants = this.getParticipantCount();
1807
+
1808
+    if (numberOfParticipants > this.options.config.startAudioMuted) {
1809
+        audioMuted = true;
1810
+    }
1811
+
1812
+    if (numberOfParticipants > this.options.config.startVideoMuted) {
1813
+        videoMuted = true;
1814
+    }
1815
+
1816
+    if ((audioMuted && !this.startMutedPolicy.audio) || (videoMuted && !this.startMutedPolicy.video)) {
1817
+        this._updateStartMutedPolicy(audioMuted, videoMuted);
1818
+    }
1828
 };
1819
 };
1829
 
1820
 
1830
 /* eslint-enable max-params */
1821
 /* eslint-enable max-params */
2264
     // Open a channel with the videobridge.
2255
     // Open a channel with the videobridge.
2265
     this._setBridgeChannel(jingleOffer, jingleSession.peerconnection);
2256
     this._setBridgeChannel(jingleOffer, jingleSession.peerconnection);
2266
 
2257
 
2267
-    const localTracks = this._getInitialLocalTracks();
2258
+    const localTracks = this.getLocalTracks();
2268
 
2259
 
2269
     try {
2260
     try {
2270
         jingleSession.acceptOffer(
2261
         jingleSession.acceptOffer(
2633
         return;
2624
         return;
2634
     }
2625
     }
2635
 
2626
 
2636
-    // Do not apply the startMutedPolicy locally on the moderator, the moderator should join with available local
2637
-    // sources and the policy needs to be applied only on users that join the call after.
2638
-    // this.startMutedPolicy = policy;
2639
-    // TODO: to remove using presence for startmuted policy after old clients update
2640
-    // we keep presence to update UI of old clients
2627
+    logger.info(`Setting start muted policy: ${JSON.stringify(policy)} in presence and in conference metadata`);
2628
+
2629
+    // TODO: to remove using presence for startmuted policy after old clients update to using metadata always.
2641
     this.room.addOrReplaceInPresence('startmuted', {
2630
     this.room.addOrReplaceInPresence('startmuted', {
2642
         attributes: {
2631
         attributes: {
2643
             audio: policy.audio,
2632
             audio: policy.audio,
2646
         }
2635
         }
2647
     }) && this.room.sendPresence();
2636
     }) && this.room.sendPresence();
2648
 
2637
 
2649
-    // we want to ignore applying startMutedPolicy locally when we set it
2650
-    this._ignoreFirstStartMutedPolicyUpdate = true;
2651
-
2652
     this.getMetadataHandler().setMetadata('startMuted', {
2638
     this.getMetadataHandler().setMetadata('startMuted', {
2653
         audio: policy.audio,
2639
         audio: policy.audio,
2654
         video: policy.video
2640
         video: policy.video
2662
  * @param {boolean} video if video should be muted.
2648
  * @param {boolean} video if video should be muted.
2663
  */
2649
  */
2664
 JitsiConference.prototype._updateStartMutedPolicy = function(audio, video) {
2650
 JitsiConference.prototype._updateStartMutedPolicy = function(audio, video) {
2665
-    if (this._ignoreFirstStartMutedPolicyUpdate) {
2666
-        this._ignoreFirstStartMutedPolicyUpdate = false;
2667
-
2651
+    // Update the start muted policy for the conference only if the meta data is received before conference join.
2652
+    if (this.isJoined()) {
2668
         return;
2653
         return;
2669
     }
2654
     }
2670
 
2655
 
2696
     return this.startMutedPolicy;
2681
     return this.startMutedPolicy;
2697
 };
2682
 };
2698
 
2683
 
2699
-/**
2700
- * Check if audio is muted on join.
2701
- */
2702
-JitsiConference.prototype.isStartAudioMuted = function() {
2703
-    return this.startAudioMuted;
2704
-};
2705
-
2706
-/**
2707
- * Check if video is muted on join.
2708
- */
2709
-JitsiConference.prototype.isStartVideoMuted = function() {
2710
-    return this.startVideoMuted;
2711
-};
2712
-
2713
 /**
2684
 /**
2714
  * Returns measured connectionTimes.
2685
  * Returns measured connectionTimes.
2715
  */
2686
  */

+ 6
- 37
JitsiConferenceEventManager.js 查看文件

413
     // Room metadata.
413
     // Room metadata.
414
     chatRoom.addListener(XMPPEvents.ROOM_METADATA_UPDATED, metadata => {
414
     chatRoom.addListener(XMPPEvents.ROOM_METADATA_UPDATED, metadata => {
415
         if (metadata.startMuted) {
415
         if (metadata.startMuted) {
416
-            conference._updateStartMutedPolicy(
417
-                metadata.startMuted.audio || false,
418
-                metadata.startMuted.video || false
419
-            );
416
+            const audio = metadata.startMuted.audio || false;
417
+            const video = metadata.startMuted.video || false;
418
+
419
+            audio && (conference.isMutedByFocus = true);
420
+            video && (conference.isVideoMutedByFocus = true);
421
+            conference._updateStartMutedPolicy(audio, video);
420
         }
422
         }
421
         conference.eventEmitter.emit(JitsiConferenceEvents.METADATA_UPDATED, metadata);
423
         conference.eventEmitter.emit(JitsiConferenceEvents.METADATA_UPDATED, metadata);
422
     });
424
     });
591
         XMPPEvents.CALL_ENDED,
593
         XMPPEvents.CALL_ENDED,
592
         conference.onCallEnded.bind(conference));
594
         conference.onCallEnded.bind(conference));
593
 
595
 
594
-    this._addConferenceXMPPListener(XMPPEvents.START_MUTED_FROM_FOCUS,
595
-        (audioMuted, videoMuted) => {
596
-            if (conference.options.config.ignoreStartMuted) {
597
-                return;
598
-            }
599
-
600
-            conference.startAudioMuted = audioMuted;
601
-            conference.startVideoMuted = videoMuted;
602
-
603
-            if (audioMuted) {
604
-                conference.isMutedByFocus = true;
605
-            }
606
-
607
-            if (videoMuted) {
608
-                conference.isVideoMutedByFocus = true;
609
-            }
610
-
611
-            // mute existing local tracks because this is initial mute from
612
-            // Jicofo
613
-            conference.getLocalTracks().forEach(track => {
614
-                switch (track.getType()) {
615
-                case MediaType.AUDIO:
616
-                    conference.startAudioMuted && track.mute();
617
-                    break;
618
-                case MediaType.VIDEO:
619
-                    conference.startVideoMuted && track.mute();
620
-                    break;
621
-                }
622
-            });
623
-
624
-            conference.eventEmitter.emit(JitsiConferenceEvents.STARTED_MUTED);
625
-        });
626
-
627
     this._addConferenceXMPPListener(XMPPEvents.AV_MODERATION_CHANGED,
596
     this._addConferenceXMPPListener(XMPPEvents.AV_MODERATION_CHANGED,
628
         (value, mediaType, actorJid) => {
597
         (value, mediaType, actorJid) => {
629
             const actorParticipant = conference.getParticipants().find(p => p.getJid() === actorJid);
598
             const actorParticipant = conference.getParticipants().find(p => p.getJid() === actorJid);

+ 0
- 3
JitsiConferenceEvents.spec.ts 查看文件

58
         VIDEO_SIP_GW_AVAILABILITY_CHANGED,
58
         VIDEO_SIP_GW_AVAILABILITY_CHANGED,
59
         VIDEO_SIP_GW_SESSION_STATE_CHANGED,
59
         VIDEO_SIP_GW_SESSION_STATE_CHANGED,
60
         START_MUTED_POLICY_CHANGED,
60
         START_MUTED_POLICY_CHANGED,
61
-        STARTED_MUTED,
62
         SUBJECT_CHANGED,
61
         SUBJECT_CHANGED,
63
         SUSPEND_DETECTED,
62
         SUSPEND_DETECTED,
64
         TALK_WHILE_MUTED,
63
         TALK_WHILE_MUTED,
146
         expect( VIDEO_SIP_GW_SESSION_STATE_CHANGED ).toBe( 'conference.videoSIPGWSessionStateChanged' );
145
         expect( VIDEO_SIP_GW_SESSION_STATE_CHANGED ).toBe( 'conference.videoSIPGWSessionStateChanged' );
147
         expect( VISITORS_SUPPORTED_CHANGED ).toBe( 'conference.visitorsSupported' );
146
         expect( VISITORS_SUPPORTED_CHANGED ).toBe( 'conference.visitorsSupported' );
148
         expect( START_MUTED_POLICY_CHANGED ).toBe( 'conference.start_muted_policy_changed' );
147
         expect( START_MUTED_POLICY_CHANGED ).toBe( 'conference.start_muted_policy_changed' );
149
-        expect( STARTED_MUTED ).toBe( 'conference.started_muted' );
150
         expect( SUBJECT_CHANGED ).toBe( 'conference.subjectChanged' );
148
         expect( SUBJECT_CHANGED ).toBe( 'conference.subjectChanged' );
151
         expect( SUSPEND_DETECTED ).toBe( 'conference.suspendDetected' );
149
         expect( SUSPEND_DETECTED ).toBe( 'conference.suspendDetected' );
152
         expect( TALK_WHILE_MUTED ).toBe( 'conference.talk_while_muted' );
150
         expect( TALK_WHILE_MUTED ).toBe( 'conference.talk_while_muted' );
227
         expect( JitsiConferenceEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED ).toBe( 'conference.videoSIPGWAvailabilityChanged' );
225
         expect( JitsiConferenceEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED ).toBe( 'conference.videoSIPGWAvailabilityChanged' );
228
         expect( JitsiConferenceEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED ).toBe( 'conference.videoSIPGWSessionStateChanged' );
226
         expect( JitsiConferenceEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED ).toBe( 'conference.videoSIPGWSessionStateChanged' );
229
         expect( JitsiConferenceEvents.START_MUTED_POLICY_CHANGED ).toBe( 'conference.start_muted_policy_changed' );
227
         expect( JitsiConferenceEvents.START_MUTED_POLICY_CHANGED ).toBe( 'conference.start_muted_policy_changed' );
230
-        expect( JitsiConferenceEvents.STARTED_MUTED ).toBe( 'conference.started_muted' );
231
         expect( JitsiConferenceEvents.SUBJECT_CHANGED ).toBe( 'conference.subjectChanged' );
228
         expect( JitsiConferenceEvents.SUBJECT_CHANGED ).toBe( 'conference.subjectChanged' );
232
         expect( JitsiConferenceEvents.SUSPEND_DETECTED ).toBe( 'conference.suspendDetected' );
229
         expect( JitsiConferenceEvents.SUSPEND_DETECTED ).toBe( 'conference.suspendDetected' );
233
         expect( JitsiConferenceEvents.TALK_WHILE_MUTED ).toBe( 'conference.talk_while_muted' );
230
         expect( JitsiConferenceEvents.TALK_WHILE_MUTED ).toBe( 'conference.talk_while_muted' );

+ 0
- 6
JitsiConferenceEvents.ts 查看文件

371
      */
371
      */
372
     SILENT_STATUS_CHANGED = 'conference.silentStatusChanged',
372
     SILENT_STATUS_CHANGED = 'conference.silentStatusChanged',
373
 
373
 
374
-    /**
375
-     * Indicates that the local user has started muted.
376
-     */
377
-    STARTED_MUTED = 'conference.started_muted',
378
-
379
     /**
374
     /**
380
      * Indicates that start muted settings changed.
375
      * Indicates that start muted settings changed.
381
      */
376
      */
582
 export const SERVER_REGION_CHANGED = JitsiConferenceEvents.SERVER_REGION_CHANGED;
577
 export const SERVER_REGION_CHANGED = JitsiConferenceEvents.SERVER_REGION_CHANGED;
583
 export const SILENT_STATUS_CHANGED = JitsiConferenceEvents.SILENT_STATUS_CHANGED;
578
 export const SILENT_STATUS_CHANGED = JitsiConferenceEvents.SILENT_STATUS_CHANGED;
584
 export const START_MUTED_POLICY_CHANGED = JitsiConferenceEvents.START_MUTED_POLICY_CHANGED;
579
 export const START_MUTED_POLICY_CHANGED = JitsiConferenceEvents.START_MUTED_POLICY_CHANGED;
585
-export const STARTED_MUTED = JitsiConferenceEvents.STARTED_MUTED;
586
 export const SUBJECT_CHANGED = JitsiConferenceEvents.SUBJECT_CHANGED;
580
 export const SUBJECT_CHANGED = JitsiConferenceEvents.SUBJECT_CHANGED;
587
 export const SUSPEND_DETECTED = JitsiConferenceEvents.SUSPEND_DETECTED;
581
 export const SUSPEND_DETECTED = JitsiConferenceEvents.SUSPEND_DETECTED;
588
 export const TALK_WHILE_MUTED = JitsiConferenceEvents.TALK_WHILE_MUTED;
582
 export const TALK_WHILE_MUTED = JitsiConferenceEvents.TALK_WHILE_MUTED;

+ 1
- 0
modules/xmpp/RoomMetadata.ts 查看文件

95
         }
95
         }
96
 
96
 
97
         this._metadata = metadata;
97
         this._metadata = metadata;
98
+        logger.debug('Received metadata update', metadata);
98
         this.room.eventEmitter.emit(XMPPEvents.ROOM_METADATA_UPDATED, metadata);
99
         this.room.eventEmitter.emit(XMPPEvents.ROOM_METADATA_UPDATED, metadata);
99
     }
100
     }
100
 
101
 

+ 0
- 11
modules/xmpp/strophe.jingle.js 查看文件

3
 import { cloneDeep } from 'lodash-es';
3
 import { cloneDeep } from 'lodash-es';
4
 import { $iq, Strophe } from 'strophe.js';
4
 import { $iq, Strophe } from 'strophe.js';
5
 
5
 
6
-import { MediaType } from '../../service/RTC/MediaType';
7
 import { XMPPEvents } from '../../service/xmpp/XMPPEvents';
6
 import { XMPPEvents } from '../../service/xmpp/XMPPEvents';
8
 import RandomUtil from '../util/RandomUtil';
7
 import RandomUtil from '../util/RandomUtil';
9
 
8
 
179
         switch (action) {
178
         switch (action) {
180
         case 'session-initiate': {
179
         case 'session-initiate': {
181
             logger.info('(TIME) received session-initiate:\t', now);
180
             logger.info('(TIME) received session-initiate:\t', now);
182
-            const startMuted = $(iq).find('jingle>startmuted');
183
 
181
 
184
             isP2P && logger.debug(`Received ${action} from ${fromJid}`);
182
             isP2P && logger.debug(`Received ${action} from ${fromJid}`);
185
-            if (startMuted?.length) {
186
-                const audioMuted = startMuted.attr(MediaType.AUDIO);
187
-                const videoMuted = startMuted.attr(MediaType.VIDEO);
188
-
189
-                this.eventEmitter.emit(
190
-                    XMPPEvents.START_MUTED_FROM_FOCUS,
191
-                    audioMuted === 'true',
192
-                    videoMuted === 'true');
193
-            }
194
             const pcConfig = isP2P ? this.p2pIceConfig : this.jvbIceConfig;
183
             const pcConfig = isP2P ? this.p2pIceConfig : this.jvbIceConfig;
195
 
184
 
196
             sess
185
             sess

+ 3
- 0
modules/xmpp/xmpp.js 查看文件

284
         // for keeping stats, since it is not made available to jocofo at
284
         // for keeping stats, since it is not made available to jocofo at
285
         // the time of the initial conference-request.
285
         // the time of the initial conference-request.
286
         this.caps.addFeature('http://jitsi.org/visitors-1');
286
         this.caps.addFeature('http://jitsi.org/visitors-1');
287
+
288
+        // Advertise support for startMuted policy through room metadata.
289
+        this.caps.addFeature('http://jitsi.org/start-muted-room-metadata');
287
     }
290
     }
288
 
291
 
289
     /**
292
     /**

+ 0
- 1
service/xmpp/XMPPEvents.spec.ts 查看文件

98
         expect( XMPPEvents.BREAKOUT_ROOMS_UPDATED ).toBe( 'xmpp.breakout-rooms.updated' );
98
         expect( XMPPEvents.BREAKOUT_ROOMS_UPDATED ).toBe( 'xmpp.breakout-rooms.updated' );
99
         expect( XMPPEvents.ROOM_METADATA_EVENT ).toBe( 'xmpp.room-metadata.event' );
99
         expect( XMPPEvents.ROOM_METADATA_EVENT ).toBe( 'xmpp.room-metadata.event' );
100
         expect( XMPPEvents.ROOM_METADATA_UPDATED ).toBe( 'xmpp.room-metadata.updated' );
100
         expect( XMPPEvents.ROOM_METADATA_UPDATED ).toBe( 'xmpp.room-metadata.updated' );
101
-        expect( XMPPEvents.START_MUTED_FROM_FOCUS ).toBe( 'xmpp.start_muted_from_focus' );
102
         expect( XMPPEvents.SUBJECT_CHANGED ).toBe( 'xmpp.subject_changed' );
101
         expect( XMPPEvents.SUBJECT_CHANGED ).toBe( 'xmpp.subject_changed' );
103
         expect( XMPPEvents.SUSPEND_DETECTED ).toBe( 'xmpp.suspend_detected' );
102
         expect( XMPPEvents.SUSPEND_DETECTED ).toBe( 'xmpp.suspend_detected' );
104
         expect( XMPPEvents.TRANSCRIPTION_STATUS_CHANGED ).toBe( 'xmpp.transcription_status_changed' );
103
         expect( XMPPEvents.TRANSCRIPTION_STATUS_CHANGED ).toBe( 'xmpp.transcription_status_changed' );

+ 0
- 4
service/xmpp/XMPPEvents.ts 查看文件

376
      */
376
      */
377
     SPEAKER_STATS_RECEIVED = 'xmpp.speaker_stats_received',
377
     SPEAKER_STATS_RECEIVED = 'xmpp.speaker_stats_received',
378
 
378
 
379
-    // Designates an event indicating that we should join the conference with
380
-    // audio and/or video muted.
381
-    START_MUTED_FROM_FOCUS = 'xmpp.start_muted_from_focus',
382
-
383
     // Designates an event indicating that the subject of the XMPP MUC has
379
     // Designates an event indicating that the subject of the XMPP MUC has
384
     // changed.
380
     // changed.
385
     SUBJECT_CHANGED = 'xmpp.subject_changed',
381
     SUBJECT_CHANGED = 'xmpp.subject_changed',

+ 0
- 2
types/hand-crafted/JitsiConference.d.ts 查看文件

105
   getConnectionState: () => string | null;
105
   getConnectionState: () => string | null;
106
   setStartMutedPolicy: ( policy: { audio: boolean, video: boolean } ) => void;
106
   setStartMutedPolicy: ( policy: { audio: boolean, video: boolean } ) => void;
107
   getStartMutedPolicy: () => { audio: boolean, video: boolean };
107
   getStartMutedPolicy: () => { audio: boolean, video: boolean };
108
-  isStartAudioMuted: () => boolean;
109
-  isStartVideoMuted: () => boolean;
110
   getConnectionTimes: () => unknown;
108
   getConnectionTimes: () => unknown;
111
   setLocalParticipantProperty: ( name: string, value: unknown ) => void;
109
   setLocalParticipantProperty: ( name: string, value: unknown ) => void;
112
   removeLocalParticipantProperty: ( name: string ) => void;
110
   removeLocalParticipantProperty: ( name: string ) => void;

+ 0
- 1
types/hand-crafted/JitsiConferenceEvents.d.ts 查看文件

41
   VIDEO_SIP_GW_AVAILABILITY_CHANGED = 'conference.videoSIPGWAvailabilityChanged',
41
   VIDEO_SIP_GW_AVAILABILITY_CHANGED = 'conference.videoSIPGWAvailabilityChanged',
42
   VIDEO_SIP_GW_SESSION_STATE_CHANGED = 'conference.videoSIPGWSessionStateChanged',
42
   VIDEO_SIP_GW_SESSION_STATE_CHANGED = 'conference.videoSIPGWSessionStateChanged',
43
   START_MUTED_POLICY_CHANGED = 'conference.start_muted_policy_changed',
43
   START_MUTED_POLICY_CHANGED = 'conference.start_muted_policy_changed',
44
-  STARTED_MUTED = 'conference.started_muted',
45
   SUBJECT_CHANGED = 'conference.subjectChanged',
44
   SUBJECT_CHANGED = 'conference.subjectChanged',
46
   SUSPEND_DETECTED = 'conference.suspendDetected',
45
   SUSPEND_DETECTED = 'conference.suspendDetected',
47
   TALK_WHILE_MUTED = 'conference.talk_while_muted',
46
   TALK_WHILE_MUTED = 'conference.talk_while_muted',

+ 0
- 1
types/hand-crafted/service/xmpp/XMPPEvents.d.ts 查看文件

70
   AV_MODERATION_RECEIVED = 'xmpp.av_moderation.received',
70
   AV_MODERATION_RECEIVED = 'xmpp.av_moderation.received',
71
   AV_MODERATION_CHANGED = 'xmpp.av_moderation.changed',
71
   AV_MODERATION_CHANGED = 'xmpp.av_moderation.changed',
72
   AV_MODERATION_PARTICIPANT_APPROVED = 'xmpp.av_moderation.participant.approved',
72
   AV_MODERATION_PARTICIPANT_APPROVED = 'xmpp.av_moderation.participant.approved',
73
-  START_MUTED_FROM_FOCUS = 'xmpp.start_muted_from_focus',
74
   SUBJECT_CHANGED = 'xmpp.subject_changed',
73
   SUBJECT_CHANGED = 'xmpp.subject_changed',
75
   SUSPEND_DETECTED = 'xmpp.suspend_detected',
74
   SUSPEND_DETECTED = 'xmpp.suspend_detected',
76
   TRANSCRIPTION_STATUS_CHANGED = 'xmpp.transcription_status_changed',
75
   TRANSCRIPTION_STATUS_CHANGED = 'xmpp.transcription_status_changed',

Loading…
取消
儲存