-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Firefox throws "MSID is already used" error when using _acceptJvbIncomingCall #2631
Comments
What version of lib-jitsi-meet are you using? |
@saghul I am using version 1878, but I have also tested on the latest master branch, and the issue is the same. |
Ping @jallamsetty1 |
Additionally, downgrading to version 1877 resolves the issue. |
Hi @jallamsetty1, could you to review this issue? |
Hi, can you pls provide me more details? Can you please share STR for this? Also does this happen on meet.jit.si? Are you able to share the full browser console log from the FIrefox client? |
Hi @jallamsetty1, here is some the issue details: STR: Attached video. This is a custom feature in my app, so I’m not sure if meet.jit.si has this feature. Additional information, downgrading to version 1877 resolves the issue. Error object: {
"reason": "bad-request",
"msg": "MSID is already used: 7b5f54f5-video-0-2 cfbeb70c-c8c7-4342-832f-b660bf739f1d-2.",
"session": "JingleSessionPC[session=JVB,initiator=false,sid=73h98e7t6ipb2]"
} Error full stack:
issue-msid.mp4 |
Are you using the latest stable on your deployment? |
Hi @jallamsetty1, yep I am using latest master branch |
Can you provide a code snippet of how you are using the library? |
Hi @saghul, This is the Connection class: constructor(conferene?: string, password?: string, onToggleGoToNext?: (isOpen: boolean) => void) {
this.conference = conferene;
this.password = password;
this.connectFailed = false;
this.onToggleGoToNext = onToggleGoToNext;
this._onConnectionSuccess = this._onConnectionSuccess.bind(this);
this._onConnectionFailed = this._onConnectionFailed.bind(this);
this._connectionDisconnect = this._connectionDisconnect.bind(this);
this._onConferenceJoined = this._onConferenceJoined.bind(this);
this._onUserLeft = this._onUserLeft.bind(this);
this._onConferenceFailed = this._onConferenceFailed.bind(this);
this._getConnectionOptions = this._getConnectionOptions.bind(this);
this.connection = new JitsiMeetJS.JitsiConnection(null, null, this._getConnectionOptions());
this._addConnctionListeners();
this.rtcId = new Set();
}
_getConnectionOptions() {
return {
hosts: {
domain: 'meet.jitsi',
muc: 'muc.meet.jitsi'
},
websocket: `wss://${SERVER_PROXY_TARGET}/xmpp-websocket`,
serviceUrl: `wss://${SERVER_PROXY_TARGET}/xmpp-websocket?room=${this.conference}`,
disableRtx: true,
disableAudioLevels: true
};
}
/**
* Connect.
*/
_connectionConnect() {
this.connection.connect(); // <- the error here
}
/**
* This function is called when we disconnect.
*/
_connectionDisconnect() {
this.connection.removeEventListener(
JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,
this._onConnectionSuccess);
this.connection.removeEventListener(
JitsiMeetJS.events.connection.CONNECTION_FAILED,
this._onConnectionFailed);
this.connection.removeEventListener(
JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED,
this._connectionDisconnect);
} This is UserConnection class that extends Connection: export class UserConnection extends Connection {
/**
* @class
*/
constructor(...args: ConstructorParameters<typeof Connection>) {
super(...args);
this._createLocalTrack = this._createLocalTrack.bind(this);
this._onLocalTracks = this._onLocalTracks.bind(this);
this.replaceTrack = this.replaceTrack.bind(this);
this.connect = this.connect.bind(this);
this.disconnect = this.disconnect.bind(this);
}
/**
* Camera and micro open is require.
* Need create localtrack and add it to room. This action will let JVB create media channel to allocate.
*/
_createLocalTrack(onError: Function) {
JitsiMeetJS.init({ disableAudioLevels: false });
return JitsiMeetJS.createLocalTracks({ devices: [ 'audio', 'video' ] })
.then((tracks: Track[]) => {
tracks.forEach(track => track.type === 'audio' && (track.track.enabled = false));
this._onLocalTracks(tracks);
})
.catch((error: Error) => {
onError();
throw error;
});
}
/*
* Doc
*
* @param {any[]} tracks tracks
*/
_onLocalTracks(tracks: Track[]) {
this.localTracks = tracks;
for (let i = 0; i < this.localTracks.length; i++) {
// prevent leak camera/audio
// In some case, issue blank video will appear by this.
// this.localTracks[i].track.enabled = false;
this.localTracks[i].addEventListener(
JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
(audioLevel: number) => console.log(`Audio Level local: ${audioLevel}`));
this.localTracks[i].addEventListener(
JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
() => console.log('local track muted'));
this.localTracks[i].addEventListener(
JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
() => console.log('local track stoped'));
this.localTracks[i].addEventListener(
JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
(deviceId: string) =>
console.log(
`track audio output device was changed to ${deviceId}`));
if (this.isJoined && !this.rtcId?.has(this.localTracks[i].rtcId)) {
this.rtcId?.add(this.localTracks[i].rtcId);
this.room.addTrack(this.localTracks[i]);
}
}
}
/**
* Replace track
* There are some cases when replaceTrack does not sync with UI, so we need to manually handle UI for that.
*/
replaceTrack(stream: Record<string, any>) {
return new Promise(resolve => {
const replaceTrackPromises: any[] = [];
stream.getTracks().forEach(
(track: Track) => {
const oldLocalTrack = this.localTracks.filter(tr => tr.type === track.kind)[0];
if (oldLocalTrack) {
const newLocalTrack = Object.create(oldLocalTrack);
oldLocalTrack.track.stop(); // stop camera/audio track
Object.assign(newLocalTrack, oldLocalTrack);
newLocalTrack.deviceId = track.id;
newLocalTrack.facingMode = false;
newLocalTrack.mediaType = track.kind;
newLocalTrack.rtcId = oldLocalTrack.rtc;
newLocalTrack.stream = stream;
newLocalTrack.track = track;
newLocalTrack.type = oldLocalTrack.type;
replaceTrackPromises.push(
this.room.replaceTrack(oldLocalTrack, newLocalTrack).then(() => newLocalTrack)
.catch((error: any) => {
logger.error(error);
})
);
}
}
);
Promise.all(replaceTrackPromises).then(resolve);
});
}
spawnConnection(replaceTrack: Function) {
const anonymousConnection = new AnonymousConnection(this.conference, this.password);
anonymousConnection.doReplaceTrack = replaceTrack;
this.dependConnections.push(anonymousConnection);
}
/**
* Establish connection.
*/
connect() {
this._connectionConnect();
}
disconnect() {
this.dependConnections.forEach(conn => conn.unload());
this.unload();
}
} This is the code call the JVB test: _startTestJVB(loadedMedia?: boolean) {
const alterLoadedMedia = loadedMedia || this.loadedMedia;
if (!alterLoadedMedia) {
this.isErrorLoadSource = true;
return this._onErrorTest(JVB_ERROR_TYPE.SOURCE_ERROR);
}
if (
this.userConnection
&& !this.createdTrack
&& !this.isErrorLoadSource
) {
this.createdTrack = true;
// After 10s, if reconnect not successfully then stop reconnect.
const timeoutConnect = setTimeout(() => {
if (
this.stateMachine.state.currentState
!== STATE_MACHINE.SUCCESS
) {
this._onErrorTest(JVB_ERROR_TYPE.LOW_NETWORK);
}
}, JVB_CONNECTION_TIMEOUT);
this.timeoutList.push(timeoutConnect);
this.userConnection
._createLocalTrack(this.onGetErrorPrecontition)
.then(() => {
this.stateMachine.transition(STATE_MACHINE.RUNNING);
this.userConnection?.connect();
this.userConnection?.spawnConnection(this.handleSendVideo);
})
.catch(() => {
this._onErrorTest(JVB_ERROR_TYPE.JVB);
});
}
} |
Why are you disabling rtx?
You only want to call
Why are you adding a listener for audio levels, when you disabled them?
Any chance |
Description
When using Unified Plan in Firefox, WebRTC throws the following error: MSID is already used.
The issue occurs when calling the function
_acceptJvbIncomingCall
. This does not happen in Chrome. A possible workaround is applyingtoPlanB()
.Possible Cause
Firefox may require a different
msid
structure for Unified Plan.This is the image of the error:

This is what I tried to fix to make it work:

The text was updated successfully, but these errors were encountered: