sjkummer / janus-gateway-js

Janus-gateway WebRTC client for Node.js and the browser.
MIT License
172 stars 55 forks source link

janus-gateway-js Build Status codecov.io

About

Modern javascript client for janus gateway. Based on websockets. The original client can be found here https://janus.conf.meetecho.com/docs/rest.html.

Example of usage

This example assumes that a Janus server is running on localhost and WebSocket support is enabled on its default port 8188

var janus = new Janus.Client('ws://localhost:8188', {
  token: 'token',
  apisecret: 'apisecret',
  keepalive: 'true'
});

janus.createConnection('id').then(function(connection) {
  connection.createSession().then(function(session) {
    session.attachPlugin('bla').then(function(plugin) {
      plugin.send({}).then(function(response){});
      plugin.on('message', function(message) {});
      plugin.detach();
    });
  });
});

Install

npm i janus-gateway-js

Build

Project has a simple build. By default npm run-script build it builds the single file janus.js that contains Janus library and all its dependencies.

API

The library is available for Node and Browser environment. In Browser it is declared through window.Janus. The exported classes are:

Important! Please read MediaPlugin's info when using in Node.

Client

Class for creating connections. Use it if you want to create multiple connections to the same address with the same options.

Connection

Represents websocket connection to Janus. Instance of EventEmitter2.

Session

Represents Janus session. Instance of EventEmitter2.

Plugin

Represents Janus plugin. Instance of EventEmitter2.

MediaPlugin

Abstraction plugin class that holds generic Media methods and data. Extends Plugin.

IMPORTANT MediaPlugin has methods that require a working WebRTC which is not presented in Node environment. So, be careful when using this library in Node or browser that does not provide WebRTC. This warning is true for all plugins that extend from MediaPlugin.

Additional methods to Plugin are:

AudiobridgePlugin

It corresponds to 'janus.plugin.audiobridge'. Extends MediaPlugin. More thorough details to methods params below can be found at @see https://janus.conf.meetecho.com/docs/janus__audiobridge_8c.html#details. Additional methods to MediaPlugin are:

AudioroomPlugin

It corresponds to 'janus.plugin.cm.audioroom'. Docu page is https://github.com/cargomedia/janus-gateway-audioroom. It provides the same functionality as AudiobridgePlugin with minor differences: https://github.com/cargomedia/janus-gateway-audioroom#overview.

StreamingPlugin

It corresponds to 'janus.plugin.streaming'. Extends MediaPlugin. More thorough details to methods params below can be found at @see https://janus.conf.meetecho.com/docs/janus__streaming_8c.html#details. Additional methods to MediaPlugin are:

RtpbroadcastPlugin

It corresponds to 'janus.plugin.cm.rtpbroadcast'. Extends MediaPlugin. Docu page is https://github.com/cargomedia/janus-gateway-rtpbroadcast. Additional methods to MediaPlugin are:

WebsocketConnection

Promisified API for WebSocket. Instance of EventEmitter2.

Error

Custom Janus errors. Used for controlled errors that happen on janus messages.

JanusError

Tests

Tests are located under test/ directory. To run them use npm test.

Unit

These tests are located under test/unit/. To run them use $(npm bin)/mocha.

Integration

These tests are located under test/integration/. To run them you need:

Release

After that the npm release should be done automatically. If it didn't happen then release it manually:

npm publish https://github.com/sjkummer/janus-gateway-js/archive/<GitTagWithUpdatedPackageJson>.tar.gz

Plugins

Currently the project has four implemented plugins: audiobridge, videostreaming, rtpbroadcast and audioroom. It is temporarily. As soon as the project is stable those plugins will be moved to their own repositories. If you require a plugin that is not implemented then you need to write it on your own.

How to write a Plugin

For simplicity lets write an EchoTest plugin that does only audio.

  function EchoTest() {
    Janus.MediaPlugin.apply(this, arguments);
  }

  EchoTest.NAME = 'janus.plugin.echotest';
  EchoTest.prototype = Object.create(Janus.MediaPlugin.prototype);
  EchoTest.prototype.constructor = EchoTest;

  Janus.Plugin.register(EchoTest.NAME, EchoTest);

  /**
   * @param {boolean} state
   * @returns {Promise}
   * @fulfilled {RTCSessionDescription} jsep
   */
  EchoTest.prototype.audio = function(state) {
    var self = this;
    return Promise
      .try(function() {
        return self.getUserMedia({audio: true, video: false});
      })
      .then(function(stream) {
        self.createPeerConnection();
        stream.getTracks().forEach(function(track) {
          self.addTrack(track, stream);
        });
      })
      .then(function() {
        return self.createOffer();
      })
      .then(function(jsep) {
        var message = {body: {audio: state}, jsep: jsep};
        return self.sendWithTransaction(message);
      })
      .then(function(response) {
        var jsep = response.get('jsep');
        if (jsep) {
          self.setRemoteSDP(jsep);
          return jsep;
        }
      });
  };

Then we can use it

var janus = new Janus.Client(config.url, config);
janus.createConnection('client')
  .then(function(connection) {
    return connection.createSession();
  })
  .then(function(session) {
    return session.attachPlugin(EchoTest.NAME);
  })
  .then(function(echotestPlugin) {
    return echotestPlugin.audio(true);
  })