# Javascript SDK

# Introduction

This document is ECLWebRTC JavaScript SDK API Reference. See Documents/Introduction if this is the first time for you to develop application with ECLWebRTC.

# About class

A list of the classes described in this document.

  • Peer
  • MediaConnection
  • DataConnection
  • MeshRoom
  • SFURoom

# About EventEmitter

All classes above inherit EventEmitter.

Therefore, methods such as on(), off(), and emit() are available.

function onOpen() {
  console.log("an open event occurred!");
}

// add listener
peer.on("open", onOpen);
// remove listener
peer.off("open", onOpen);

// custom events
peer.on("myev", (val) => {
  console.log(val); // 3
});
peer.emit("myev", 3);

For API details, see the document of EventEmitter.

For events details, see the document of each class.

Set a listener for 'error' event is always recommended to avoid unexpected behavior.

# Peer

The Peer class is a entry point for P2P connection and room connection. In order to use ECLWebRTC, Peer instance is necessary.

# Constructor(id, options)

# Constructor(options)

Create a new Peer instance. new Peer() starts connection to ECLWebRTC's signaling server.

# Sample

// Set debug level to 3
const peer = new Peer('some-peer-name', {
  key:   "<YOUR-API-KEY>"
  debug: 3,
});
// Use TURN server forcely
const peer = new Peer({
  key:   "<YOUR-API-KEY>"
  config: {
    iceTransportPolicy: 'relay',
  },
});

# Parameter

Name Type Required Default Description
id string Your Peer ID. If no value is given, the Peer ID is generated by the signaling server.
options options object Options to configure connection parameters.
# options object
Name Type Required Default Description
key string ECLWebRTC API key.
debug number 0 Log level. NONE: 0, ERROR: 1, WARN: 2, FULL: 3.
turn boolean true Whether using ECLWebRTC's TURN server or NOT.
credential credential object The credential to authenticate peer.
config RTCConfiguration Default RTCConfiguration object RTCConfiguration object passed into RTCPeerConnection. This is advanced option.
# credential object

See Peer authentication example for details.

Name Type Required Default Description
timestamp number Current UNIX timestamp.
ttl number Time to live; The credential expires at timestamp + ttl. The range of possible values for ttl is 600 to 90,000.
authToken string Credential token calculated with HMAC.
# Default RTCConfiguration object
const defaultConfig = {
  iceServers: [
    {
      urls: "stun:stun.webrtc.ecl.ntt.com:3478",
      url: "stun:stun.webrtc.ecl.ntt.com:3478",
    },
  ],
  iceTransportPolicy: "all",
  sdpSemantics: "unified-plan",
};

# Members

Name Type Description
id string The Peer ID specified by a user or generated by signaling server.
open boolean Whether the socket is connecting to the signaling server or NOT.
connections Object Object contains all connections.
rooms Object Object contains all rooms.
options Object Object reflects Constructor() options and default options.

# Methods

# call(peerId[, stream][, options])

Create a new MediaConnection with Peer ID. With option, bandwidth or/and codec can be specified.

# Parameters
Name Type Required Default Description
peerId string The Peer ID you are calling.
stream MediaStream The MediaStream to send to the remote peer. If not set, connection will behave as recvonly.
options call options object Options for call().
# call options object
Name Type Required Default Description
metadata Object Any additional data to send to the remote peer.
videoBandwidth number A max video bandwidth(kbps).
audioBandwidth number A max audio bandwidth(kbps).
videoCodec string Video Codec. Supported codecs vary depending on the browser. Possible values are as follows. 'H264' 'VP8' 'VP9'
audioCodec string Audio Codec. Supported codecs vary depending on the browser. Possible values are as follows. 'opus' 'ISAC' 'G722' 'PCMU' 'PCMA'
videoReceiveEnabled boolean Set to true and your stream does not include video track, you will be video receive only mode.
audioReceiveEnabled boolean Set to true and your stream does not include audio track, you will be audio receive only mode.
connectionId string The ID to identify each connection.
label string Deprecated! The Label to identify each connection. Use connectionId instead.
# Return value

A MediaConnection instance.

# Sample
// Call a remote peer with your stream
const call = peer.call("peerID", localStream);
// Call a remote peer with your stream and metadata
const call = peer.call("peerID", localStream, {
  metadata: {
    foo: "bar",
  },
});
// Call a remote peer with H264 as a video codec
const call = peer.call("peerID", localStream, {
  videoCodec: "H264",
});
// Call a remote peer with audio receive only mode
const call = peer.call("peerID", null, {
  audioReceiveEnabled: true,
});

# connect(peerId[, options])

Create a new DataConnection with Peer ID.

# Parameters
Name Type Required Default Description
peerId string The Peer ID you are connecting.
options connect options object Options for connect().
# connect options object
Name Type Required Default Description
metadata Object Any additional data to send to the remote peer.
serialization string 'binary' Serialization for data when sending. One of 'binary', 'json', or 'none'.
dcInit RTCDataChannelInit {} RTCDataChannelInit object passed into createDataChannel() to change reliability. It is defaulting to true.
connectionId string The ID to identify each connection.
label string Deprecated! The Label to identify each connection. Use connectionId instead.
# Return value

A DataConnection instance.

# Sample
// Connect a remote peer with reliable mode(default)
peer.connect("peerId");
// Connect a remote peer with metadata
peer.connect("peerId", {
  metadata: {
    hoge: "foobar",
  },
});
// Connect a remote peer with unreliable mode
peer.connect("peerId", {
  dcInit: {
    maxRetransmits: 2,
  },
});

# destroy()

Close the connection to the signaling server and the already connected mediaConnection and dataConnection.

# Return value

undefined

# disconnect()

Disconnect the connection to the signaling server. In addition, the connected mediaConnection and dataConnection are continued.

# Return value

undefined

# reconnect()

Reconnect to the signaling server. Use the assigned Peer ID when reconnecting.

# Return value

undefined

# joinRoom(roomName[, roomOptions])

Join full-mesh type or SFU type room. See this page for the difference between full-mesh and SFU type.

# Parameters
Name Type Rquired Default Description
roomName string The room name you are joining.
roomOptions room options object {} Options for joinRoom().
# room options object
Name Type Required Default Description
mode string 'mesh' One of 'sfu' or 'mesh'.
stream MediaStream The MediaStream to send to the room you are joining. If not set, connection will behave as recvonly.
videoBandwidth number A max video bandwidth(kbps). Only available when mode is 'mesh'.
audioBandwidth number A max audio bandwidth(kbps). Only available when mode is 'mesh'.
videoCodec string Video Codec. Supported codecs vary depending on the browser. Possible values are as follows. 'H264' 'VP8' 'VP9' Only available when mode is 'mesh'.
audioCodec string Audio Codec. Supported codecs vary depending on the browser. Possible values are as follows. 'opus' 'ISAC' 'G722' 'PCMU' 'PCMA' Only available when mode is 'mesh'.
videoReceiveEnabled boolean Set to true and your stream does not include video track, you will be video receive only mode. Only available when mode is 'mesh'.
audioReceiveEnabled boolean Set to true and your stream does not include audio track, you will be audio receive only mode. Only available when mode is 'mesh'.
# Return value

An SFURoom instance or a MeshRoom instance.

# Sample
// Join full-mesh room
const room = peer.joinRoom("roomName", {
  mode: "mesh",
  stream: localStream,
});
// Join sfu room
const room = peer.joinRoom("roomName", {
  mode: "sfu",
  stream: localStream,
});

# listAllPeers(callback)

Call REST API to get the list of Peer IDs associated with API key.

# Parameters
Name Type Required Default Description
callback Function The callback function to get Peer IDs.
# Return value

undefined

# Sample
peer.listAllPeers((peers) => {
  console.log(peers);
  // => ["yNtQkNyjAojJNGrt", "EzAmgFhCKBQMzKw9"]
});

# getConnection(peerId, connectionId)

Query the created MediaConnection or DataConnection.

# Parameters
Name Type Required Default Description
peerId string The Peer ID.
connectionId string The connection ID.
# Return value

MediaConnection instance or DataConnection instance or null.

# updateCredential(credential)

Update credential to extend TTL of authentication. See Peer authentication example for details.

# Parameters
Name Type Required Default Description
credential credential object A new credential generated by user.
# Return value

undefined

# Events

Event names can be referred by static property EVENTS of Peer class.

// These are the same
peer.on("open", () => {});
peer.on(Peer.EVENTS.open, () => {});

# Event: 'open'

Fired when connected to the signaling server successfully.

Name Type Description
id string The Peer ID.
peer.on("open", (id) => {
  // ...
});

# Event: 'call'

Fired when received a media call from remote peer.

Name Type Description
call MediaConnection A MediaConnection instance.
peer.on("call", (call) => {
  // ...
});

# Event: 'close'

This event is fired by executing peer.destroy(). After this event, the connection to the signaling server, all mediaConnection and dataConnection will be disconnected and the user will be ejected from all Rooms.

peer.on("close", () => {
  // ...
});

# Event: 'connection'

Fired when received a data connection from remote peer.

Name Type Description
conn DataConnection A DataConnection instance.
peer.on("connection", (conn) => {
  // ...
});

# Event: 'disconnected'

Fired when disconnected from the signaling server.

Name Type Description
id string The Peer ID.
peer.on("disconnected", (id) => {
  // ...
});

# Event: 'expiresin'

Fired when the former credential expired.

Name Type Description
sec number The second before credential expires.
peer.on("expiresin", (sec) => {
  // ...
});

# Event: 'error'

Fired upon some error.

Name Type Description
error Error An error object.

Error object has type property to know its details.

| Type | Description |

Type Description
room-error Room name must be defined.
This room name is already used as different room type. Please try another room name.
SFU room functionality is disabled for this apikey.
An error occurred joining the room. Please wait a while and try again.
An error occurred getting log messages. Please wait a while and try again.
An error occurred getting users in the room. Please wait a while and try again.
An error occurred requesting offer. Please wait a while and try again.
An error occurred handling answer. Please wait a while and try again.
A SFU room is only joined up to 1000 times.
permission You do not have permission to access this room
list-error It doesn't look like you have permission to list peers IDs. Please enable the SkyWay REST API on dashboard.
disconnected Cannot connect to new Peer before connecting to SkyWay server or after disconnecting from the server.
socket-error Lost connection to server.
Could not connect to server.
There was a problem with the request for the dispatcher. Check your peer options and network connections.
The request for the dispatcher was aborted.
The request for the dispatcher timed out. Check your firewall, network speed, SkyWay failure information.
Connection failed. Unexpected response.
The dispatcher server returned an invalid JSON response. have no signaling server domain in JSON.
The dispatcher server returned an invalid JSON response.
invalid-id PeerId is not valid. Use a string between 1 to 63 characters long.
unavailable-id This peerid is already in use. Choose a different peerId and try again.
invalid-key This API key is invalid.
invalid-domain This domain is not registered to this API key.
authentication "timestamp" can't be in the future.
Credential has expired.
"authToken" has already expired.
"authToken" is invalid.
"ttl" is too large. Max value is ${maxTTL}.
"ttl" is too small. Min value is ${minTTL}.
server-error There was a problem with the server. Please wait a while and try again.
sfu-client-not-supported This client does not support using sfu rooms. Please use the latest version of Google Chrome.
peer-unavailable Failed to send to this peer. Please make sure the peerId is correct.
signaling-limited The request limit has been exceeded (500,000 Connection Count / month).
sfu-limited The TURN usage limit has been exceeded (500 GB / month).
turn-limited The SFU usage limit has been exceeded (500 GB / month).
// If you join a room without room name
peer.on("error", (error) => {
  console.log(`${error.type}: ${error.message}`);
  // => room-error: Room name must be defined.
});

WARNING

For Community Edition, if the "xxxx-limited" error occurs, the monthly usage limit of the corresponding function has been exceeded and the function will not be available until the beginning of next month.

# MediaConnection

The MediaConnection is a class which manages a media connection to another peer.

The constructor should not be used other than used inside the ECLWebRTC SDK. A MediaConnection instance will be given as a return value of Peer#call() and as an input of call event of the Peer.

# Sample

// Calling party
const mediaConnection = peer.call("peerID", mediaStream);

// Called party
peer.on("call", (mediaConnection) => {
  // answer with called party's media stream.
  mediaConnection.answer(mediaStream);
});

# Members

Name Type Description
type string String which describes the connection type. In MediaConnection, the value is 'media'.
metadata Object User-defined metadata given in Peer#call(). The called party has the value given by the calling party.
localStream MediaStream Local stream given in Peer#call() or MediaConnection#answer().
open boolean Boolean that is True if the connection is opened. The stream event of MediaConnection and MediaConnection#answer() could open the connection, the close event of MediaConnection and MediaConnection#close() could close the connection.
remoteId string The Peer ID of the peer this connection connect to.
peer string Deprecated The Peer ID of the peer this connection connect to. Use remoteId instead.
id string The ID to identify each connection.

# Methods

# answer(stream[, options])

Create and send an answer for the media connection offer.

# Parameters
Name Type Required Default Description
stream MediaStream A MediaStream which send to the calling party.
options answer options object Object which contains options which customize the answer.
# answer options object
Name Type Required Default Description
videoBandwidth number A max video bandwidth(kbps).
audioBandwidth number A max audio bandwidth(kbps).
videoCodec string Video Codec. Supported codecs vary depending on the browser. Possible values are as follows. 'H264' 'VP8' 'VP9'
audioCodec string Audio Codec. Supported codecs vary depending on the browser. Possible values are as follows. 'opus' 'ISAC' 'G722' 'PCMU' 'PCMA'
# Return value

undefined

# Sample
peer.on("call", (mediaConnection) => {
  const answerOption = {
    videoCodec: "H264",
  };

  mediaConnection.answer(mediaStream, answerOption);
});

# close(forceClose)

Close the MediaConnection between remote peer.

# Parameters
Name Type Required Default Description
forceClose boolean false Set to true and the connection on remote peer will close immediately. When set to false, the connection on remote peer will close after the end of the ICE reconnect by the browser.

Deprecated
false is deprecated and may be changed to true from a future version.
# Return value

undefined

# replaceStream(stream)

Change the MediaStream that is being sent.

For example, you can use it to change the camera or microphone device, or to change the image or sound quality.

CAUTION

It is not possible to change the state of a MediaStream from not sending to sending. You cannot change the state of MediaStream from not sending to sending and vice versa.

It is also not possible to interchange "MediaStream with either video or audio only" and "MediaStream with both video and audio".

# Parameters
Name Type Required Default Description
stream MediaStream The stream to be replaced.
# Return value

undefined

# getPeerConnection()

Get RTCPeerConnection instance which used internally in the MediaConnection between remote peer. If open property is false, it returns null instead.

!!! Notice Note that if you operate RTCPeerConnection directly, the ECLWebRTC SDK may not work properly.

# Return value

A RTCPeerConnection instance or null.

# Sample
if (mediaConnection.open) {
  const pc = mediaConnection.getPeerConnection();

  // ...
}

# Events

# Event: 'stream'

Fired when received a stream.

Name Type Description
stream MediaStream A MediaStream which received from remote peer.
mediaConnection.on("stream", (stream) => {
  // ...
});

# Event: 'close'

Fired when call MediaConnection#close(), or the media connection is closed.

mediaConnection.on("close", () => {
  // ...
});

# DataConnection

The DataConnection is a class which manages a data connection to another peer.

The constructor should not be used other than used inside the ECLWebRTC SDK. A DataConnection instance will be given as a return value of Peer#connect() and as an input of connection event of the Peer.

# Sample

// Calling party
const dataConnection = peer.connect("peerID");

// Called party
peer.on("connection", (dataConnection) => {
  // ...
});

# Members

Name Type Description
type string String which describes the connection type. In DataConnection, the value is 'data'.
metadata Object User-defined metadata object given in Peer#connect(). The called party has the value given by the calling party.
serialization string The serialization type given in Peer#connect(). The called party has the value given by the calling party.
dcInit RTCDataChannelInit RTCDataChannelInit object given in Peer#connect(). The called party has the value given by the calling party.
open boolean Boolean that is True if the connection is opened. The open event of DataConnection can open the connection, and it will be closed when the close event of DataConnection is fired or the data connection is disconnected.
remoteId string The Peer ID of the peer this connection connect to.
peer string Deprecated The Peer ID of the peer this connection connect to. Use remoteId instead.
id string The ID to identify each connection.

# Methods

# send(data)

Send data to the remote peer. If serialization is 'binary', it will chunk it before sending.

# Parameters
Name Type Required Default Description
data * The data to send to the peer.
# Return value

undefined

# Sample
// Send data
dataConnection.on("open", () => {
  const data = {
    name: "SkyWay",
    msg: "Hello, World!",
  };
  dataConnection.send(data);
});

// Receive data
dataConnection.on("data", ({ name, msg }) => {
  console.log(`${name}: ${msg}`);
  // => 'SkyWay: Hello, World!'
});

# getPeerConnection()

Get RTCPeerConnection instance which used internally in the DataConnection between remote peer. If open property is false, it returns null instead.

!!! Notice Note that if you operate RTCPeerConnection directly, the ECLWebRTC SDK may not work properly.

# Return value

A RTCPeerConnection instance or null.

# Sample
if (dataConnection.open) {
  const pc = dataConnection.getPeerConnection();

  // ...
}

# close(forceClose)

Close the DataConnection between the remote peer.

# Parameters
Name Type Required Default Description
forceClose boolean false Set to true and the connection on remote peer will close immediately.

Deprecated
false is deprecated and may be changed to true from a future version.
# Return value

undefined

# Events

# Event: 'open'

Fired when the data connection is opened.

dataConnection.on("open", () => {
  // ...
});

# Event: 'data'

Fired when received data from the remote peer. If serialization is 'binary', this event is fired when received all the chunked data and completed to unchunk.

Name Type Description
data * The data which received.
dataConnection.on("data", (data) => {
  // ...
});

# Event: 'close'

Fired when call DataConnection#close(), or the data connection is closed.

dataConnection.on("close", () => {
  // ...
});

# Event: 'error'

Fired when call DataConnection#send(), but the data connecion is not opened yet.

dataConnection.on("error", () => {
  // ...
});

# MeshRoom

The MeshRoom is a class which manages a full-mesh type room.

The constructor should not be used other than used inside the ECLWebRTC SDK. A MeshRoom instance will be given as a return value of Peer#joinRoom().

# Sample

const meshRoom = peer.joinRoom("roomName", {
  mode: "mesh",
  stream: localStream,
});
meshRoom.on("open", () => {});

# Members

Name Type Description
name string The room name.
connections Object Object contains all connections.

# Methods

# close()

Close all connections in the room.

# Return value

undefined

# getLog()

Start getting room's logs from signaling server. When fetching logs succeeds, log event fires.

# Return value

undefined

# Sample
room.once("log", (log) => {
  // ...
});
room.getLog();

# replaceStream(stream)

Change the MediaStream that is being sent.

For example, you can use it to change the camera or microphone device, or to change the image or sound quality.

CAUTION

It is not possible to change the state of a MediaStream from not sending to sending. You cannot change the state of MediaStream from not sending to sending and vice versa.

It is also not possible to interchange "MediaStream with either video or audio only" and "MediaStream with both video and audio".

# Parameters
Name Type Required Default Description
stream MediaStream The stream to be replaced.
# Return value

undefined

# send(data)

Send data to all members in the room with WebSocket.

CAUTION

  • The maximum size of the data to be sent is 20MB.

  • The frequent of consecutive send is limited to once every 100 msec. Outgoing data that exceeds the sending frequency limit is queued and sent sequentially every 100 msec

# Parameters
Name Type Required Default Description
data * The data to send.
# Return value

undefined

# Events

# Event: 'open'

Fired when the room is ready and you joined the room successfully.

room.on("open", () => {
  // ...
});

# Event: 'peerJoin'

Fired when a new remote peer has joined.

Name Type Description
peerId string The Peer ID of joined peer.
room.on("peerJoin", (peerId) => {
  // ...
});

# Event: 'peerLeave'

Fired when a remote peer has left.

Name Type Description
peerId string The Peer ID of left peer.
room.on("peerLeave", (peerId) => {
  // ...
});

# Event: 'log'

Fired when received the room log.

Name Type Description
logs string[] Array of JSON strings.
room.once("log", (logs) => {
  for (const logStr of logs) {
    const { messageType, message, timestamp } = JSON.parse(logStr);
    // ...
  }
});

# Event: 'stream'

Fired when received a MediaStream from remote peer in the room. The Peer ID of stream origin can be obtained via stream.peerId.

Name Type Description
stream MediaStream A MediaStream instance.
room.on("stream", (stream) => {
  // ...
});

# Event: 'data'

Fired when received the data from a remote peer in the room.

Name Type Description
data object data object itself.
# data object
Name Type Description
src string The Peer ID who sent this data.
data * Sent data.
room.on("data", ({ src, data }) => {
  // ...
});

# Event: 'close'

Fired when the Peer left the room.

room.on("close", () => {
  // ...
});

# SFURoom

The SFURoom is a class which manages an SFU type room.

The constructor should not be used other than used inside the ECLWebRTC SDK. An SFURoom instance will be given as a return value of Peer#joinRoom().

# Sample

const sfuRoom = peer.joinRoom("roomName", {
  mode: "sfu",
  stream: localStream,
});
sfuRoom.on("open", () => {});

# Members

Name Type Description
name string The room name.
remoteStreams Object Object contains all remote streams with MediaStream.id as key.
members string[] Array of the Peer ID in this room.

# Methods

# close()

Close all connections in the room.

# Return value

undefined

# getLog()

Start getting room's logs from signaling server. When fetching logs succeeds, log event fires.

# Return value

undefined

# Sample
room.once("log", (log) => {
  // ...
});
room.getLog();

# replaceStream(stream)

Change the MediaStream that is being sent.

For example, you can use it to change the camera or microphone device, or to change the image or sound quality.

CAUTION

It is not possible to change the state of a MediaStream from not sending to sending. You cannot change the state of MediaStream from not sending to sending and vice versa.

It is also not possible to interchange "MediaStream with either video or audio only" and "MediaStream with both video and audio".

# Parameters
Name Type Required Default Description
stream MediaStream The stream to be replaced.
# Return value

undefined

# send(data)

Send data to all members in the room with WebSocket.

CAUTION

  • The maximum size of the data to be sent is 20MB.

  • The frequent of consecutive send is limited to once every 100 msec. Outgoing data that exceeds the sending frequency limit is queued and sent sequentially every 100 msec

# Parameters
Name Type Required Default Description
data * The data to send.
# Return value

undefined

# Events

# Event: 'open'

Fired when the room is ready and you joined the room successfully.

room.on("open", () => {
  // ...
});

# Event: 'peerJoin'

Fired when a new remote peer joined.

Name Type Description
peerId string The Peer ID of joined peer.
room.on("peerJoin", (peerId) => {
  // ...
});

# Event: 'peerLeave'

Fired when a remote peer left.

Name Type Description
peerId string The Peer ID of left peer.
room.on("peerLeave", (peerId) => {
  // ...
});

# Event: 'log'

Fired when received the room log.

Name Type Description
logs string[] Array of JSON strings.
room.once("log", (logs) => {
  for (const logStr of logs) {
    const { messageType, message, timestamp } = JSON.parse(logStr);
    // ...
  }
});

# Event: 'stream'

Fired when received a MediaStream from remote peer in the room. The Peer ID of stream origin can be obtained via stream.peerId.

Name Type Description
stream MediaStream A MediaStream instance.
room.on("stream", (stream) => {
  // ...
});

# Event: 'data'

Fired when received the data from a remote peer in the room.

Name Type Description
data object data object itself.
# data object
Name Type Description
src string The Peer ID who sent this data.
data * Sent data.
room.on("data", ({ src, data }) => {
  // ...
});

# Event: 'close'

Fired when the Peer left the room, or the connection with the SFU server was disconnected.

room.on("close", () => {
  // ...
});

# TIPS

This page introduces Tips on WebRTC application development using ECLWebRTC JavaScript SDK.

The content does no guarantee its behavior. It always depends on the browser implementation.

# How to get MediaStream

Some methods like Peer#call() and Peer#joinRoom() accepts MediaStream as its arguments.

But our SDK does not provide specific API to get MediaStream.

In JavaScript API, you can get MediaStream in the following way.

  • navigator.mediaDevices.getUserMedia(options)
  • navigator.mediaDevices.getDisplayMedia(options)
(async function() {
  // ..

  const stream = await navigator.mediaDevices.getUserMedia({ video: true });
  const call = peer.call("remote-peerId", stream);

  // ...
})();

Details of options and how it works depends on each browser implementation.

Other than that, you can use captureStream() method from HTMLVideoElement, HTMLAudioElement and HTMLCanvasElement.

# Screen sharing

You can also use your own display itself as MediaStream.

By using it, it is possible to share your screen to the remote peer.

(async function() {
  // ..

  const stream = await navigator.mediaDevices.getDisplayMedia({ video: true });
  const call = peer.call("remote-peerId", stream);

  // ...
})();

If your browser does not support this API, a library like skyway/skyway-screenshare will be helpful.

# Select devices to use

If multiple cameras and microphones are available, you can select and use it.

(async function() {
  // ..

  const defaultVideoStream = await navigator.mediaDevices.getUserMedia({
    video: true,
  });

  // Get a list of devices
  const devices = await navigator.mediaDevices.enumerateDevices();

  // Specify any device
  const newVideoInputDevice = devices.find(
    (device) => device.kind === "videoinput"
  );
  const newVideoStream = await navigator.mediaDevices.getUserMedia({
    video: {
      deviceId: newVideoInputDevice.deviceId,
    },
  });

  // ...
})();

By using navigator.mediaDevices.enumerateDevices(), you can get the list of available devices.

Then select one in the list, and pass its deviceId to getUserMedia(), you can specify input source.

# Mute a MediaStream

If you want to mute your video and/or audio temporarily, set enabled property of MediaStreamTrack.

(async function() {
  // ..

  const stream = await navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true,
  });
  const call = peer.call("remote-peerId", stream);

  // mute audio
  stream.getAudioTracks().forEach((track) => (track.enabled = false));

  // ...
})();

# Multistream

In case sending multiple streams.

Currently, our SDK does not provide function to achieve that.

On your application code, you can do it by preparing multiple MediaConnection.

# sdpSemantics

You can pass RTCConfiguration for the RTCPeerConnection via Peer constructor.

But we always use the value unified-plan for the sdpSemantics property.