This tutorial enables you to quickly get started with creating an Agora account, downloading the SDK, and using the Agora sample app to give you an overview on how to develop requests to the Agora API:
- Join / Leave calls
- Publish / Unpublish streams
- Enable / Disable audio
- Enable / Disable video
- Agora.io Developer Account
- Web server that supports SSL (https)
This section shows you how to prepare, build, and run the sample application.
In order to build and run the sample application you must obtain an App ID:
- Create a developer account at agora.io. Once you finish the signup process, you will be redirected to the Dashboard.
- Navigate in the Dashboard tree on the left to Projects > Project List.
- Copy the App ID that you obtained from the Dashboard into a text file. You will use this when you launch the app.
The SDK must be integrated into the sample project before it can run.
-
Download the Agora Video SDK from Agora.io SDK. Under the Video + Interactive Broadcasting SDK heading, choose the Web download.
-
Unzip the downloaded SDK package.
-
Create a build folder in the root of the Github project and Copy the
AgoraRTCSDK
js file in the build folder. The file will have a sample name similar toAgoraRTCSDK-2.2.0.js
.Note:
2.2.0
is a placeholder for the version number of the SDK js file you downloaded.
-
Open the
index.html
file in a code editor. -
At the top of the file, in the
<head>
section, make sure the JavaScript file source is changed toAgoraRTCSDK-2.2.0.js
. Ensure the2.2.0
placeholder is the version number of the SDK js file you downloaded.Before
<script src="build/AgoraRTC-development.js"></script>
After
<script src="build/AgoraRTCSDK-2.2.0.js"></script>
-
Deploy the project on a web server. Make sure you access the page through an SSL (https) connection. The Agora SDK requires a secure connection to use the audio and video devices connected to the browser.
-
Use your browser to navigate to the index.html file. Once you have loaded the sample app, your browser will look like this:
-
In your browser window, paste the AppID into the
Key
UI text field. -
Press the
Join
UI button to join the call. As soon as someone else joins the call, the call will be started and you will see each other in the browser window.Note: If your sample app must be accessible using mobile browsers, ensure the
createClient
method is called with the propermode
(See section Create the Client). For more information, see the Agora API documentation.
- Check AgoraRTC and System Requirements
- Setup App Initialization and Logging
- Create the Client and Join a Channel Session
- Create and Manage a Stream
- Add Client Event Listeners
- Leave a Channel
- Publish and Unpublish a Stream
- Enable and Disable Audio and Video
AgoraRTC
is the base JavaScript class of Agora Web SDK, which enables the use of Agora Web SDK's communication functionality.
Agora requires WebRTC to run. To alert users that their browser does not support WebRTC, call the checkSystemRequirements()
method.
if(!AgoraRTC.checkSystemRequirements()) {
alert("Your browser does not support WebRTC!");
}
For convenience, the sample app declares the client
, localStream
, camera
, and microphone
variables after the page loads so they can be easily referenced in the code.
var client, localStream, camera, microphone;
Similarly, the sample app initializes the audio source audioSelect
and video source videoSelect
UI dropdown menus, which are used to populate them when the user's available audio and video devices are retrieved.
var audioSelect = document.querySelector('select#audioSource');
var videoSelect = document.querySelector('select#videoSource');
The index.html
file contains agetDevices()
method. This method loads all the available browser-enabled audio and video connections into the audio source
and video source
UI dropdown menus.
// function to find and load browser-enabled audio and video devices
function getDevices() {
AgoraRTC.getDevices(function (devices) {
for (var i = 0; i !== devices.length; ++i) {
var device = devices[i];
var option = document.createElement('option');
option.value = device.deviceId;
if (device.kind === 'audioinput') {
option.text = device.label || 'microphone ' + (audioSelect.length + 1);
audioSelect.appendChild(option);
} else if (device.kind === 'videoinput') {
option.text = device.label || 'camera ' + (videoSelect.length + 1);
videoSelect.appendChild(option);
} else {
console.log('Some other kind of source/device: ', device);
}
}
});
}
// initialize audio and video devices on page load
getDevices();
To use logging, invoke the methods from AgoraRTC.Logger
. The sample app shows examples of error
, warning
, info
, and debug
logging.
/* simulated data to proof setLogLevel() */
AgoraRTC.Logger.error('this is error');
AgoraRTC.Logger.warning('this is warning');
AgoraRTC.Logger.info('this is info');
AgoraRTC.Logger.debug('this is debug');
The sample app uses the join()
method to join the user to a specific channel.
function join() {
...
}
The join()
method starts with creating the broadcast client object. The interop
mode means that the app has permission to also work with Agora Native SDKs and is required if your app must run on mobile devices.
Specifically:
- In communication scenarios, interoperability with Agora Native SDKs is enabled automatically.
- In live broadcast scenarios, interoperability with Agora Native SDKs is enabled when the user calls
enableWebSdkInteroperability()
.
Note: The broadcast client object can only be created once per call session.
client = AgoraRTC.createClient({mode: 'interop'});
Once the client has been created, the sample app initializes the client by passing the app ID to the client.init()
method. In the sample app, the app ID is the text in the UI text field labeled Key
.
client.init(appId.value, function () {
console.log("AgoraRTC client initialized");
...
}, function (err) {
console.log("AgoraRTC client init failed", err);
});
Once the client initialization is complete, the client.join()
method is added to the onSuccess
callback. Pass the channel key, channel name, and user ID to the method parameters:
- Channel key: String used for broadcast security. For low security requirements, pass
null
as the parameter value. - Channel name: String that provides a unique channel name for the Agora session. This should be a numerical value for the Web SDK. The sample app uses
channel.value
(the value from theChannel
UI text field). - User ID: The user ID is a 32-bit unsigned integer ranging from 1 to (2^32-1). If you set the user ID to
null
, the Agora server allocates a user ID and returns it in theonSuccess
callback. If you decide to enter a specific user ID, make sure the integer is unique or an error will occur.
Note: Users in the same channel can talk to each other, but users with different app IDs cannot call each other even if they join the same channel.
Once this method is called successfully, the SDK triggers the callbacks.
var channel_key = null;
client.join(channel_key, channel.value, null, function(uid) {
console.log("User " + uid + " join channel successfully");
...
}, function(err) {
console.log("Join channel failed", err);
});
- Host a Stream
- Create a Stream
- Set the Stream Video Profile
- Set the Stream Event Listeners for Camera and Microphone Access
If a user who has joined the stream will act as the host, the app must create a stream. For the sample app, it checks if the Host
UI checkbox is checked. This check is applied within the onSuccess
callback of the client.join()
method.
if (document.getElementById("video").checked) {
...
}
If the user is a host, start the stream using the AgoraRTC.createStream()
method. The sample app passes in an object with the following properties:
- streamID: The stream ID. Normally the stream ID is set as the user ID, which can be retrieved from the
client.join()
callback. - audio: Indicates if this stream contains an audio track.
- video: Indicates if this stream contains a video track.
- screen: Indicates if this stream contains a screen sharing track. Currently screen sharing is only supported by the Google Chrome Explorer.
- cameraId: (Optional) The camera device ID retrieved from the getDevices method.
- microphoneId: (Optional) The microphone device ID retrieved from the getDevices method.
The createStream
object is set up for additional optional attributes. See the Agora API documentation for more information.
The sample app passes in the callback's user ID (uid
) as the stream ID, enables audio, uses the selected audio and video devices from the dropdowns, enables video for the host only, and disables screen sharing:
camera = videoSource.value;
microphone = audioSource.value;
localStream = AgoraRTC.createStream({
streamID: uid,
audio: true,
cameraId: camera,
microphoneId: microphone,
video: document.getElementById("video").checked,
screen: false}
);
If the user is a host, the video profile must be set. The sample app sets the video profile to 720p_3
, which represents a resolution of 1280x720, frame rate (fps) of 30, and a bitrate (kbps) of 1710. See the Agora API documentation for additional video profile options.
if (document.getElementById("video").checked) {
localStream.setVideoProfile('720p_3');
}
Once the stream has been set up and configured, the sample app adds event listeners using the localStream.on()
method to check for the user's microphone and camera permissions. These event listeners are used for debugging and to send alerts to request permissions. The sample app uses console logs to check if access to the camera and microphone was allowed or denied by the user.
// The user has granted access to the camera and mic.
localStream.on("accessAllowed", function() {
console.log("accessAllowed");
});
// The user has denied access to the camera and mic.
localStream.on("accessDenied", function() {
console.log("accessDenied");
});
Next, the sample app initializes the stream by calling the localStream.init()
method. Once initialized, the stream's host publishes the stream using the client.publish()
method.
localStream.init(function() {
console.log("getUserMedia successfully");
localStream.play('agora_local');
client.publish(localStream, function (err) {
console.log("Publish local stream error: " + err);
});
client.on('stream-published', function (evt) {
console.log("Publish local stream successfully");
});
}, function (err) {
console.log("getUserMedia failed", err);
});
- Setup Client Error Handling
- Add a Stream to the Client
- Subscribe a Stream to the Client and Add to the DOM
- Remove a Stream from the Client
- Remove a Peer from the Client
You can add listeners to the broadcast client to help you with debugging and managing streams. The sample app has event listeners for error messages, stream operations, and peer removal.
Passing error
into the client.on()
method will return the error type err.reason
. The sample app uses this error type for debugging and re-invoking methods that failed.
Since the Channel Key has an expiration, the sample app checks for the error DYNAMIC_KET_TIMEOUT
in the onFailure
callback. It then renews the channel key using the client.renewChannelKey()
method.
Note: If the channel key is not renewed, the communication to the SDK will disconnect.
channelKey = "";
client.on('error', function(err) {
console.log("Got error msg:", err.reason);
if (err.reason === 'DYNAMIC_KEY_TIMEOUT') {
client.renewChannelKey(channelKey, function(){
console.log("Renew channel key successfully");
}, function(err){
console.log("Renew channel key failed: ", err);
});
}
});
The stream-added
event listener detects when a new stream is added to the client. The sample app subscribes the newly added stream to the client after a new stream is added to the client.
client.on('stream-added', function (evt) {
var stream = evt.stream;
console.log("New stream added: " + stream.getId());
console.log("Subscribe ", stream);
client.subscribe(stream, function (err) {
console.log("Subscribe stream failed", err);
});
});
The sample app uses the stream-subscribed
event listener to detect when a new stream has been subscribed to the client, and to retrieve its stream ID using the stream.getId()
method. The stream is appended to the UI display using a <div>
.
Once the stream has been appended to the DOM, the sample app plays the stream by calling the stream.play()
method, passing in the string agora_remote
followed by the stream ID.
client.on('stream-subscribed', function (evt) {
var stream = evt.stream;
console.log("Subscribe remote stream successfully: " + stream.getId());
if ($('div#video #agora_remote'+stream.getId()).length === 0) {
$('div#video').append('<div id="agora_remote'+stream.getId()+'" style="float:left; width:810px;height:607px;display:inline-block;"></div>');
}
stream.play('agora_remote' + stream.getId());
});
If the stream is removed from the client stream-removed
, the sample app stops the stream from playing by calling the stream.stop()
method. It then removes it from the DOM using JQuery's remove()
method.
client.on('stream-removed', function (evt) {
var stream = evt.stream;
stream.stop();
$('#agora_remote' + stream.getId()).remove();
console.log("Remote stream is removed " + stream.getId());
});
When the sample app detects that a peer leaves the client using the peer-leave
event listener, it stops the stream from playing, and removes the stream from the DOM.
client.on('peer-leave', function (evt) {
var stream = evt.stream;
if (stream) {
stream.stop();
$('#agora_remote' + stream.getId()).remove();
console.log(evt.uid + " leaved from this channel");
}
});
}
The sample app applies the JavaScript leave()
method to the Leave
UI button.
The client.leave()
method removes the user from the current video call (channel). The sample app checks if the action succeeds or fails using the onSuccess
and onFailure
callbacks.
function leave() {
document.getElementById("leave").disabled = true;
client.leave(function () {
console.log("Leavel channel successfully");
}, function (err) {
console.log("Leave channel failed");
});
}
The sample app applies the JavaScript publish()
method to the Publish
UI button.
The client.publish()
method publishes the local stream to the server. The sample app passes in the stream object and uses the onFailure
callback to check for errors during the publishing process.
function publish() {
document.getElementById("publish").disabled = true;
document.getElementById("unpublish").disabled = false;
client.publish(localStream, function (err) {
console.log("Publish local stream error: " + err);
});
}
The sample app applies the JavaScript function unpublish()
to the Unpublish
UI button.
Similar to client.publish()
, the client.unpublish()
method unpublishes the local stream from the server. The sample app passes in the stream object and uses the onFailure
callback to check for errors during the publishing process.
function unpublish() {
document.getElementById("publish").disabled = false;
document.getElementById("unpublish").disabled = true;
client.unpublish(localStream, function (err) {
console.log("Unpublish local stream failed" + err);
});
}
For this section, run the cdn.html
sample file. Make sure to apply the same instructions from the File updates section to the cdn.html
file.
For each connected stream, the Agora API can enable or disable audio.
To enable audio, call the enableAudio()
method on the stream. The sample app applies the enableAudio()
method on the Enable Audio
UI button to enable audio on the open localStream
.
function enableAudio() {
localStream.enableAudio();
}
Disabling audio is exactly the same, but requires the disableAudio()
method. The sample app uses the disableAudio()
method applied to the Disable Audio
UI button.
function disableAudio() {
localStream.disableAudio();
}
For each connected stream, the Agora API can enable or disable video.
Enabling video is the same as enabling audio, but uses the enableVideo()
method on the stream. The sample app applies the enableVideo()
method to the Enable Video
UI button.
function enableVideo() {
localStream.enableVideo();
}
To disable video, use the disableVideo()
method. The sample app applies the disableVideo()
method applied to the Disable Video
UI button.
function disableVideo() {
localStream.disableVideo();
}
- Complete API documentation is available at the Document Center.
- You can file bugs about this sample here.
This software is under the MIT License (MIT). View the license.