Once you have connected to a session, you can publish a stream that other clients connected to the session can view.
This topic includes the following sections:
Once you have connected to a session, you can check if the client can publish. Check the value of
the capabilities.publish
property of the Session
object. If it is set to 1,
the client can publish:
if (session.capabilities.publish == 1) {
// The client can publish. See the next section.
} else {
// The client cannot publish.
// You may want to notify the user.
}
To publish, the client must connect to the session with a token that is assigned a role that supports publishing. There must be a connected camera and microphone. Also, the client environment must support publishing (see Browser support).
Also, publishing is only supported on HTTPS pages.
The OT.initPublisher()
method initializes and returns a Publisher object. The Publisher object represents
the view of a video you publish:
var publisher;
var targetElement = 'publisherContainer';
publisher = OT.initPublisher(targetElement, null, function(error) {
if (error) {
// The client cannot publish.
// You may want to notify the user.
} else {
console.log('Publisher initialized.');
}
});
The OT.initPublisher()
method takes three parameters:
targetElement
(Optional) Defines the DOM element that the Publisher
video replaces.properties
(Optional) A set of properties that customize the Publisher.
The properties
parameter also includes options to specify an audio and video input
device used by the publisher (see Setting the camera and microphone
used by the publisher).
The properties
parameter also includes options for customizing the appearance of
view in the HTML page (see Customizing
the UI) and select whether to publish audio and video (see
Publishing audio or video only).
For more publisher options, see the documentation of the properties
parameter
of the OT.initPublisher() method.
completionHandler
(Optional) A completion handler that specifies
whether the publisher instantiated successfully or with an error.
You can pass this Publisher object into the Session.publish()
method to publish a stream to a session.
See Publishing a stream.
Before calling Session.publish()
, you can use this
Publisher object to test the microphone and camera attached to the Publisher.
The insertMode
property of the properties
parameter of the
OT.initPublisher()
method specifies how the Publisher object will be inserted
in the HTML DOM, in relation to the targetElement
parameter. You can set
this parameter to one of the following values:
"replace"
The Publisher object replaces contents of the targetElement.
This is the default."after"
The Publisher object is a new element inserted after the
targetElement in the HTML DOM. (Both the Publisher and targetElement have the same parent
element.)"before"
The Publisher object is a new element inserted before the
targetElement in the HTML DOM. (Both the Publisher and targetElement have the same parent
element.)"append"
The Publisher object is a new element added as a child of the
targetElement. If there are other child elements, the Publisher is appended as the last
child element of the targetElement.
For example, the following code adds a new Publisher object as a child of a
publisherContainer
DOM element:
// Try setting insertMode to other values: "replace", "after", or "before":
var publisherProperties = {insertMode: "append"};
var publisher = OT.initPublisher('publisherContainer', publisherProperties, function (error) {
if (error) {
console.log(error);
} else {
console.log("Publisher initialized.");
}
});
Before a Publisher object can access the client's camera and microphone, the user must grant access to them. The Publisher object dispatches events when the user grants or denies access to the camera and microphone:
publisher.on({
accessAllowed: function (event) {
// The user has granted access to the camera and mic.
},
accessDenied: function accessDeniedHandler(event) {
// The user has denied access to the camera and mic.
}
});
Also, a Publisher object dispatches events when the user is presented with the option to allow or deny access to the camera and microphone:
publisher.on({
accessDialogOpened: function (event) {
// The Allow/Deny dialog box is opened.
},
accessDialogClosed, function (event) {
// The Allow/Deny dialog box is closed.
}
});
The Publisher has an accessAllowed
property, which indicates whether a client has
(true
) or has not (false
) granted access to the camera and
microphone.
You can (optionally) specify an audio and video input device for the publisher to use.
When you call the OT.initPublisher()
method, you can (optionally) set the
audioSource
and videoSource
properties of the properties
object passed into the OT.initPublisher()
method.
First, use the OT.getDevices()
method to enumerate available devices. The array of devices
is passed in as the devices
parameter of the callback
function passed into the
OT.getDevices()
method. For example, the following code gets a list of audio and
video input devices:
var audioInputDevices;
var videoInputDevices;
OT.getDevices(function(error, devices) {
audioInputDevices = devices.filter(function(element) {
return element.kind == "audioInput";
});
videoInputDevices = devices.filter(function(element) {
return element.kind == "videoInput";
});
for (var i = 0; i < audioInputDevices.length; i++) {
console.log("audio input device: ", audioInputDevices[i].deviceId);
}
for (i = 0; i < videoInputDevices.length; i++) {
console.log("video input device: ", videoInputDevices[i].deviceId);
}
});
Each device listed by OT.getDevices()
has a unique device ID, set as the deviceId
property. You can use these device ID values as the audioSource
and videoSource
properties of the properties
object passed into OT.initPublisher()
:
var pubOptions =
{
audioSource: audioInputDevices[0].deviceId,
videoSource: videoInputDevices[0].deviceId
};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
console.log("OT.initPublisher error: ", error);
});
Set the videoSource
property to null
or false
in a voice-only
session (see Publishing in a voice session).
The OpenTok hardware set-up component
provides a user interface for clients to select the camera and microphone to
use. It is built using the OT.getDevices()
method.
Note that you can also publish a screen-sharing stream — one in which the source is the client's screen, not a camera. For details, see Screen sharing.
You can also change the camera used by the publisher, or set it to use the front- or back-facing camera (when this option is available).
You can also change the audio source used by the publisher.
When you initialize a publisher, you can set the facingMode
property of
the options object you pass into the
OT.initPublisher().
For example, you can set the property to "user"
(front-facing
camera) or "environment"
(rear-facing camera), when this option is available
on the client's system. (Generally, these options are available on mobile devices only.)
If you set the facingMode
option, do not set the
videoSource
property.
For security in pages loaded over HTTP, all browsers always prompt the user to select the camera and microphone used to publish a stream.
In pages loaded over HTTPS in Chrome, the user's camera and microphone selection is remembered and reused on subsequent visits to a page loaded from the same HTTPS domain.
In pages loaded over HTTPS in Firefox, the user has an option to remember the camera and microphone (in subsequent visits to a page loaded from the same HTTPS domain) when selecting the devices.
In pages loaded over HTTPS in IE, you can use the user's previous camera and microphone selection
from previous usage to the same HTTPS domain (if there was any), by setting the
usePreviousDeviceSelection
property to true
in the options you pass into
the OT.initPublisher()
method:
var pubOptions = {usePreviousDeviceSelection: true};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
console.log("OT.initPublisher error: ", error);
});
To prompt the user to select the camera and microphone to use in IE (and ignore previous device
selections), do not set the usePreviousDevices
property in the options you
pass into the OT.initPublisher()
method (or set it to false
, the
default).
By default, the SDK automatically handles the audio input device switching if there was a new one plugged in. This might not be the desired behavior for some end users that would like to keep the selection of their current microphone.
As an advanced user of the SDK, you can disable automatic audio input device management.
You can do so by setting the disableAudioInputDeviceManagement
property to the
options passed into the
OT.initPublisher()
method:
var pubOptions = {disableAudioInputDeviceManagement: true};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
console.log("Publishing a stream");
});
Note: This is an advanced feature. If you enable this, the audio input device used by the SDK will not be updated when the end user changes their microphone.
Note: This is a beta feature.
Once you create a Publisher object (See Initializing a publisher), you can pass it into
the publish()
method of a Session object to publish a stream to the session:
publisher = OT.initPublisher('replacementElementId');
session.publish(publisher, function(error) {
if (error) {
console.log(error);
} else {
console.log('Publishing a stream.');
}
});
The second parameter is a completion handler function that is passed an error object if publishing fails. Otherwise the completion handler function is called with no error passed in.
This code assumes that session
is a Session object, and that the client has connected to the
session. For more information, see Joining a Session.
The Publish object dispatches a streamCreated
event when it starts streaming to
the session:
var publisher = OT.initPublisher();
session.publish(publisher, function(error) {
if (error) {
console.log(error);
} else {
console.log('Publishing a stream.');
}
});
publisher.on('streamCreated', function (event) {
console.log('The publisher started streaming.');
});
The Publisher object has an element
property, which is set to the HTML DOM element
containing it.
You can stop publisher from streaming to the session by calling the unpublish()
method of the
Session object:
session.unpublish(publisher);
Note that you can individually stop sending video or audio (while still publishing). For more information, see Adjusting audio and video.
The Publisher object dispatches a streamDestroyed
event when it stops streaming to
the session:
var publisher = OT.initPublisher();
session.publish(publisher);
publisher.on("streamDestroyed", function (event) {
console.log("The publisher stopped streaming. Reason: "
+ event.reason);
});
The streamDestroyed
event is defined by the StreamEvent class. The event includes a reason
property, which details why the stream ended. These reasons include "clientDisconnected"
,
"forceDisconnected"
, "forceUnpublished"
, or "networkDisconnected"
. For details,
see StreamEvent.
By default, when a Publisher dispatches the streamDestroyed
event, the Publisher is destroyed and
removed from the HTML DOM. You can prevent this default behavior by calling the preventDefault()
method of
the StreamEvent object:
publisher.on("streamDestroyed", function (event) {
event.preventDefault();
console.log("The publisher stopped streaming.");
});
You may want to prevent the default behavior, and retain the Publisher, if you want to reuse the Publisher object to publish again to the session.
The Publisher also dispatches a destroyed
event when the object has been
removed from the HTML DOM. In response to this event, you may choose to adjust (or remove) DOM
elements related to the publisher that was removed.
To set a recommended video resolution for a published stream, set the resolution
property of the properties
parameter you pass into the OT.initPublisher()
method:
var publisherProperties = {resolution: '1280x720'};
var publisher = OT.initPublisher(targetElement,
publisherProperties);
publisher.on('streamCreated', function(event) {
console.log('Stream resolution: ' +
event.stream.videoDimensions.width +
'x' + event.stream.videoDimensions.height);
});
This resolution
property is a string, defining the desired resolution of the video.
The format of the string is "widthxheight"
, where the width and height
are represented in pixels. Valid values are "1920x1080"
, "1280x720"
,
"640x480"
, and "320x240"
.
The requested resolution of a video stream is set as the videoDimensions.width
and
videoDimensions.height
properties of the Stream object.
The default resolution for a stream (if you do not specify a resolution) is 640x480 pixels. If the client system cannot support the resolution you requested, the stream will use the next largest setting supported.
The videoHeight()
and videoWidth()
methods return the configured resolution of the Publisher object.
The actual resolution of a Subscriber video stream is returned by the videoWidth()
and videoHeight()
methods of
the Subscriber object. These may differ from the values of the resolution
property
passed in as the properties
property of the OT.initPublisher()
method, if
publishing the browser does not support the requested resolution.
Note: See the 1080p developer guide for considerations about using 1080p resolution.
To set a recommended frame rate for a published stream, set the frameRate
property
of the properties
parameter you pass into the OT.initPublisher()
method:
var publisherProperties = {frameRate: 7};
var publisher = OT.initPublisher(targetElement,
publisherProperties);
publisher.on('streamCreated', function(event) {
console.log('Frame rate: ' + event.stream.frameRate);
});
Set the value to the desired frame rate, in frames per second, of the video. Valid values are 30, 15, 7, and 1.
If the publisher specifies a frame rate, the actual frame rate of the video stream is set as
the frameRate
property of the Stream object, though the actual frame rate will
vary based on changing network and system conditions. If you do not specify a frame rate when
you call OT.initPublisher
, this property is undefined.
For sessions that use the OpenTok Media Router (sessions with the media mode set to routed), lowering the frame rate proportionally reduces the maximum bandwidth the stream can use. However, in session with the media mode set to relayed, lowering the frame rate does not reduce the stream's bandwidth.
You can also restrict the frame rate of a Subscriber's video stream. For more information, see Restricting the frame rate of a subscribed stream.
You can delete a Publisher by calling its destroy()
method:
publisher.destroy();
Calling the destroy()
method deletes the Publisher object and removes it from the HTML DOM.
The
Publisher.getStats()
method provides you with an array
of objects defining the current audio-video statistics for the publisher.
For a publisher in a routed session (one that uses the
OpenTok
Media Router), this array includes one object, defining the statistics for
the single audio-video stream that is sent to the OpenTok Media Router. In a relayed session,
the array includes an object for each subscriber to the published stream. Each object
in the array contains a stats
property that includes the following properties:
Additionally, for a publisher in a relayed session, each object in the array contains the following two properties:
connectionId
— The unique ID of the client's connection,
which matches the id
property of the connection
property
of the connectionCreated
event that the Session object dispatched
for the remote client.
subscriberId
— The unique ID of the subscriber, which matches
the id
property of the Subscriber object in the subscribing
client's app.
These two properties are undefined for a publisher in a routed session.
The following code logs the audio packet loss ratio, the audio bit rate, and the video packet loss ratio, and the video bit rate for the publisher's stream every second:
let prevStats = {};
window.setInterval(() => {
publisher.getStats((error, statsArray) => {
if (error) {
return console.log(error);
}
statsArray.forEach(statsObj => {
if (statsObj.connectionId) {
let prevStatsObj = prevStats[connectionId];
console.log('stats for connection', statsObj.connectionId);
} else {
prevStatsObj = prevStats;
}
const stats = statsObj.stats;
if (prevStatsObj.video) {
var videoBitRate = 8 * (stats.video.bytesSent - prevStatsObj.video.bytesSent);
console.log('video bit rate: ', videoBitRate, 'bps');
var audioBitRate = 8 * (stats.audio.bytesSent - prevStatsObj.audio.bytesSent);
console.log('audio bit rate: ', audioBitRate, 'bps');
}
if (stats.connectionId) {
prevStats[connectionId] = stats;
} else {
prevStats = stats;
}
});
})}, 1000);
To get more detailed stream statics, use the
Publisher.getRtcStatsReport()
method. It returns a promise that,
on success, resolves with an array of
RtcStatsReport
objects:
publisher.getRtcStatsReport()
.then(statArrays => statsArray.forEach(console.log))
.catch(console.log);
You can publish a test stream and check its audio and video statistics to determine the type of stream (such as high-resolution or audio-only) supported by your connection.
To get statistics for a stream published by the local client, you must use a session
that uses the OpenTok Media Router (sessions with the
media mode set to routed), and
you must set the testNetwork
property to true
in the
options
object you pass into the
Session.subscribe() method.
You can then use the getStats()
method of the Subscriber object to get
audio and video statistics for the stream you publish. See
this topic for more information.
The opentok-network-test repo includes sample code for showing how to use statistics of a test stream before publishing to a session.
You can set the video source for a Publisher to a video MediaStreamTrack object. This lets you do the following:
Publish video using an HTML Canvas element as the video. You can call the
captureStream()
method of the
HTMLCanvasElement object and call the getVideoTracks()
method of the resulting
CanvasCaptureMediaStream object to get a video MediaStreamTrack object.
For a basic example, see the Publish-Canvas sample
opentok-web-samples repo on
GitHub.
Publish video from a Video element. Call the captureStream()
method of
an
HTMLVideoElement object to obtain a MediaStream object. The getVideoTracks()
method of the MediaStream object returns an array of audio MediaStreamTrack objects (usually,
just one). You can then use the MediaStreamTrack object as the audioSource
property of the options
object you pass into the
OT.initPublisher() method.
For a basic example, see the Publish-Video sample
opentok-web-samples repo on
GitHub.
You can use a video MediaStreamTrack object as the videoSource
property
of the options
object you pass into the
OT.initPublisher() method.
This causes the video represented by the MediaStreamTrack object to be the video source for
the published stream.
You can set the audio source for a Publisher to an audio MediaStreamTrack object. This lets you do the following:
captureStream()
method of an
HTMLAudioElement object or an
HTMLVideoElement object to obtain a MediaStream object. The getAudioTracks()
method of the MediaStream object is an array of audio MediaStreamTrack objects (usually,
just one). You can then use the MediaStreamTrack object as the audioSource
property of the options
object you pass into the
OT.initPublisher() method.
createMediaStreamDestination().stream.getAudioTracks()[0]
on the AudioContext
object to get the audio MediaStreamTrack object to use as the audioSource
property of the options
object you pass into the
OT.initPublisher() method.
For a basic example, see the Stereo-Audio sample
opentok-web-samples repo on
GitHub.
You can apply filters and effects, such as background replacement or background blur, on audio or video obtained from a microphone or camera used as the source audio or video for a published stream — see this topic.
You can set a video content hint to improve the quality and performance of a published video. This can be useful in certain situations:
This tells the browser to use encoding or processing methods more appropriate to the type of content you specify.
Set the initial video content hint for a stream by setting the videoContentHint
property
of the options you pass into the OT.initPublisher()
method:
var publisherOptions = {
videoContentHint: "text",
// other options, such as videoSource: "screen"
};
var publisher = OT.initPublisher(targetElement, publisherOptions, callbackFunction);
You can change the video content hint dynamically by calling the
setVideoContentHint()
method of a Publisher object:
publisher.setVideoContentHint("motion");
You can set the video content hint to one of the following values:
""
— No hint is provided (the default). The publishing client
will make a best guess at how video content should be treated.
"motion"
— The track should be treated as if it contains video
where motion is important. For example, you may use this setting for a screen-sharing video stream
that contains video.
"detail"
— The track should be treated as if video details
are extra important. For example, you may use this setting for a screen-sharing video stream
that contains text content, painting, or line art.
"text"
— The track should be treated as if text details are
extra important. For example, you may use this setting for a screen-sharing video stream
that contains text content.
With the "text" and "detailed" content hints, the browser attempts to maintain high resolution, even if it must reduce the video frame rate. For the "motion" content hint, the browser reduces resolution to prevent the frame rate from stalling.
You can read more about these options in the W3C Working Draft.
Chrome 60+, Safari 12.1+, Edge 79+, and Opera 47+ support video content hints. The setting is ignored in other browsers.
If you can accept a slow frame rate, you may also consider restricting the frame rate of subscribed streams to improve quality.
See the developer guide for audio fallback . The publisher audio fallback feature provides enhanced bandwidth and quality monitoring to improve communications.
See the developer guide for Adjusting audio and video.
See Getting statistics about a publisher's stream.
This section includes tips for successfully publishing streams.
It is best practice to let your users know that they are going to be asked to allow access to their camera and microphone. We find that by far the largest number of failures to publish are a result of users clicking the "deny" button or not clicking the allow button at all. We provide you with all of the events you need to be able to guide your users through this process:
publisher.on({
accessDialogOpened: function (event) {
// Show allow camera message
pleaseAllowCamera.style.display = 'block';
},
accessDialogClosed: function (event) {
// Hide allow camera message
pleaseAllowCamera.style.display = 'none';
}
});
It is also a good idea to serve your website over SSL. This is because Chrome only requires users to click to allow access to devices once per domain if that domain is served over SSL. This means that your users (if on Chrome) don't have to deal with that inconvenient allow/deny dialog box every time they load the page.
Another thing we recommend is splitting the OT.initPublisher()
and Session.publish()
steps. This speeds up the initial connect time because you're connecting to the session while you're waiting for
the user to click the allow button. So instead of:
session.connect(token, function (err) {
{... your error handling code ...}
if (!err) {
var publisher = OT.initPublisher();
session.publish(publisher);
}
});
Move the OT.initPublisher()
step to before you connect, as in the following:
var publisher = OT.initPublisher();
session.connect(token, function (err) {
{... your error handling code ...}
if (!err) {
session.publish(publisher);
}
});
You can set the resolution and frame rate of the Publisher when you initialize it:
OT.initPublisher(divId, {
resolution: '320x240',
frameRate: 15
});
By default the resolution of a Publisher is 640x480, but you can set it to 1920x1080, 1280x720 or 320x240 as well. It is best to try to match the resolution to the size that the video will be displayed. If you are only displaying the video at 320x240 pixels then there is no point in streaming at 1280x720 or 1920x1080. Reducing the resolution can save bandwidth and reduce congestion and connection drops.
By default the frame rate of the video is 30 frames per second, but you can set it to 15, 7, or 1 as well. Reducing the frame rate can reduce the bandwidth required. Smaller resolution videos can have a lower frame rate without as much of a perceived difference to the user. So if you are using a low resolution, you might also want to think about using a low frame rate.
For more information, see the documentation for OT.initPublisher().
Follow the tips in this section to avoid connectivity issues when publishing. For general information on troubleshooting, see Debugging — Web.
There are callback methods for both Session.publish()
and OT.initPublisher()
. We recommend
handling the error responses to both of these methods. As mentioned earlier, it is best to split up
these steps and call OT.initPublisher()
before you have started connecting to your Session. It
also makes error handling easier if you are not calling both of these methods at the same time. This
is because both error handlers will fire if there is any error publishing. It is best to wait for
OT.initPublisher()
to complete and Session.connect()
to complete and then call
Session.publish()
. This way you can handle all hardware related issues in the OT.initPublisher()
callback and all network related issues in the Session.publish()
callback.
var connected = false,
publisherInitialized = false;
var publisher = OT.initPublisher(function(err) {
if (err) {
// handle error
} else {
publisherInitialized = true;
publish();
}
});
var publish = function() {
if (connected && publisherInitialized) {
session.publish(publisher);
}
};
session.connect(token, function(err) {
if (err) {
// handle error
} else {
connected = true;
publish();
}
});
The highest number of failures to OT.initPublisher()
are a result of the end-user denying access
to the camera and microphone. This can either be handled by listening for the accessDenied
event
or by listening for an error response to the OT.initPublisher() method with a code
property set
to 1500 and a message
property set to "Publisher Access Denied:". We recommend that you handle
this case and surface a message to the user indicating that they should try to publish again and
allow access to the camera.
publisher.on({
'accessDenied': function() {
showMessage('Please allow access to the Camera and Microphone and try publishing again.');
}
});
Another reason for OT.initPublisher()
to fail is if OpenTok cannot get access to a camera or
microphone. This can happen if there is no camera or microphone attached to the machine, if there is
something wrong with the driver for the camera or microphone, or if some other application is using
the camera or microphone (this only happens in Windows). You can try to minimize the occurrence of
these issues by using our Hardware Setup Component or by calling the OT.getDevices()
method directly. However you should also handle any error when calling
OT.initPublisher()
because something could still go wrong. For example, the user could
have denied access to the camera or microphone. In this case, the error.name
property is set to "OT_USER_MEDIA_ACCESS_DENIED"
:
publisher = OT.initPublisher('publisher', {}, function (err) {
if (err) {
if (err.name === 'OT_USER_MEDIA_ACCESS_DENIED') {
// Access denied can also be handled by the accessDenied event
showMessage('Please allow access to the Camera and Microphone and try publishing again.');
} else {
showMessage('Failed to get access to your camera or microphone. Please check that your webcam'
+ ' is connected and not being used by another application and try again.');
}
publisher.destroy();
publisher = null;
}
});
The other reasons for failures in publishing are usually due to some kind of network failure. We handle
these in the callback to Session.publish()
. If the user is not connected to the
network, the callback function is passed an error object with the name
property set
to "OT_NOT_CONNECTED"
. If the user is on a really restrictive network connection that
does not allow for WebRTC connections, the Publisher fails to connect, and the Publisher element
will just display a spinning wheel. This error has an name
property set to
"OT_CREATE_PEER_CONNECTION_FAILED"
. In this case recommend that you surface
a message to the user indicating that they failed to publish and that they should check their
network connection. Handling these errors looks like this:
session.publish(publisher, function(err) {
if (err) {
switch (err.name) {
case "OT_NOT_CONNECTED":
showMessage("Publishing your video failed. You are not connected to the internet.");
break;
case "OT_CREATE_PEER_CONNECTION_FAILED":
showMessage("Publishing your video failed. This could be due to a restrictive firewall.");
break;
default:
showMessage("An unknown error occurred while trying to publish your video. Please try again later.");
}
publisher.destroy();
publisher = null;
}
});
Your Publisher can also lose its connection after it has already succeeded in connecting. More
often than not, this will also result in the Session losing its connection, but that's not always
the case. You can handle the Publisher disconnecting by listening for the streamDestroyed
event
with a reason
property set to "networkDisconnected" like so:
publisher.on({
streamDestroyed: function (event) {
if (event.reason === 'networkDisconnected') {
showMessage('Your publisher lost its connection. Please check your internet connection and try publishing again.');
}
}
});
The following code creates a publisher, connects to a session (see Session basics), publishes a stream to the session when the client connects to the session, and detects when the publisher starts and stops streaming:
var session;
var publisher;
// Replace with the replacement element ID:
publisher = OT.initPublisher(replacementElementId);
publisher.on({
streamCreated: function (event) {
console.log("Publisher started streaming.");
},
streamDestroyed: function (event) {
console.log("Publisher stopped streaming. Reason: "
+ event.reason);
}
});
// Replace apiKey and sessionID with your own values:
session = OT.initSession(apiKey, sessionID);
// Replace token with your own value:
session.connect(token, function (error) {
if (session.capabilities.publish == 1) {
session.publish(publisher);
} else {
console.log("You cannot publish an audio-video stream.");
}
});