GithubHelp home page GithubHelp logo

jitsi / lib-jitsi-meet Goto Github PK

View Code? Open in Web Editor NEW
1.3K 57.0 1.1K 15.88 MB

A low-level JS video API that allows adding a completely custom video experience to web apps.

License: Apache License 2.0

JavaScript 87.31% TypeScript 12.69%

lib-jitsi-meet's Introduction

Jitsi Meet API library

You can use Jitsi Meet API to create Jitsi Meet video conferences with a custom GUI.

Installation

Building the sources

NOTE: you need Node.js >= 12 and npm >= 7

To build the library, just type:

npm install
npm run build

To lint:

npm run lint

and to run unit tests:

npm test

if you need to rebuild lib-jitsi-meet.min.js

npm run build

Both linting and units will also be done by a pre-commit hook.

lib-jitsi-meet's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lib-jitsi-meet's Issues

RTCBrowserType.supportsSimulcast() is too limited

Current code:

    /**
     * Whether jitsi-meet supports simulcast on the current browser.
     * @returns {boolean}
     */
    supportsSimulcast() {
        // This mirrors what sdp-simulcast uses (which is used when deciding
        // whether to actually enable simulcast or not).
        // TODO: the logic should be in one single place.
        return window.chrome !== undefined;
    }

Just to summarize: Microsoft Edge does have window.chrome and, for sure, we don't want simulcast on it.

unable to see start/stop live stream option in my jitsi

Hello

I have installed the jitsi-meet from the below link on ubuntu 14.04
https://github.com/jitsi/jitsi-meet/blob/master/doc/quick-install.md

i am able to install successfully on my server Ip 54.214.113.198 and its working but i can not see the
option that is " start/stop live stream"

Please may i know how can i fix this problem and let me know the steps or command to resolve that easily..

I would appreciated the help.

Thank you

Thank you

Audio is not working in Windows-10 OS

Hi Team,

I am facing audio issues while integrating jitsi in my project, Audio is not working in windows 10 OS, tested in chrome and firefox browsers and also Not showing any errors in console but its working in mac os x and windows-7 with chrome browser.

Can any one please suggest what could be the issue?

PresenceMap with Colibri extensions as a child of x (query) stanza breaks Openfire

In ChatRoom.prototype.sendPresence, JSON2packet is used to add colibri extensions as children of x (query) stanza. This breaks openfire as the MUC Manager consumes this stanza for room management and does not pass it on to participants.

An alternative approach which would work in both Prosody and Openfire would be to use a colibri stanza as a sibling node to the x (query) node.

[request] Way to query videobridge about lastN

Is there any way to ask videobridge about lastN endpoints array? There is issue when new user connects to muc, he tries to render all videostreams in conference, but tracks can be frozen.
How it works now: Videobridge tries to send datachannel message, but fails with message no datachannel opened for user, and when datachannel will open, bridge does not tries to send this message again. It will be great to query videobridge about lastN after datachannel is opened.

Don't set description.sdp

In various places within the RTC module, the sdp attribute of a RTCSessionDescription is mangled:

In TraceablePeerConnection.js:

localDescription.sdp = transformer.toRawSDP();

As per spec, the sdp attribute is read-only and eventually things may just fail. It's better to create a new description from scratch. In fact, the spec no longer requires passing a real RTCSessionDescription instance, but just a RTCSessionDescriptionInit which basically is a common Object with two keys: type and sdp.

Video Previews Not Appearing in Example

I recently discovered lib-jitsi-meet, and I'm really excited to see a javascript library to help work with jitsi-videobridge/jitsi-meet. Anyway, I have a working installation of jitsi-meet working, and I tried today to get the example working.

As far as I can, the signalling is happening and streams are getting created, and I can see that the video/audio elements are getting created in the DOM, but I don't see video previews for the local or remote streams. I'm not really sure what is going on. I updated to the most recent versions of the video bridge and jicofo to make sure that wasn't the issue.

Anyway, I realize the library is under development right now, but I was hoping maybe someone could point me in the right direction. I've attached the chrome console output if that helps.

chrome_console.txt

Thanks!

VideoBridge ignores `channelLastN` option

Tested with current lib-jitsi-meet and videobridge from jitsi-meet-unstable (1810) version.
When some user joined to conference, some of videos of other participants stay black. It may be happened when this videos not in lastN, i think. Problem solves itself when users, which video is not displaying, will mute then unmute their videos.
I set config option channelLastN: -1, but i still receive last_n_changed event. It looks like adaptiveLastN works, but it disabled in config.

[Edge] Local IP:port not shown

When in Edge, the local IP:port is not shown when clicking on "Show more" in the self-view video. It shows "Address: N/A".

However, I can confirm that proper data is being given via the StatisticsEvents.CONNECTION_STATS event. In fact, in RTCStatsCollector.js, when this is called:

this.eventEmitter.emit(
        StatisticsEvents.CONNECTION_STATS,
        this.peerconnection,
        {
            'bandwidth': this.conferenceStats.bandwidth,
            'bitrate': this.conferenceStats.bitrate,
            'packetLoss': this.conferenceStats.packetLoss,
            'resolution': resolutions,
            'framerate': framerates,
            'transport': this.conferenceStats.transport
        });

This is the content of such a object:

{  
  "bandwidth":{  

  },
  "bitrate":{  
    "upload":0,
    "download":0,
    "audio":{  
      "upload":0,
      "download":0
    },
    "video":{  
      "upload":0,
      "download":0
    }
  },
  "packetLoss":{  
    "total":0,
    "download":0,
    "upload":0
  },
  "resolution":{  

  },
  "framerate":{  

  },
  "transport":[  
    {  
      "ip":"52.90.94.230:10000",
      "type":"udp",
      "localip":"2.136.213.170:57934",
      "p2p":false
    }
  ]
}

However, such a IP is not shown in the UI. I've checked the rest of the code and also the corresponding React component in the jitsi-meet code and I don't find anything that would prevent the IP:port from being displayed (even if some other connection data, such as framerate and resolution is not given (due #523)).

Failing to install lib-jitsi-meet on fresh ubuntu machine

I am facing issue while building jitsi-meet. The required lib-jitsi-meet is not getting installed from 'npm install'. Following is the error I am facing.

[email protected] postinstall /home/skarambelkar/src/jitsi-meet/node_modules/lib-jitsi-meet
webpack -p

/home/skarambelkar/src/jitsi-meet/node_modules/lib-jitsi-meet/webpack.config.js:11
new webpack.LoaderOptionsPlugin({
^

TypeError: webpack.LoaderOptionsPlugin is not a constructor
at Object. (/home/skarambelkar/src/jitsi-meet/node_modules/lib-jitsi-meet/webpack.config.js:11:5)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at module.exports (/home/skarambelkar/src/jitsi-meet/node_modules/webpack/bin/convert-argv.js:80:13)
at Object. (/home/skarambelkar/src/jitsi-meet/node_modules/webpack/bin/webpack.js:39:40)
npm WARN [email protected] requires a peer of webpack@2 but none was installed.
npm WARN [email protected] requires a peer of eslint@^2.0.0 but none was installed.
npm ERR! Linux 4.4.0-83-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v6.11.0
npm ERR! npm v3.10.10
npm ERR! code ELIFECYCLE

npm ERR! [email protected] postinstall: webpack -p
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] postinstall script 'webpack -p'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the lib-jitsi-meet package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! webpack -p
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs lib-jitsi-meet
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls lib-jitsi-meet
npm ERR! There is likely additional logging output above.

This looks like some issue with lib-jitsi-meet package in npm repository. Looks like it is not compliant with required webpack api. Can someone please check the repository contents and fix this problem?

Appreciate any response on this.

Thank you,
Sandeep Karambelkar

How to know local user id

How do I know local users' id when he/she joined the conference? I read the available docs don't seem to provide such functionality. Am I missing something?

Multiple Video Tracks

Currently, lib-jitsi-meet only allows an endpoint to add one video track to a conference. I am wondering if it is at all planned to eventually support adding multiple video tracks? Is there a suggested work around? The most obvious use case would be having a webcam plus screenshare. I will note that, in my particular application, I would like to be able to support an arbitrary number of video tracks. My understanding is that the videobridge supports endpoints sending multiple video tracks to an extent, but that lib-jitsi-meet does not.

I implemented a semi-functioning version of this in a clone of lib-jitsi-meet about a year ago, but things seem to have changed quite a bit since then. I am not sure, but it seems like the more difficult parts of the problem are managing multiple simulcast streams and bitrate adaptivity. I assume there are probably other complications. I guess I am just wondering if this is something on the team's radar?

Making a room password protected

XEP-0045 defines two room_config fields that relate to the password protection of a room:

<field
     var='muc#roomconfig_passwordprotectedroom'
     type='boolean'
     label='Whether a Password is Required to Enter'/>
<field
     var='muc#roomconfig_roomsecret'
     type='text-single'
     label='The Room Password'/>

Prosody appears to work with only the latter, while Openfire requires you to set both, and will not make the room password protected when setting only the roomsecret field.

Arguably, setting the room password implies that a user wants the the room to be password protected (which is raised as an Openfire issue here, but the specification is somewhat confusing at this point (as discussed here)

At some point, the original author of the code wondered about this behavior, given the 'fixme' comment left at https://github.com/jitsi/lib-jitsi-meet/blob/master/modules/xmpp/ChatRoom.js#L857

To be safe, the client should always set both values - that will always have the desired effect, no matter what interpretation is implemented server-sided.

Cannot read property 'disableAudioLevels' of undefined

Hi, i followed the Getting Started in the doc.

I added jitsi api
<script type="text/javascript" src="https://meet.jit.si/libs/lib-jitsi-meet.min.js"></script>

And i wrote the code as docs says
JitsiMeetJS.init(); var options = {}; options.disableAudioLevels = false; var connection = new JitsiMeetJS.JitsiConnection(null, null, options);

When i refresh my page
my console.log is

[modules/RTC/RTCBrowserType.js] <Array.r>: This appears to be Chrome, ver: 56
lib-jitsi-meet.min.js:1 Uncaught TypeError: Cannot read property 'disableAudioLevels' of undefined
at Function.s.init (lib-jitsi-meet.min.js:1)
at Object.init (lib-jitsi-meet.min.js:1)
at (index):11
Can you tell me where is my mistake ? Or is that a bug in the api ?

Thanks.

Safari: TraceablePeerConnection error

There is an error fires, when trying to connect with safari (with temasys plugin).

_createOfferOrAnswer 
TypeError: this.peerconnection.createAnswer.bind is not a function. (In 'this.peerconnection.createAnswer.bind(this.peerconnection)', 'this.peerconnection.createAnswer.bind' is undefined)

TraceablePeerconnection.js assumes simulcast

In TraceablePeerConnection.prototype.setRemoteDescription method:

TraceablePeerConnection.prototype.setRemoteDescription
= function(description, successCallback, failureCallback) {
    this.trace('setRemoteDescription::preTransform', dumpSDP(description));

    // TODO the focus should squeze or explode the remote simulcast
    // eslint-disable-next-line no-param-reassign
    description = this.simulcast.mungeRemoteDescription(description);

This is assuming simulcast without even checking RTCBrowserType.supportsSimulcast().

Stats are hidden after a second

In the new UI, when doing mouse "hover" to show the stats of a peer, the layer is hidden after ~1 second. It seems to me that it's hidden when calling again to pc.getStats().

Uncaught SyntaxError: Unexpected token import

I try to use use lib-jitsi-meet from the source code like this
<script src="lib-jitsi-meet/JitsiMeetJS.js"></script>
I already do the npm install from my lib-jitsi-meet folder, but when I load the page, I always get the Uncaught SyntaxError: Unexpected token import. Npm install always successful btw. Can you help me?

Here's my index.html, I just use from the example:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="libs/jquery-2.1.1.min.js"></script>
    <script src="libs/strophe/strophe.js"></script>
    <script src="libs/strophe/strophe.disco.min.js?v=1"></script>
    <script src="lib-jitsi-meet/JitsiMeetJS.js"></script>
    <script src="example.js" ></script>
</head>
<body>
    <a href="#" onclick="unload()">Unload</a>
    <a href="#" onclick="switchVideo()">switchVideo</a>
    <div id="audioOutputSelectWrapper" style="display: none;">
        Change audio output device
        <select id="audioOutputSelect" onchange="changeAudioOutput(this)"></select>
    </div>
    <!-- <video id="localVideo" autoplay="true"></video> -->
    <!--<audio id="localAudio" autoplay="true" muted="true"></audio>-->
</body>
</html>

And here's my javascript example.js, again, I just use the example:

/* global $, JitsiMeetJS */

const options = {
    hosts: {
        domain: 'jitsi-meet.localhost',
        muc: 'conference.jitsi-meet.localhost' // FIXME: use XEP-0030
    },
    bosh: '//jitsi-meet.localhost/http-bind', // FIXME: use xep-0156 for that

    // The name of client node advertised in XEP-0115 'c' stanza
    clientNode: 'http://jitsi.org/jitsimeet'
};

const confOptions = {
    openSctp: true
};

let connection = null;
let isJoined = false;
let room = null;

let localTracks = [];
const remoteTracks = {};

/**
 * Handles local tracks.
 * @param tracks Array with JitsiTrack objects
 */
function onLocalTracks(tracks) {
    localTracks = tracks;
    for (let i = 0; i < localTracks.length; i++) {
        localTracks[i].addEventListener(
            JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
            audioLevel => console.log(`Audio Level local: ${audioLevel}`));
        localTracks[i].addEventListener(
            JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
            () => console.log('local track muted'));
        localTracks[i].addEventListener(
            JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
            () => console.log('local track stoped'));
        localTracks[i].addEventListener(
            JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
            deviceId =>
                console.log(
                    `track audio output device was changed to ${deviceId}`));
        if (localTracks[i].getType() === 'video') {
            $('body').append(`<video autoplay='1' id='localVideo${i}' />`);
            localTracks[i].attach($(`#localVideo${i}`)[0]);
        } else {
            $('body').append(
                `<audio autoplay='1' muted='true' id='localAudio${i}' />`);
            localTracks[i].attach($(`#localAudio${i}`)[0]);
        }
        if (isJoined) {
            room.addTrack(localTracks[i]);
        }
    }
}

/**
 * Handles remote tracks
 * @param track JitsiTrack object
 */
function onRemoteTrack(track) {
    if (track.isLocal()) {
        return;
    }
    const participant = track.getParticipantId();

    if (!remoteTracks[participant]) {
        remoteTracks[participant] = [];
    }
    const idx = remoteTracks[participant].push(track);

    track.addEventListener(
        JitsiMeetJS.events.track.TRACK_AUDIO_LEVEL_CHANGED,
        audioLevel => console.log(`Audio Level remote: ${audioLevel}`));
    track.addEventListener(
        JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
        () => console.log('remote track muted'));
    track.addEventListener(
        JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
        () => console.log('remote track stoped'));
    track.addEventListener(JitsiMeetJS.events.track.TRACK_AUDIO_OUTPUT_CHANGED,
        deviceId =>
            console.log(
                `track audio output device was changed to ${deviceId}`));
    const id = participant + track.getType() + idx;

    if (track.getType() === 'video') {
        $('body').append(
            `<video autoplay='1' id='${participant}video${idx}' />`);
    } else {
        $('body').append(
            `<audio autoplay='1' id='${participant}audio${idx}' />`);
    }
    track.attach($(`#${id}`)[0]);
}

/**
 * That function is executed when the conference is joined
 */
function onConferenceJoined() {
    console.log('conference joined!');
    isJoined = true;
    for (let i = 0; i < localTracks.length; i++) {
        room.addTrack(localTracks[i]);
    }
}

/**
 *
 * @param id
 */
function onUserLeft(id) {
    console.log('user left');
    if (!remoteTracks[id]) {
        return;
    }
    const tracks = remoteTracks[id];

    for (let i = 0; i < tracks.length; i++) {
        tracks[i].detach($(`#${id}${tracks[i].getType()}`));
    }
}

/**
 * That function is called when connection is established successfully
 */
function onConnectionSuccess() {
    room = connection.initJitsiConference('conference', confOptions);
    room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
    room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, track => {
        console.log(`track removed!!!${track}`);
    });
    room.on(
        JitsiMeetJS.events.conference.CONFERENCE_JOINED,
        onConferenceJoined);
    room.on(JitsiMeetJS.events.conference.USER_JOINED, id => {
        console.log('user join');
        remoteTracks[id] = [];
    });
    room.on(JitsiMeetJS.events.conference.USER_LEFT, onUserLeft);
    room.on(JitsiMeetJS.events.conference.TRACK_MUTE_CHANGED, track => {
        console.log(`${track.getType()} - ${track.isMuted()}`);
    });
    room.on(
        JitsiMeetJS.events.conference.DISPLAY_NAME_CHANGED,
        (userID, displayName) => console.log(`${userID} - ${displayName}`));
    room.on(JitsiMeetJS.events.conference.TRACK_AUDIO_LEVEL_CHANGED,
      (userID, audioLevel) => {
          console.log(`${userID} - ${audioLevel}`);
      });
    room.on(JitsiMeetJS.events.conference.RECORDER_STATE_CHANGED, () => {
        console.log(`${room.isRecordingSupported()} - ${
             room.getRecordingState()} - ${
             room.getRecordingURL()}`);
    });
    room.on(JitsiMeetJS.events.conference.PHONE_NUMBER_CHANGED, () => {
        console.log(
            `${room.getPhoneNumber()} - ${
             room.getPhonePin()}`);
    });
    room.join();
}

/**
 * This function is called when the connection fail.
 */
function onConnectionFailed() {
    console.error('Connection Failed!');
}

/**
 * This function is called when the connection fail.
 */
function onDeviceListChanged(devices) {
    console.info('current devices', devices);
}

/**
 * This function is called when we disconnect.
 */
function disconnect() {
    console.log('disconnect!');
    connection.removeEventListener(
        JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,
        onConnectionSuccess);
    connection.removeEventListener(
        JitsiMeetJS.events.connection.CONNECTION_FAILED,
        onConnectionFailed);
    connection.removeEventListener(
        JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED,
        disconnect);
}

/**
 *
 */
function unload() {
    for (let i = 0; i < localTracks.length; i++) {
        localTracks[i].stop();
    }
    console.log(room);
    if (room !== null) {
        room.leave();
        connection.disconnect();
    }
}

let isVideo = true;

/**
 *
 */
function switchVideo() { // eslint-disable-line no-unused-vars
    isVideo = !isVideo;
    if (localTracks[1]) {
        localTracks[1].dispose();
        localTracks.pop();
    }
    JitsiMeetJS.createLocalTracks(
            { devices: isVideo ? [ 'video' ] : [ 'desktop' ] })
        .then(tracks => {
            localTracks.push(tracks[0]);
            localTracks[1].addEventListener(
                JitsiMeetJS.events.track.TRACK_MUTE_CHANGED,
                () => console.log('local track muted'));
            localTracks[1].addEventListener(
                JitsiMeetJS.events.track.LOCAL_TRACK_STOPPED,
                () => console.log('local track stoped'));
            localTracks[1].attach($('#localVideo1')[0]);
            room.addTrack(localTracks[1]);
        })
        .catch(error => console.log(error));
}

/**
 *
 * @param selected
 */
function changeAudioOutput(selected) { // eslint-disable-line no-unused-vars
    JitsiMeetJS.mediaDevices.setAudioOutputDevice(selected.value);
}

$(window).bind('beforeunload', unload);
$(window).bind('unload', unload);

// JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);
const initOptions = {
    disableAudioLevels: true,

    // The ID of the jidesha extension for Chrome.
    desktopSharingChromeExtId: 'mbocklcggfhnbahlnepmldehdhpjfcjp',

    // Whether desktop sharing should be disabled on Chrome.
    desktopSharingChromeDisabled: false,

    // The media sources to use when using screen sharing with the Chrome
    // extension.
    desktopSharingChromeSources: [ 'screen', 'window' ],

    // Required version of Chrome extension
    desktopSharingChromeMinExtVersion: '0.1',

    // The ID of the jidesha extension for Firefox. If null, we assume that no
    // extension is required.
    desktopSharingFirefoxExtId: null,

    // Whether desktop sharing should be disabled on Firefox.
    desktopSharingFirefoxDisabled: true,

    // The maximum version of Firefox which requires a jidesha extension.
    // Example: if set to 41, we will require the extension for Firefox versions
    // up to and including 41. On Firefox 42 and higher, we will run without the
    // extension.
    // If set to -1, an extension will be required for all versions of Firefox.
    desktopSharingFirefoxMaxVersionExtRequired: -1,

    // The URL to the Firefox extension for desktop sharing.
    desktopSharingFirefoxExtensionURL: null
};

JitsiMeetJS.init(initOptions)
    .then(() => {
        connection = new JitsiMeetJS.JitsiConnection(null, null, options);

        connection.addEventListener(
            JitsiMeetJS.events.connection.CONNECTION_ESTABLISHED,
            onConnectionSuccess);
        connection.addEventListener(
            JitsiMeetJS.events.connection.CONNECTION_FAILED,
            onConnectionFailed);
        connection.addEventListener(
            JitsiMeetJS.events.connection.CONNECTION_DISCONNECTED,
            disconnect);

        JitsiMeetJS.mediaDevices.addEventListener(
            JitsiMeetJS.events.mediaDevices.DEVICE_LIST_CHANGED,
            onDeviceListChanged);

        connection.connect();
        JitsiMeetJS.createLocalTracks({ devices: [ 'audio', 'video' ] })
            .then(onLocalTracks)
            .catch(error => {
                throw error;
            });
    })
    .catch(error => console.log(error));

if (JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('output')) {
    JitsiMeetJS.mediaDevices.enumerateDevices(devices => {
        const audioOutputDevices
            = devices.filter(d => d.kind === 'audiooutput');

        if (audioOutputDevices.length > 1) {
            $('#audioOutputSelect').html(
                audioOutputDevices
                    .map(
                        d =>
                            `<option value="${d.deviceId}">${d.label}</option>`)
                    .join('\n'));

            $('#audioOutputSelectWrapper').show();
        }
    });
}

Please help, thank you very much...

Disposed conference are not unsubscribed from the event emitter causing errors

Hello team,

I am attempting to leave a conference, and join another conference. I have been receiving a null reference error when another user attempts to join my new conference.

The error occurs on JitsiConference.js

JitsiConference.prototype.onIncomingCall = function (jingleSession, jingleOffer, now) { if (!this.room.isFocus(jingleSession.peerjid)) {....

The this.room is null, as this is the old conference that has been left and is still kicking around in the event emitters.

I can attempt to fix this myself by adding an analogous function called removeListeners to match the setupListeners and then run that in the JitsiConference leave method.

If this sounds right, give me the go ahead and I will gladly reach out and do so. For now I will add try and handle this problem externally. Not sure if I am missing something here or doing something improperly.

Thanks!

Calder

Cannot switch between authenticated conferences (Settings.js bugs)

Hi,

When using authenticated conferences, jicofo checks if "machineID" == "machineID in session".
"sessionid" is stored in localStorage, "jitsiMeetId" (machineID) is stored in localStorage but per conference, so you get a new one per conference,and you cannot switch conference because you hit https://github.com/jitsi/jicofo/blob/86fdbf031cab144f672c472e609cd56c0aded1e6/src/main/java/org/jitsi/jicofo/auth/AbstractAuthAuthority.java#L464

sessionid and jitsiMeetId need to be together (preferably global and not per conference)

Also Settings.js exists in both lib-jitsi-meet and jitsi-meet, maybe we should rename or delete one of them.

[Edge] Need to signal end of remote candidates

The problem

Microsoft Edge does not implement Trickle-ICE, which means that remote candidates cannot be added at any time. And worse, the ORTC RTCIceTransport implementation in Edge won't start ICE procedures until an empty candidate { } is given.

So, when the SDP offer from jitsi-videobridge is received, the WebRTC shim (see the exact flow here) extracts the candidates from the remote SDP offer, signals them to the RTCIceTransport via addRemoteCandidate(candidate) and, after that, it also signals an empty candidate via addRemoteCandidate({}) (otherwise ICE procedures won't start).

And even worse: after such an empty candidate, addRemoteCandidate() cannot be called again with candidates receives later (they would be ignored).

This is not an issue when talking to the server since all the candidates already exists in the SDP. But when it comes to do P2P, remote candidates arrives at any time.

The current code works in server mode, but won't work in P2P because it assumes that all the candidates are in the SDP and won't accept candidates given later.

At the same time, the WebRTC peerconnection.addIceCandidate() method does not allow passing null or an empty object as argument, so here another problem.

Proposal

So, a solution coming to my mind is that the library (maybe JingleSessionPC.js) calls peerconnection.addIceCandidate({ }) (with an empty object) just in Edge, so the ORTC WebRTC shim will internally call iceTransport.addRemoteCandidate({ })), and must do that once it knows that all the remote candidates have been given, this is:

  • If this is a peerconnection with the jitsi-videobridge server, then the library knows that no more remote candidates will be given after calling setRemoteDescription(), so call addIceCandidate({ }) after it.
  • If this is a P2P peerconnection, then somehow signal end of candidates to the remote peer and, on receipt of it, call addIceCandidate({ }).

Again, just call addIceCandidate({ }) if the browser is Edge.

Is something like this possible?

[Edge] pc.getStats(): no way to get usable and needed stats

getStats() has been added to the Edge's RTCPeerConnection shim. Basically it's achieved by collecting all the stats from the all RTCIceTransport , RTCRtpSender and RTCRtpReceiver instances internally handled by the RTCPeerConnection object.

Below the results of pc.getStats() in Edge after 1 minute (more or less) in a call with a Chrome browser (which was running in a computer with a hardcoded 25% of up/down packet lost):

{  
  "20291937208485":{  
    "id":"20291937208485",
    "type":"transport",
    "timestamp":1498649044000,
    "bytesSent":0,
    "bytesReceived":0,
    "rtcpTransportStatsId":"",
    "activeConnection":true,
    "selectedCandidatePairId":"",
    "localCertificateId":"",
    "remoteCertificateId":""
  },
  "20291937208487":{  
    "id":"20291937208487",
    "timestamp":1498649044000,
    "localAddress":"2.136.213.170:56004",
    "localSite":"192.168.1.41:56004",
    "remoteAddress":"52.90.94.230:10000",
    "remoteSite":"52.90.94.230:4443",
    "iceWarningFlags":{  
      "turnTcpTimedOut":false,
      "turnUdpAllocateFailed":false,
      "turnUdpSendFailed":false,
      "turnTcpAllocateFailed":false,
      "turnTcpSendFailed":false,
      "udpLocalConnectivityFailed":false,
      "udpNatConnectivityFailed":false,
      "udpRelayConnectivityFailed":false,
      "tcpNatConnectivityFailed":false,
      "tcpRelayConnectivityFailed":false,
      "connCheckMessageIntegrityFailed":false,
      "allocationMessageIntegrityFailed":false,
      "connCheckOtherError":false,
      "turnAuthUnknownUsernameError":false,
      "noRelayServersConfigured":true,
      "multipleRelayServersAttempted":false,
      "portRangeExhausted":false,
      "alternateServerReceived":false,
      "pseudoTLSFailure":false,
      "turnTurnTcpConnectivityFailed":false,
      "useCandidateChecksFailed":false,
      "fipsAllocationFailure":false
    },
    "portRangeMin":50001,
    "portRangeMax":65535,
    "localMRTCPPort":0,
    "remoteMRTCPPort":0,
    "stunVer":2,
    "numConsentReqSent":20,
    "numConsentReqReceived":33,
    "numConsentRespSent":33,
    "numConsentRespReceived":20,
    "interfaces":{  
      "interfaceTypeEthernet":false,
      "interfaceTypeWireless":true,
      "interfaceTypePPP":false,
      "interfaceTypeTunnel":true,
      "interfaceTypeWWAN":false
    },
    "protocol":"udp",
    "localInterface":{  
      "interfaceTypeEthernet":false,
      "interfaceTypeWireless":true,
      "interfaceTypePPP":false,
      "interfaceTypeTunnel":false,
      "interfaceTypeWWAN":false
    },
    "localAddrType":"peer-derived",
    "remoteAddrType":"stun",
    "iceRole":"controlled",
    "rtpRtcpMux":true,
    "allocationTimeInMs":23,
    "msRtcEngineVersion":"6.0.8974.294",
    "msType":"transportdiagnostics"
  },
  "20291937196004":{  
    "id":"20291937196004",
    "type":"track",
    "timestamp":1498649044000,
    "trackIdentifier":"EB29FBAC-0E26-4E32-B3BE-2C04E849043C",
    "remoteSource":false,
    "ssrcIds":[  
      "701605465"
    ],
    "frameWidth":0,
    "frameHeight":0,
    "framesPerSecond":0,
    "framesSent":0,
    "framesReceived":0,
    "framesDecoded":0,
    "framesDropped":0,
    "framesCorrupted":0,
    "audioLevel":-31,
    "echoReturnLoss":0,
    "echoReturnLossEnhancement":0
  },
  "20291937196001":{  
    "id":"20291937196001",
    "type":"inboundrtp",
    "timestamp":1498649044000,
    "ssrc":"0",
    "isRemote":true,
    "codecId":"",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20291937196002",
    "mediaTrackId":"20291937196004",
    "transportId":"20291937208485",
    "packetsReceived":0,
    "bytesReceived":0,
    "packetsLost":0,
    "jitter":0,
    "fractionLost":0
  },
  "20291937196002":{  
    "id":"20291937196002",
    "type":"outboundrtp",
    "timestamp":1498649044000,
    "ssrc":"701605465",
    "isRemote":false,
    "codecId":"opus",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20291937196001",
    "mediaTrackId":"20291937196004",
    "transportId":"20291937208485",
    "packetsSent":0,
    "bytesSent":0,
    "targetBitrate":0,
    "roundTripTime":0
  },
  "20291937252164":{  
    "id":"20291937252164",
    "type":"track",
    "timestamp":1498649044000,
    "trackIdentifier":"8F275253-8565-4BD7-BA3E-49DF1AE05E4D",
    "remoteSource":false,
    "ssrcIds":[  
      "2256665303"
    ],
    "frameWidth":0,
    "frameHeight":0,
    "framesPerSecond":0,
    "framesSent":0,
    "framesReceived":0,
    "framesDecoded":0,
    "framesDropped":0,
    "framesCorrupted":0,
    "audioLevel":0,
    "echoReturnLoss":0,
    "echoReturnLossEnhancement":0
  },
  "20291937252161":{  
    "id":"20291937252161",
    "type":"inboundrtp",
    "timestamp":1498649044000,
    "ssrc":"0",
    "isRemote":true,
    "codecId":"",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20291937252162",
    "mediaTrackId":"20291937252164",
    "transportId":"20291937208485",
    "packetsReceived":0,
    "bytesReceived":0,
    "packetsLost":0,
    "jitter":0,
    "fractionLost":0
  },
  "20291937252162":{  
    "id":"20291937252162",
    "type":"outboundrtp",
    "timestamp":1498649044000,
    "ssrc":"2256665303",
    "isRemote":false,
    "codecId":"VP8",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20291937252161",
    "mediaTrackId":"20291937252164",
    "transportId":"20291937208485",
    "packetsSent":1556,
    "bytesSent":0,
    "targetBitrate":0,
    "roundTripTime":0
  },
  "20287305816964":{  
    "id":"20287305816964",
    "type":"track",
    "timestamp":1498649044000,
    "trackIdentifier":"FC920022-04C7-4E11-9BAC-BAC3C9CD1968",
    "remoteSource":true,
    "ssrcIds":[  
      "1709210239"
    ],
    "frameWidth":0,
    "frameHeight":0,
    "framesPerSecond":0,
    "framesSent":0,
    "framesReceived":0,
    "framesDecoded":0,
    "framesDropped":0,
    "framesCorrupted":0,
    "audioLevel":0,
    "echoReturnLoss":0,
    "echoReturnLossEnhancement":0
  },
  "20287305816961":{  
    "id":"20287305816961",
    "type":"inboundrtp",
    "timestamp":1498649044000,
    "ssrc":"1709210239",
    "isRemote":false,
    "codecId":"",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20287305816962",
    "mediaTrackId":"20287305816964",
    "transportId":"20291937208485",
    "packetsReceived":0,
    "bytesReceived":0,
    "packetsLost":0,
    "jitter":0,
    "fractionLost":0
  },
  "20287305816962":{  
    "id":"20287305816962",
    "type":"outboundrtp",
    "timestamp":1498649044000,
    "ssrc":"0",
    "isRemote":true,
    "codecId":"",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20287305816961",
    "mediaTrackId":"20287305816964",
    "transportId":"20291937208485",
    "packetsSent":0,
    "bytesSent":0,
    "targetBitrate":0,
    "roundTripTime":0
  },
  "20292021592324":{  
    "id":"20292021592324",
    "type":"track",
    "timestamp":1498649044000,
    "trackIdentifier":"CF10D197-BCB7-4BB1-8E9D-988183074310",
    "remoteSource":true,
    "ssrcIds":[  
      "2409668377"
    ],
    "frameWidth":0,
    "frameHeight":0,
    "framesPerSecond":0,
    "framesSent":0,
    "framesReceived":0,
    "framesDecoded":0,
    "framesDropped":0,
    "framesCorrupted":0,
    "audioLevel":-32,
    "echoReturnLoss":0,
    "echoReturnLossEnhancement":0
  },
  "20292021592321":{  
    "id":"20292021592321",
    "type":"inboundrtp",
    "timestamp":1498649044000,
    "ssrc":"2409668377",
    "isRemote":false,
    "codecId":"opus",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20292021592322",
    "mediaTrackId":"20292021592324",
    "transportId":"20291937208485",
    "packetsReceived":4466,
    "bytesReceived":0,
    "packetsLost":0,
    "jitter":0.006,
    "fractionLost":0.10599517822265625
  },
  "20292021592322":{  
    "id":"20292021592322",
    "type":"outboundrtp",
    "timestamp":1498649044000,
    "ssrc":"0",
    "isRemote":true,
    "codecId":"",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20292021592321",
    "mediaTrackId":"20292021592324",
    "transportId":"20291937208485",
    "packetsSent":0,
    "bytesSent":0,
    "targetBitrate":0,
    "roundTripTime":0
  },
  "20292021601924":{  
    "id":"20292021601924",
    "type":"track",
    "timestamp":1498649044000,
    "trackIdentifier":"46AB3E5E-13D0-4C88-8E50-E3DDF72660B4",
    "remoteSource":true,
    "ssrcIds":[  
      "799301531"
    ],
    "frameWidth":640,
    "frameHeight":360,
    "framesPerSecond":18.35708236694336,
    "framesSent":0,
    "framesReceived":0,
    "framesDecoded":0,
    "framesDropped":0,
    "framesCorrupted":0,
    "audioLevel":0,
    "echoReturnLoss":0,
    "echoReturnLossEnhancement":0
  },
  "20292021601921":{  
    "id":"20292021601921",
    "type":"inboundrtp",
    "timestamp":1498649044000,
    "ssrc":"799301531",
    "isRemote":false,
    "codecId":"VP8",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20292021601922",
    "mediaTrackId":"20292021601924",
    "transportId":"20291937208485",
    "packetsReceived":5832,
    "bytesReceived":0,
    "packetsLost":0,
    "jitter":0.002,
    "fractionLost":0.030874136835336685
  },
  "20292021601922":{  
    "id":"20292021601922",
    "type":"outboundrtp",
    "timestamp":1498649044000,
    "ssrc":"0",
    "isRemote":true,
    "codecId":"",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20292021601921",
    "mediaTrackId":"20292021601924",
    "transportId":"20291937208485",
    "packetsSent":0,
    "bytesSent":0,
    "targetBitrate":0,
    "roundTripTime":0
  },
  "20287247411844":{  
    "id":"20287247411844",
    "type":"track",
    "timestamp":1498649044000,
    "trackIdentifier":"980E7C4B-F7F3-4517-9347-EF97786DDD89",
    "remoteSource":true,
    "ssrcIds":[  
      "4265767963"
    ],
    "frameWidth":0,
    "frameHeight":0,
    "framesPerSecond":0,
    "framesSent":0,
    "framesReceived":0,
    "framesDecoded":0,
    "framesDropped":0,
    "framesCorrupted":0,
    "audioLevel":0,
    "echoReturnLoss":0,
    "echoReturnLossEnhancement":0
  },
  "20287247411841":{  
    "id":"20287247411841",
    "type":"inboundrtp",
    "timestamp":1498649044000,
    "ssrc":"4265767963",
    "isRemote":false,
    "codecId":"",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20287247411842",
    "mediaTrackId":"20287247411844",
    "transportId":"20291937208485",
    "packetsReceived":0,
    "bytesReceived":0,
    "packetsLost":0,
    "jitter":0,
    "fractionLost":0
  },
  "20287247411842":{  
    "id":"20287247411842",
    "type":"outboundrtp",
    "timestamp":1498649044000,
    "ssrc":"0",
    "isRemote":true,
    "codecId":"",
    "firCount":0,
    "pliCount":0,
    "nackCount":0,
    "sliCount":0,
    "associateStatsId":"20287247411841",
    "mediaTrackId":"20287247411844",
    "transportId":"20291937208485",
    "packetsSent":0,
    "bytesSent":0,
    "targetBitrate":0,
    "roundTripTime":0
  }
}

install errors

I have problems with installation "lib-jitsi-meet".
package.json :
"dependencies": {
"lib-jitsi-meet": "jitsi/lib-jitsi-meet"
},

I found what is going wrong. "lib-jitsi-meet" use dependency: "socket.io-client": "1.3.6" .
And it crashed process of the installation.
If you try to install only socket.io-client with version 1.3.6 (npm install [email protected])
you will get errors , because version 1.3.6 very bad.
If developers of the library "lib-jitsi-meet" change version of the dependency to "socket.io-client": "1.*" you will not get errors.
Next problem with "string-replace" module. I also get errors related with it:

ERROR in Entry module not found: Error: Cannot resolve module 'string-replace' in /Users/mac-182/workspace/t/node_modules/lib-jitsi-meet

I use "windows 10 + git bash" or "Mac os x EL Capitan version 10.11.3" for develop.

Duplicated/overridden code in TraceablePeerConnection.js

    this.onaddstream = null;
    this.peerconnection.onaddstream = event => {
        this.trace('onaddstream', event.stream.id);
        if (this.onaddstream !== null) {
            this.onaddstream(event);
        }
    };
    this.onremovestream = null;
    this.peerconnection.onremovestream = event => {
        this.trace('onremovestream', event.stream.id);
        if (this.onremovestream !== null) {
            this.onremovestream(event);
        }
    };
    this.peerconnection.onaddstream
        = event => this._remoteStreamAdded(event.stream);
    this.peerconnection.onremovestream
        = event => this._remoteStreamRemoved(event.stream);

Basically this.peerconnection.onaddstream and this.peerconnection.onremovestream above are being overridden below. This is, if the app sets traceablePeerConnection.onaddstream that would never be called.

Deprecation warning on Firefox

I get this warning on Firefox:
RTCSessionDescription's members are readonly! Writing to them is deprecated and will break soon.
What does it mean and what do I do to make members are not readonly? Thank you

[Edge] InvalidStateError when calling send() / receive()

This is a bug I've reported to Edge developers here:

https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12459320/

IMHO this is a clear bug in Edge and there is little we can do in JS to avoid it. It just happens that, sometimes, calling send() on a new RtpSender or receive() on a new RtpReceiver fails with InvalidStateError with no arguable reason (as explained in the bug reported above).

This means that, sometimes, receiving the audio/video from a new participant in a room fails.

[Edge] ICE error: Wrong MESSAGE-INTEGRITY

The issue

In some cases, Edge cannot establish the ICE connection with JVB. The next screenshot shows:

  • At the left: a successful ICE connection, and a random ICE Binding request sent by Edge which gets a OK response from JVB.
  • At the right: a similar ICE Binding request sent by Edge which gets an error response from JBC.

ice-ok-left-ice-wrong-right

The following screenshot shows the error response sent by JVB (Wrong MESSAGE-INTEGRITY):

ice-error-response

So, it may happen that:

  1. Indeed Edge is generating Binding request with wrongly calculated MESSAGE-INTEGRITY, or
  2. JVB is wrongly checking the request's MESSAGE-INTEGRITY.

How to reproduce it

I cannot yet confirm that the issue just happens in the following scenario. However it may be related:

  1. Make Chrome enter a room.
  2. Make Firefox join that room (or another Chrome).
  3. Make Edge join that room.

This scenario means that, at the beginning, Chrome and Firefox try a P2P connection and then they move to the SFU once Edge joins. From my point of view this should have zero impact in how Edge (or any other browser) performs the ICE procedures with JVB.

Said that, I've not seen any kind of ICE role conflict. The JVB sends the SDP offer so it becomes ICE controlling (as per RFC) and Edge receives the SDP offer so becomes ICE controlled. This is ok in the traces above.

FacingMode for local track is not working

Currently, the video of my local track is moving the opposite of user's movement, I want to make the local track to display the video like a mirror (mirroring user's movement). I tried to set facingMode to both user and environment when creating local track but none is working. The movement in the video still the opposite of user's movement.
Please help what am I missing?
Thank you

[Edge] stats audioLevel issue

According to the spec, audioLevel in stats should be in the range 0..1 (0 is silence). However Edge produces negative values (not sure about the range, but usually with little mic level, it's around -10).

RTPStatsCollector.js normalizes Chrome/Firefox values to 0..1. In order to do the same with Edge, an algorithm must be given.

Optimize for npm install

Apologies if this has been discussed already, but I can't find any other conversations on this topic.

Is there a reason that this package isn't really optimized for being installed through npm? I'm trying to integrate this into a React app and I'm having a bit of a hard time getting everything up and running.

It would be nice if we could simply npm install lib-jitsi-meet within a project and then just import JitsiMeetJS from 'lib-jitsi-meet';, however this currently doesn't seem to be possible.

Obviously the package isn't currently published to npm, but that's not an issue as we can install directly from this repo. Doing that, however, seems to do three things. It...

  1. Clones the repo
  2. Installs production dependencies only, not devDependencies
  3. Runs postinstall npm script (webpack -p) and fails because of missing devDependencies.

Navigating to <my-react-project>/node_modules/lib-jitsi-meet and running npm install manually does install these devDependencies and run the postinstall script successfully, creating lib-jitsi-meet.min.js and lib-jitsi-meet.min.map.

At this point, trying to import JitsiMeetJS from 'lib-jitsi-meet'; creates errors as the "main" property of the package.json references the ./index.js file, rather than the built (and transpiled) lib-jitsi-meet.min.js file created by webpack.

If we update the "main" property of the package.json to be ./lib-jitsi-meet.min.js then import JitsiMeetJS from 'lib-jitsi-meet'; does in fact import JitsiMeetJS as expected. Now, however, we get a ReferenceError: Strophe is not defined.

Adding import strophe; does resolve this, however we then get Missing strophe-plugins (disco and caps plugins are required)!. At this point it's clear that the strophe and strophe-plugins modules aren't included in the lib-jitsi-meet.min.js file that webpack builds, even though they are listed as project dependencies. Is there a reason that the choice was made to require these modules globally, rather than just importing them whenever they're needed? From looking through the codebase it looks like the same goes for jQuery.

This all can be solved by the user including <script> tags in their html, as you recommend, or possibly by using webpack's ProvidePlugin, but it seems like it would be far nicer to try to do as much as possible when packaging the module in the first place.

Interested to hear your thoughts on this.

how to unmute for participant jitsi meet?

Hi Team.

I want to custom some thing jitsi meet for my website. I want that : Moderator can unmute for any participant in room. Please! Can you tell me How to do that?.

I can see function
JitsiConference.prototype.muteParticipant = function(id) {
const participant = this.getParticipantById(id);
if (!participant) {
return;
}
this.room.muteParticipant(participant.getJid(), true);
};

in jitsiConference.js. I try to change false in this.room.muteParticipant(participant.getJid(), false); like this
JitsiConference.prototype.muteParticipant = function(id) {
const participant = this.getParticipantById(id);
if (!participant) {
return;
}
this.room.muteParticipant(participant.getJid(), false);
};

But it is not work.

If someone have any idea. please tell me. thank a lot.

sorry all . My english is not good.

Thank all.

[Edge] Device selection does not work

In Edge, the device selector UI shows grayed drop down lists for mic and webcam. Working on it.

The console says: "Failed to get access to local media. Error ". The call to getUserMedia() fails. Let's see why.

[Edge] Wrong BWE (JVB reports bad connectivity)

When testing with Chrome, Firefox and Edge, most of the time the JVB reports a terribly bandwidth availability on Edge (so in Chrome and Firefox I read "Edge is having connectivity issues" with frozen grayed video and so on).

I'm on a good network so I expect that the mechanism used by the JBV to estimate browsers bandwidth does not work fine with Edge.

NOTE: Edge does not support DataChannel so statistics are also missing. But I don't think this is related to the reported issue.

NOTE: The current implementation of lib-jitsi-meet in Edge does not support P2P mode so, for sure, this is always through the JVB.

/CC @gpolitis

Data channels support is disabled!

Just got this error with latest version.

Logger.js:89 [/modules/xmpp/strophe.util.js] <Object.Strophe.log>:  Strophe: error: Data channels support is disabled!
Error: Data channels support is disabled!
    at RTC.selectEndpoint (https://sub.example.com/libs/lib-jitsi-meet.min.js?v=139:4:16583)

What's wrong with the configuration?

Jingle timeout errors when trying to rejoin a conference

I'm building an application based on the example. The use case is slightly different, however, and I think I'm running into an untested situation here.

The use case: user opens the application page, clicks on a room button from a list of buttons, gets the selected (fullscreen) one-on-one conference until either the user or the remote party hangs up, and goes back the application page, repeat.

To get this repeated behaviour, I let the application page connect to JM on load and (leave and) disconnect on unload. However, after the first successful conference and hangup, I get Jingle timeout errors when I try to start a new conference:

[/modules/xmpp/ChatRoom.js] <new ChatRoom>:  Joined MUC as [email protected]/703057db
[/modules/xmpp/moderator.js] <Moderator.setFocusUserJid>:  Focus jid set to:  undefined
[/modules/xmpp/moderator.js] <Moderator.createConferenceIq>:  Session ID: null machine UID: 0afcf44782145cc147fdff78e2441afa
[/modules/RTC/RTCUtils.js] <>:  onUserMediaSuccess
Adding local tracks
[/modules/xmpp/JingleSessionPC.js] <JingleSessionPC.<anonymous>>:  Jingle error
Object {reason: "timeout", source: iq#631:sendIQ, session: JingleSessionPC}
  reason: "timeout"
  session: JingleSessionPC
  source: iq#631:sendIQ
  __proto__: Object

  log                   @       strophe.jingle.js:73
  (anonymous function)  @       ChatRoom.js:381
  (anonymous function)  @       strophe.min.js:2
  run                   @       strophe.min.js:2
  _onIdle               @       strophe.min.js:2

after which I cannot join any conference anymore until I reload the application page.
Note that this does not occur when I join and leave a conference that contains no remote peers.

I am ready to provide more debug information, if necessary. I can work on a smaller example than the application I currently have too.

Issue making the final browserify JS

I made few changes to the few Javascript in modules and I am trying to do make && make clean. It is failing with the following error

cp ./app.bundle.min.js ./app.bundle.min.map
./app.bundle.js ./app.bundle.js.map
./external_api.js.map ./external_api.js
./external_api.min.map ./external_api.min.js
libs
cp node_modules/lib-jitsi-meet//lib-jitsi-meet.min.js
node_modules/lib-jitsi-meet//lib-jitsi-meet.min.map
node_modules/lib-jitsi-meet//lib-jitsi-meet.js
node_modules/lib-jitsi-meet//lib-jitsi-meet.js.map
node_modules/lib-jitsi-meet//connection_optimization/external_connect.js
libs
cp: cannot stat ‘node_modules/lib-jitsi-meet//lib-jitsi-meet.min.js’: No such file or directory
cp: cannot stat ‘node_modules/lib-jitsi-meet//lib-jitsi-meet.min.map’: No such file or directory
cp: cannot stat ‘node_modules/lib-jitsi-meet//lib-jitsi-meet.js’: No such file or directory
cp: cannot stat ‘node_modules/lib-jitsi-meet//lib-jitsi-meet.js.map’: No such file or directory
cp: cannot stat ‘node_modules/lib-jitsi-meet//connection_optimization/external_connect.js’: No such file or directory

Calling the "mute" method causes the remote track to stop

When I call the mute method on a local track, the "TRACK_STOPPED" event gets triggered for remote peers.

Reproduction steps using demo application doc/example:

  • Open two browser windows
  • Enter localTracks[1].mute() into one users console (this will mute the video stream)
  • Observe that "remote track stoped" appears in the other users console
  • Calling localTracks[1].unmute() will create a new remote track instead of unmuting the existing one

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.