Skip to content

Releases: twilio/twilio-video.js

2.13.0

03 Mar 22:02
Compare
Choose a tag to compare

2.13.0 (March 3, 2021)

New Features

Video Processor API Pilot (Chrome only)

  • You can now register a VideoProcessor with a VideoTrack in order to process its video frames. In a LocalVideoTrack, video frames are processed before being sent to the encoder. In a RemoteVideoTrack, video frames are processed before being sent to the attached <video> element(s). The VideoProcessor should implement the interface shown below. (VIDEO-3560, VIDEO-3561)

    abstract class VideoProcessor {
      abstract processFrame(inputFrame: OffscreenCanvas)
        : Promise<OffscreenCanvas | null>
        | OffscreenCanvas | null;
    }

    A VideoTrack provides new methods addProcessor and removeProcessor which can be used to add and remove a VideoProcessor. It also provides a new property processor which points to the current VideoProcessor being used by the VideoTrack. For example, you can toggle a blur filter on a LocalVideoTrack as shown below.

    import { createLocalVideoTrack } from 'twilio-video';
    
    class BlurVideoProcessor {
      private readonly _outputFrameCtx: CanvasRenderingContext2D;
      private readonly _outputFrame: OffscreenCanvas;
    
      constructor(width: number, height: number, blurRadius: number) {
        this._outputFrame = new OffscreenCanvas(width, height);
        this._outputFrameCtx = this._outputFrame.getContext('2d');
        this._outputFrameCtx.filter = `blur(${blurRadius}px)`;
      }
    
      processFrame(inputFrame: OffscreenCanvas) {
        this._outputFrameCtx.drawImage(inputFrame, 0, 0);
        return this._outputFrame;
      }
    }
    
    // Local video track
    createLocalVideoTrack({
      width: 1280,
      height: 720
    }).then(track => {
      const processor = new BlurVideoProcessor(1280, 720, 5);
      document.getElementById('preview').appendChild(track.attach());
      document.getElementById('toggle-blur').onclick = () => track.processor
        ? track.removeProcessor(processor)
        : track.addProcessor(processor);
    });

    You can also toggle a blur filter on a RemoteVideoTrack as shown below.

    room.on('trackSubscribed', track => {
      if (track.kind === 'video') {
        const { width, height } = track.dimensions;
        const processor = new BlurVideoProcessor(width, height, 3);
        document.getElementById('preview-remote').appendChild(track.attach());
        document.getElementById('toggle-blur-remote').onclick = () => track.processor
          ? track.removeProcessor(processor)
          : track.addProcessor(processor);
      }
    });

2.12.0

10 Feb 20:47
Compare
Choose a tag to compare

2.12.0 (Feb 10, 2020)

New Features

100 Participant Rooms Pilot

  • In this pilot program developers can connect to a Group Room with Maximum Participants set between 50 and 100.
    A Room created with Max Participants greater than 50 is structured to support a small number of presenters and a large number of viewers. It has the following behavioral differences compared to regular Group Rooms:
    • "participantConnected" event is raised on the Room when a RemoteParticipant
      publishes the first LocalTrack.
    • "participantDisconnected" event is raised on the Room when a RemoteParticipant
      stops publishing all of its LocalTracks.
    • The total number of published Tracks in the Room cannot exceed 16 at any one time. Any attempt
      to publish more Tracks will be rejected with a ParticipantMaxTracksExceededError. (JSDK-3021)

Bug Fixes

  • Fixed a bug where calling LocalMediaTrack.restart() logged a warning about PeerConnection being closed in Peer to Peer Rooms. (JSDK-2912)
  • Fixed a race condition that sometimes caused switchedOff event for RemoteVideoTrack to not get emitted, which also resulted in wrong value for RemoteVideoTrack.isSwitchedOff property. (VIDEO-3695)

2.11.0

27 Jan 01:48
Compare
Choose a tag to compare

2.11.0 (January 26, 2021)

New Features

  • You can now import type definitions for the SDK APIs to your project. Previously, typescript developers relied on definitelyTyped for these definitions. We would like to thank the folks at DefinitelyTyped for maintaining these definitions. Going forward, the definitions will be included in the library and will take precedence over any other type definitions that you may be using. (JSDK-3007)

You can access the types of the public API classes from the Video namespace as shown below:

import * as Video from 'twilio-video';

Video.connect('token', { name: 'my-cool-room' }).then((room: Video.Room) => {
  console.log('Connected to Room:', room.name);
  room.on('participantConnected', (participant: Video.RemoteParticipant) => {
    console.log('RemoteParticipant joined:', participant.identity);
  });
});

Bug Fixes

  • Fixed a bug where the Video namespace is not exported properly when using RequireJS. (JSDK-3129)

2.10.0

10 Dec 23:43
Compare
Choose a tag to compare

2.10.0 (December 10, 2020)

New Features

  • twilio-video now allows customizing logger using loglevel module. With this feature, logs can now be intercepted at runtime to allow real-time processing of the logs which include but not limited to inspecting the log data and sending it to your own server. (JSDK-2373)

With this change ConnectOptions's logLevel property is now deprecated. You can instead use logger.setLevel to set the desired log level.

var { Logger, connect } = require('twilio-video');
var logger = Logger.getLogger('twilio-video');

// setLevel lets you to control what gets printed on console logs by twilio-video.
logger.setLevel('debug');
connect(token, {
  name: 'my-cool-room'
}).then(function(room) {
  room.on('participantConnected', function(participant) {
    console.log(participant.identity + ' has connected');
  });
}).catch(error => {
  console.log('Could not connect to the Room:', error.message);
});

Additionally ConnectOptions's eventListener property is now deprecated. You can listen for the signaling events by intercepting the logger's messages as shown in the example below. (JSDK-2977)

Example:

var { Logger, connect } = require('twilio-video');
var token = getAccessToken();

var logger = Logger.getLogger('twilio-video');

// Listen for logs
var originalFactory = logger.methodFactory;
logger.methodFactory = function (methodName, level, loggerName) {
  var method = originalFactory(methodName, level, loggerName);

  return function (datetime, logLevel, component, message, data) {
    method(datetime, logLevel, component, message, data);
    // check for signaling events that previously used to be
    // emitted on (now deprecated) eventListener
    // they are fired with message = `event`, and group == `signaling`
    if (message === 'event' && data.group === 'signaling') {
      if (data.name === 'waiting') {
        console.warn('Twilio\'s signaling server is busy, so we wait a little while before trying again.');
      } else if (data.name === 'connecting') {
        console.log('Connecting to Twilio\'s signaling server.');
      } else if (data.name === 'open') {
        console.log('Connected to Twilio\'s signaling server, joining the Room now.');
      } else if (data.name === 'closed') {
        if (data.level === 'error') {
          const { payload: { reason } } = data;
          console.error('Connection to Twilio\'s signaling server abruptly closed:', data.reason);
        } else {
          console.log('Connection to Twilio\'s signaling server closed.');
        }
      }
    }
  };
};

// you need to setLevel to info (or debug) in order to intercept signaling events.
logger.setLevel('info');
connect(token, {
  name: 'my-cool-room'
}).then(function(room) {
  room.on('participantConnected', function(participant) {
    console.log(participant.identity + ' has connected');
  });
}).catch(error => {
  console.log('Could not connect to the Room:', error.message);
});

2.9.0

03 Dec 01:50
Compare
Choose a tag to compare

2.9.0 (December 2, 2020)

Changes

  • Previously, Room.isRecording indicated whether recording is enabled for the Room.
    Now it indicates if the Track published to the Room are being recorded. If recording is
    enabled for the Room, then Room.isRecording is set to true when the first Track is published
    to the Room. It is set to false when the last Track is unpublished from the Room.
    The recordingStarted and recordingStopped events will be emitted on the Room
    when Room.isRecording toggles. (JSDK-3064)

Bug Fixes

  • Fixed a bug where LocalTrack event listeners attached by the SDK were not being cleaned up after disconnecting from a Room. (JSDK-2985)

2.8.0-beta.3

03 Dec 00:48
Compare
Choose a tag to compare
2.8.0-beta.3 Pre-release
Pre-release

2.8.0-beta.3 (December 2, 2020)

Change

This beta release adds instrumentation to capture usage of testPreflight API. if you are using testPreflight API please update to this version.

2.8.0

20 Nov 20:52
Compare
Choose a tag to compare

2.8.0 (November 20, 2020)

New Features

  • Enabled discontinuous transmission (DTX) in the Opus audio codec by default, which will result in bandwidth and CPU savings during silence and background noise. You can control this feature using the ConnectOptions property preferredAudioCodecs. (JSDK-3022)

    const { connect } = require('twilio-video');
    
    // Disable DTX for Opus.
    connect('token', {
      preferredAudioCodecs: [{ codec: 'opus', dtx: false }]
    });

Bug Fixes

  • Fixed a bug where Chrome Participants failed to restart a LocalAudioTrack or LocalVideoTrack on some android devices. (JSDK-3003)
  • Fixed a bug where sometimes Tracks that were added in quick succession were not published due to a race condition. (JSDK-2807)

2.8.0-beta.2

23 Oct 21:03
Compare
Choose a tag to compare

2.8.0-beta.2 (October 23, 2020)

Bug Fixes

  • Fixed a bug where an iOS 14 Safari Participant is not heard by others in a Room after handling an incoming phone call. (JSDK-3031)

2.7.3

22 Oct 03:55
Compare
Choose a tag to compare

2.7.3 (October 21, 2020)

Bug Fixes

  • Fixed a bug where an iOS 14 Safari Participant is not heard by others in a Room after handling an incoming phone call. (JSDK-3031)

2.8.0-beta.1

29 Sep 00:27
Compare
Choose a tag to compare

2.8.0-beta.1 (September 28, 2020)

New Features

  • This beta release adds a new experimental API testPreflight to help test the connectivity with twilio servers.
    The API connects two participants to the video room using supplied tokens. It publishes synthetic audio and video
    tracks from one participant. It also ensures that other participant receives media on those tracks.
    After successfully verifying the connectivity, it generates a report about statistics of the connection.

Few things to note:

  • The tokens used for the connection must specify the room for the test. This must be a unique test room
    and not to be used for regular operations.
  • Since the API connects participants to the room it would incur the typical cost for 2 mins of usage. The actual cost
    would depend on the room type used.
  • This function uses web audio API's.
    Browser's autoplay policies sometimes require user action before accessing these APIs. Please ensure that this API
    is called in response to user action like a button click.
  • preflightTest emits failed event to indicate test failures. Please refer to
    this guide
    for interpreting common errors.

Report generated by preflightTest on completed can be used to determine the quality of connection. Some of the useful stats and their optimal values are listed below.

Stat Explanation Optimal values
jitter Packets delay variation on audio tracks < 30ms
packetLoss Packet loss as a percent of total packets sent < 1%
networkQuality Network quality score (1 to 5), available only for group rooms > 3
rtt Round trip time in milliseconds. < 200ms

We encourage you to reach out to us with any feedback with the usage of the API.

const Video = require('twilio-video');
const tempRoomName = 'test-room-' + Date.now();
const publisherToken = getAccessToken('alice', tempRoomName);
const subscriberToken = getAccessToken('bob', tempRoomName);

const preflightTest = Video.testPreflight(publisherToken, subscriberToken);

preflightTest.on('completed', function(report) {
  console.log("Test completed in " + report.testTiming.duration + " milliseconds.");
  console.log(" It took " + report.networkTiming.connect.duration + " milliseconds to connect");
  console.log(" It took " + report.networkTiming.media.duration + " milliseconds to receive media");

  // network score is available only for group rooms.
  console.log(" Your network score was: " + report.stats.networkQuality);
});

preflightTest.on('failed', function(error) {
  console.log("Test failed:" + error);
});

preflightTest.on('progress', function(progressState) {
  console.log(progressState);
});

Bug Fixes

  • Fixed a bug where LocalTrack event listeners were not being cleaned up after disconnecting from a room. (JSDK-2985)