Amazon Chime SDK for JavaScript
Amazon Chime SDK Project Board
Amazon Chime SDK React Components
Build video calling, audio calling, messaging, and screen sharing applications powered by the Amazon Chime SDK
The Amazon Chime SDK is a set of real-time communications components that developers can
use to quickly add messaging, audio, video, and screen sharing capabilities to their web or
mobile applications.
Developers can build on AWS's global communications infrastructure to deliver
engaging experiences in their applications. For example, they can add video to a
health application so patients can consult remotely with doctors on health
issues, or create customized audio prompts for integration with the public
telephone network.
The Amazon Chime SDK for JavaScript works by connecting to meeting session
resources that you create in your AWS account. The SDK has everything
you need to build custom calling and collaboration experiences in your
web application, including methods to configure meeting sessions, list and
select audio and video devices, start and stop screen share and screen share
viewing, receive callbacks when media events such as volume changes occur, and
control meeting features such as audio mute and video tile bindings.
If you are building a React application, consider using the Amazon Chime SDK React Component Library that supplies client-side state management and reusable UI components for common web interfaces used in audio and video conferencing applications. Amazon Chime also offers Amazon Chime SDK for iOS and Amazon Chime SDK for Android for native mobile application development.
The Amazon Chime SDK Project Board captures the status of community feature requests across all our repositories. The descriptions of the columns on the board are captured in this guide.
Resources
Blog posts
In addition to the below, here is a list of all blog posts about the Amazon Chime SDK.
High level
Frontend
Full stack and PSTN
Messaging
Media Pipelines
Webinars and videos
JavaScript SDK Guides
The following developer guides cover specific topics for a technical audience.
Migration Guides
Developer Guides
The following developer guides cover the Amazon Chime SDK more broadly.
Examples
PSTN Audio Examples
Troubleshooting and Support
Review the resources given in the README and use our client documentation for guidance on how to develop on the Chime SDK for JavaScript. Additionally, search our issues database and FAQs to see if your issue is already addressed. If not please cut us an issue using the provided templates.
The blog post Monitoring and Troubleshooting With Amazon Chime SDK Meeting Events goes into detail about how to use meeting events to troubleshoot your application by logging to Amazon CloudWatch.
If you have more questions, or require support for your business, you can reach out to AWS Customer support. You can review our support plans here.
WebRTC Resources
The Amazon Chime SDK for JavaScript uses WebRTC, the real-time communication API supported in most modern browsers. Here are some general resources on WebRTC.
Installation
Make sure you have Node.js version 18 or higher. Node 20 is recommended and supported.
To add the Amazon Chime SDK for JavaScript into an existing application,
install the package directly from npm:
npm install amazon-chime-sdk-js --save
Note that the Amazon Chime SDK for JavaScript targets ES2015, which is fully compatible with
all supported browsers.
Setup
Meeting session
Create a meeting session in your client application.
import {
ConsoleLogger,
DefaultDeviceController,
DefaultMeetingSession,
LogLevel,
MeetingSessionConfiguration
} from 'amazon-chime-sdk-js';
const logger = new ConsoleLogger('MyLogger', LogLevel.INFO);
const deviceController = new DefaultDeviceController(logger);
const meetingResponse = ;
const attendeeResponse = ;
const configuration = new MeetingSessionConfiguration(meetingResponse, attendeeResponse);
const meetingSession = new DefaultMeetingSession(
configuration,
logger,
deviceController
);
Getting responses from your server application
You can use an AWS SDK, the AWS Command Line Interface (AWS CLI), or the REST API
to make API calls. In this section, you will use the AWS SDK for JavaScript in your server application, e.g. Node.js.
See Amazon Chime SDK API Reference for more information.
⚠️ The server application does not require the Amazon Chime SDK for JavaScript.
const AWS = require('aws-sdk');
const { v4: uuid } = require('uuid');
const chime = new AWS.ChimeSDKMeetings({ region: 'us-east-1' });
const meetingResponse = await chime
.createMeeting({
ClientRequestToken: uuid(),
MediaRegion: 'us-west-2',
})
.promise();
const attendeeResponse = await chime
.createAttendee({
MeetingId: meetingResponse.Meeting.MeetingId,
ExternalUserId: uuid(),
})
.promise();
Now securely transfer the meetingResponse
and attendeeResponse
objects to your client application.
These objects contain all the information needed for a client application using the Amazon Chime SDK for JavaScript to join the meeting.
The value of the MediaRegion parameter in the createMeeting() should ideally be set to the one of the media regions which is closest to the user creating a meeting. An implementation can be found under the topic 'Choosing the nearest media Region' in the Amazon Chime SDK Media Regions documentation.
Messaging session
Create a messaging session in your client application to receive messages from Amazon Chime SDK for Messaging.
import { ChimeSDKMessagingClient } from '@aws-sdk/client-chime-sdk-messaging';
import {
ConsoleLogger,
DefaultMessagingSession,
LogLevel,
MessagingSessionConfiguration,
} from 'amazon-chime-sdk-js';
const logger = new ConsoleLogger('SDK', LogLevel.INFO);
const chime = new ChimeSDKMessagingClient({ region: 'us-east-1'});
const userArn = ;
const sessionId = ;
const configuration = new MessagingSessionConfiguration(userArn, sessionId, undefined, chime);
const messagingSession = new DefaultMessagingSession(configuration, logger);
If you would like to enable prefetch feature when connecting to a messaging session, you can follow the code below.
Prefetch feature will send out CHANNEL_DETAILS event upon websocket connection, which includes information about channel,
channel messages, channel memberships etc. Prefetch sort order can be adjusted with prefetchSortBy
, setting it to either
unread
(default value if not set) or lastMessageTimestamp
configuration.prefetchOn = Prefetch.Connect;
configuration.prefetchSortBy = PrefetchSortBy.Unread;
Building and testing
git fetch --tags https://github.com/aws/amazon-chime-sdk-js
npm run build
npm run test
After running npm run test
the first time, you can use npm run test:fast
to speed up the test suite.
Tags are fetched in order to correctly generate versioning metadata.
To view code coverage results open coverage/index.html
in your browser after running npm run test
.
If you run npm run test
and the tests are running but the coverage report is not getting generated then you might have a resource clean up issue. In Mocha v4.0.0 or newer the implementation was changed so that the Mocha processes will not force exit when the test run is complete.
For example, if you have a DefaultVideoTransformDevice
in your unit test then you must call await device.stop();
to clean up the resources and not run into this issue. You can also look into the usage of done();
in the Mocha documentation.
Generating the documentation
To generate JavaScript API reference documentation run:
npm run build
npm run doc
Then open docs/index.html
in your browser.
Reporting a suspected vulnerability
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our
vulnerability reporting page.
Please do not create a public GitHub issue.
Usage
Device
Note: Before starting a session, you need to choose your microphone, speaker, and camera.
Use case 1. List audio input, audio output, and video input devices. The browser will ask for microphone and camera permissions.
With the forceUpdate
parameter set to true, cached device information is discarded and updated after the device label trigger is called. In some cases, builders need to delay the triggering of permission dialogs, e.g., when joining a meeting in view-only mode, and then later be able to trigger a permission prompt in order to show device labels; specifying forceUpdate
allows this to occur.
const audioInputDevices = await meetingSession.audioVideo.listAudioInputDevices();
const audioOutputDevices = await meetingSession.audioVideo.listAudioOutputDevices();
const videoInputDevices = await meetingSession.audioVideo.listVideoInputDevices();
audioInputDevices.forEach(mediaDeviceInfo => {
console.log(`Device ID: ${mediaDeviceInfo.deviceId} Microphone: ${mediaDeviceInfo.label}`);
});
Use case 2. Choose audio input and audio output devices by passing the deviceId
of a MediaDeviceInfo
object.
Note that you need to call listAudioInputDevices
and listAudioOutputDevices
first.
const audioInputDeviceInfo = ;
await meetingSession.audioVideo.startAudioInput(audioInputDeviceInfo.deviceId);
const audioOutputDeviceInfo = ;
await meetingSession.audioVideo.chooseAudioOutput(audioOutputDeviceInfo.deviceId);
Use case 3. Choose a video input device by passing the deviceId
of a MediaDeviceInfo
object.
Note that you need to call listVideoInputDevices
first.
If there is an LED light next to the attendee's camera, it will be turned on indicating that it is now capturing from the camera.
You probably want to choose a video input device when you start sharing your video.
const videoInputDeviceInfo = ;
await meetingSession.audioVideo.startVideoInput(videoInputDeviceInfo.deviceId);
await meetingSession.audioVideo.stopVideoInput();
Use case 4. Add a device change observer to receive the updated device list.
For example, when you pair Bluetooth headsets with your computer, audioInputsChanged
and audioOutputsChanged
are called
with the device list including headsets.
You can use the audioInputMuteStateChanged
callback to track the underlying
hardware mute state on browsers and operating systems that support that.
const observer = {
audioInputsChanged: freshAudioInputDeviceList => {
freshAudioInputDeviceList.forEach(mediaDeviceInfo => {
console.log(`Device ID: ${mediaDeviceInfo.deviceId} Microphone: ${mediaDeviceInfo.label}`);
});
},
audioOutputsChanged: freshAudioOutputDeviceList => {
console.log('Audio outputs updated: ', freshAudioOutputDeviceList);
},
videoInputsChanged: freshVideoInputDeviceList => {
console.log('Video inputs updated: ', freshVideoInputDeviceList);
},
audioInputMuteStateChanged: (device, muted) => {
console.log('Device', device, muted ? 'is muted in hardware' : 'is not muted');
},
};
meetingSession.audioVideo.addDeviceChangeObserver(observer);
Starting a session
Use case 5. Start a session. To hear audio, you need to bind a device and stream to an <audio>
element.
Once the session has started, you can talk and listen to attendees.
Make sure you have chosen your microphone and speaker (See the "Device" section), and at least one other attendee has joined the session.
const audioElement = ;
meetingSession.audioVideo.bindAudioElement(audioElement);
const observer = {
audioVideoDidStart: () => {
console.log('Started');
}
};
meetingSession.audioVideo.addObserver(observer);
meetingSession.audioVideo.start();
Use case 6. Add an observer to receive session lifecycle events: connecting, start, and stop.
Note: You can remove an observer by calling meetingSession.audioVideo.removeObserver(observer)
.
In a component-based architecture (such as React, Vue, and Angular), you may need to add an observer
when a component is mounted, and remove it when unmounted.
const observer = {
audioVideoDidStart: () => {
console.log('Started');
},
audioVideoDidStop: sessionStatus => {
console.log('Stopped with a session status code: ', sessionStatus.statusCode());
},
audioVideoDidStartConnecting: reconnecting => {
if (reconnecting) {
console.log('Attempting to reconnect');
}
},
};
meetingSession.audioVideo.addObserver(observer);
Audio
Note: So far, you've added observers to receive device and session lifecycle events.
In the following use cases, you'll use the real-time API methods to send and receive volume indicators and control mute state.
Use case 7. Mute and unmute an audio input.
meetingSession.audioVideo.realtimeMuteLocalAudio();
const unmuted = meetingSession.audioVideo.realtimeUnmuteLocalAudio();
if (unmuted) {
console.log('Other attendees can hear your audio');
} else {
console.log('You cannot unmute yourself');
}
Use case 8. To check whether the local microphone is muted, use this method rather than keeping track of your own mute state.
const muted = meetingSession.audioVideo.realtimeIsLocalAudioMuted();
if (muted) {
console.log('You are muted');
} else {
console.log('Other attendees can hear your audio');
}
Use case 9. Disable unmute. If you want to prevent users from unmuting themselves (for example during a presentation), use these methods rather than keeping track of your own can-unmute state.
meetingSession.audioVideo.realtimeSetCanUnmuteLocalAudio(false);
meetingSession.audioVideo.realtimeMuteLocalAudio();
const unmuted = meetingSession.audioVideo.realtimeUnmuteLocalAudio();
console.log(`${unmuted} is false. You cannot unmute yourself`);
Use case 10. Subscribe to volume changes of a specific attendee. You can use this to build a real-time volume indicator UI.
import { DefaultModality } from 'amazon-chime-sdk-js';
const presentAttendeeId = meetingSession.configuration.credentials.attendeeId;
meetingSession.audioVideo.realtimeSubscribeToVolumeIndicator(
presentAttendeeId,
(attendeeId, volume, muted, signalStrength) => {
const baseAttendeeId = new DefaultModality(attendeeId).base();
if (baseAttendeeId !== attendeeId) {
console.log(`The volume of ${baseAttendeeId}'s content changes`);
}
console.log(`${attendeeId}'s volume data: `, {
volume,
muted,
signalStrength,
});
}
);
Use case 11. Subscribe to mute or signal strength changes of a specific attendee. You can use this to build UI for only mute or only signal strength changes.
const presentAttendeeId = meetingSession.configuration.credentials.attendeeId;
meetingSession.audioVideo.realtimeSubscribeToVolumeIndicator(
presentAttendeeId,
(attendeeId, volume, muted, signalStrength) => {
if (muted === null) {
return;
}
console.log(`${attendeeId}'s mute state changed: `, {
muted,
});
}
);
meetingSession.audioVideo.realtimeSubscribeToVolumeIndicator(
presentAttendeeId,
(attendeeId, volume, muted, signalStrength) => {
if (signalStrength === null) {
return;
}
console.log(`${attendeeId}'s signal strength changed: `, {
signalStrength,
});
}
);
Use case 12. Detect the most active speaker. For example, you can enlarge the active speaker's video element if available.
import { DefaultActiveSpeakerPolicy } from 'amazon-chime-sdk-js';
const activeSpeakerCallback = attendeeIds => {
if (attendeeIds.length) {
console.log(`${attendeeIds[0]} is the most active speaker`);
}
};
meetingSession.audioVideo.subscribeToActiveSpeakerDetector(
new DefaultActiveSpeakerPolicy(),
activeSpeakerCallback
);
Video
Note: In Chime SDK terms, a video tile is an object containing an attendee ID,
a video stream, etc. To view a video in your application, you must bind a tile to a <video>
element.
- Make sure you bind a tile to the same video element until the tile is removed.
- A local video tile can be identified using
localTile
property. - A tile is created with a new tile ID when the same remote attendee restarts the video.
- Media Capture Pipeline relies on the meeting session to get the attendee info. After calling
this.meetingSession.audioVideo.start();
, wait for audioVideoDidStart
event to be received before calling startLocalVideoTile
.
Use case 13. Start sharing your video. The local video element is flipped horizontally (mirrored mode).
const videoElement = ;
const videoInputDevices = await meetingSession.audioVideo.listVideoInputDevices();
await meetingSession.audioVideo.startVideoInput(videoInputDevices[0].deviceId);
const observer = {
videoTileDidUpdate: tileState => {
if (!tileState.boundAttendeeId || !tileState.localTile) {
return;
}
meetingSession.audioVideo.bindVideoElement(tileState.tileId, videoElement);
}
};
meetingSession.audioVideo.addObserver(observer);
meetingSession.audioVideo.startLocalVideoTile();
Use case 14. Stop sharing your video.
const videoElement = ;
let localTileId = null;
const observer = {
videoTileDidUpdate: tileState => {
if (!tileState.boundAttendeeId || !tileState.localTile) {
return;
}
console.log(`If you called stopLocalVideoTile, ${tileState.active} is false.`);
meetingSession.audioVideo.bindVideoElement(tileState.tileId, videoElement);
localTileId = tileState.tileId;
},
videoTileWasRemoved: tileId => {
if (localTileId === tileId) {
console.log(`You called removeLocalVideoTile. videoElement can be bound to another tile.`);
localTileId = null;
}
}
};
meetingSession.audioVideo.addObserver(observer);
meetingSession.audioVideo.stopLocalVideoTile();
await meetingSession.audioVideo.stopVideoInput();
meetingSession.audioVideo.removeLocalVideoTile();
Use case 15. View one attendee video, e.g. in a 1-on-1 session.
const videoElement = ;
const observer = {
videoTileDidUpdate: tileState => {
if (!tileState.boundAttendeeId || tileState.localTile || tileState.isContent) {
return;
}
meetingSession.audioVideo.bindVideoElement(tileState.tileId, videoElement);
}
};
meetingSession.audioVideo.addObserver(observer);
Use case 16. View up to 25 attendee videos. Assume that you have 25 video elements in your application,
and that an empty cell means it's taken.
const videoElements = [
];
const indexMap = {};
const acquireVideoElement = tileId => {
for (let i = 0; i < 25; i += 1) {
if (indexMap[i] === tileId) {
return videoElements[i];
}
}
for (let i = 0; i < 25; i += 1) {
if (!indexMap.hasOwnProperty(i)) {
indexMap[i] = tileId;
return videoElements[i];
}
}
throw new Error('no video element is available');
};
const releaseVideoElement = tileId => {
for (let i = 0; i < 25; i += 1) {
if (indexMap[i] === tileId) {
delete indexMap[i];
return;
}
}
};
const observer = {
videoTileDidUpdate: tileState => {
if (!tileState.boundAttendeeId || tileState.localTile || tileState.isContent) {
return;
}
meetingSession.audioVideo.bindVideoElement(
tileState.tileId,
acquireVideoElement(tileState.tileId)
);
},
videoTileWasRemoved: tileId => {
releaseVideoElement(tileId);
},
};
meetingSession.audioVideo.addObserver(observer);
Use case 17. Add an observer to know all the remote video sources when changed.
const observer = {
remoteVideoSourcesDidChange: videoSources => {
videoSources.forEach(videoSource => {
const { attendee } = videoSource;
console.log(
`An attendee (${attendee.attendeeId} ${attendee.externalUserId}) is sending video`
);
});
},
};
meetingSession.audioVideo.addObserver(observer);
You can also call below method to know all the remote video sources:
Note: getRemoteVideoSources
method is different from getAllRemoteVideoTiles
,
getRemoteVideoSources
returns all the remote video sources that are available to be viewed,
while getAllRemoteVideoTiles
returns the ones that are actually being seen.
const videoSources = meetingSession.audioVideo.getRemoteVideoSources();
videoSources.forEach(videoSource => {
const { attendee } = videoSource;
console.log(`An attendee (${attendee.attendeeId} ${attendee.externalUserId}) is sending video`);
});
Screen and content share
Note: When you or other attendees share content (a screen capture, a video file, or any other MediaStream object),
the content attendee (attendee-id#content) joins the session and shares content as if a regular attendee shares a video.
For example, your attendee ID is "my-id". When you call meetingSession.audioVideo.startContentShare
,
the content attendee "my-id#content" will join the session and share your content.
Use case 18. Start sharing your screen.
import { DefaultModality } from 'amazon-chime-sdk-js';
const observer = {
videoTileDidUpdate: tileState => {
if (!tileState.boundAttendeeId || !tileState.isContent) {
return;
}
const yourAttendeeId = meetingSession.configuration.credentials.attendeeId;
const boundAttendeeId = tileState.boundAttendeeId;
const baseAttendeeId = new DefaultModality(boundAttendeeId).base();
if (baseAttendeeId === yourAttendeeId) {
console.log('You called startContentShareFromScreenCapture');
}
},
contentShareDidStart: () => {
console.log('Screen share started');
},
contentShareDidStop: () => {
console.log('Screen share stopped');
},
};
meetingSession.audioVideo.addContentShareObserver(observer);
meetingSession.audioVideo.addObserver(observer);
const contentShareStream = await meetingSession.audioVideo.startContentShareFromScreenCapture();
If you want to display the content share stream for the sharer, you can bind the returned content share stream to a
video element using connectVideoStreamToVideoElement
from DefaultVideoTile.
DefaultVideoTile.connectVideoStreamToVideoElement(contentShareStream, videoElement, false);
Use case 19. Start sharing your screen in an environment that does not support a screen picker dialog. e.g. Electron
const sourceId = ;
await meetingSession.audioVideo.startContentShareFromScreenCapture(sourceId);
Use case 20. Start streaming your video file from an <input>
element of type file
.
const videoElement = ;
const inputElement = ;
inputElement.addEventListener('change', async () => {
const file = inputElement.files[0];
const url = URL.createObjectURL(file);
videoElement.src = url;
await videoElement.play();
const mediaStream = videoElement.captureStream();
await meetingSession.audioVideo.startContentShare(mediaStream);
inputElement.value = '';
});
Use case 21. Stop sharing your screen or content.
const observer = {
contentShareDidStop: () => {
console.log('Content share stopped');
},
};
meetingSession.audioVideo.addContentShareObserver(observer);
await meetingSession.audioVideo.stopContentShare();
Use case 22. View up to 2 attendee content or screens. Chime SDK allows 2 simultaneous content shares per meeting.
import { DefaultModality } from 'amazon-chime-sdk-js';
const videoElementStack = [
];
const tileMap = {};
const observer = {
videoTileDidUpdate: tileState => {
if (!tileState.boundAttendeeId || !tileState.isContent) {
return;
}
const yourAttendeeId = meetingSession.configuration.credentials.attendeeId;
const boundAttendeeId = tileState.boundAttendeeId;
const baseAttendeeId = new DefaultModality(boundAttendeeId).base();
if (baseAttendeeId !== yourAttendeeId) {
console.log(`${baseAttendeeId} is sharing screen now`);
const videoElement = tileMap[tileState.tileId] || videoElementStack.pop();
if (videoElement) {
tileMap[tileState.tileId] = videoElement;
meetingSession.audioVideo.bindVideoElement(tileState.tileId, videoElement);
} else {
console.log('No video element is available');
}
}
},
videoTileWasRemoved: tileId => {
const videoElement = tileMap[tileId];
if (videoElement) {
videoElementStack.push(videoElement);
delete tileMap[tileId];
}
},
};
meetingSession.audioVideo.addObserver(observer);
Attendees
Use case 23. Subscribe to attendee presence changes. When an attendee joins or leaves a session,
the callback receives presentAttendeeId
and present
(a boolean).
const attendeePresenceSet = new Set();
const callback = (presentAttendeeId, present) => {
console.log(`Attendee ID: ${presentAttendeeId} Present: ${present}`);
if (present) {
attendeePresenceSet.add(presentAttendeeId);
} else {
attendeePresenceSet.delete(presentAttendeeId);
}
};
meetingSession.audioVideo.realtimeSubscribeToAttendeeIdPresence(callback);
Use case 24. Create a simple roster by subscribing to attendee presence and volume changes.
import { DefaultModality } from 'amazon-chime-sdk-js';
const roster = {};
meetingSession.audioVideo.realtimeSubscribeToAttendeeIdPresence((presentAttendeeId, present) => {
if (!present) {
delete roster[presentAttendeeId];
return;
}
meetingSession.audioVideo.realtimeSubscribeToVolumeIndicator(
presentAttendeeId,
(attendeeId, volume, muted, signalStrength) => {
const baseAttendeeId = new DefaultModality(attendeeId).base();
if (baseAttendeeId !== attendeeId) {
return;
}
if (roster.hasOwnProperty(attendeeId)) {
roster[attendeeId].volume = volume;
roster[attendeeId].muted = muted;
roster[attendeeId].signalStrength = signalStrength;
} else {
roster[attendeeId] = {
attendeeId,
volume,
muted,
signalStrength,
};
}
}
);
});
Monitoring and alerts
Use case 25. Add an observer to receive WebRTC metrics processed by Chime SDK such as bitrate, packet loss, and bandwidth. See AudioVideoObserver
for more available metrics.
const observer = {
metricsDidReceive: clientMetricReport => {
const metricReport = clientMetricReport.getObservableMetrics();
const {
videoPacketSentPerSecond,
videoUpstreamBitrate,
availableOutgoingBitrate,
availableIncomingBitrate,
audioSpeakerDelayMs,
} = metricReport;
console.log(
`Sending video bitrate in kilobits per second: ${
videoUpstreamBitrate / 1000
} and sending packets per second: ${videoPacketSentPerSecond}`
);
console.log(
`Sending bandwidth is ${availableOutgoingBitrate / 1000}, and receiving bandwidth is ${
availableIncomingBitrate / 1000
}`
);
console.log(`Audio speaker delay is ${audioSpeakerDelayMs}`);
},
};
meetingSession.audioVideo.addObserver(observer);
Use case 26. Add an observer to receive alerts. You can use these alerts to notify users of connection problems.
const observer = {
connectionDidBecomePoor: () => {
console.log('Your connection is poor');
},
connectionDidSuggestStopVideo: () => {
console.log('Recommend turning off your video');
},
videoSendDidBecomeUnavailable: () => {
console.log('You cannot share your video');
},
videoAvailabilityDidChange: videoAvailability => {
if (videoAvailability.canStartLocalVideo) {
console.log('You can share your video');
} else {
console.log('You cannot share your video');
}
},
};
meetingSession.audioVideo.addObserver(observer);
Stopping a session
Use case 27. Leave a session.
import { MeetingSessionStatusCode } from 'amazon-chime-sdk-js';
const observer = {
audioVideoDidStop: sessionStatus => {
const sessionStatusCode = sessionStatus.statusCode();
if (sessionStatusCode === MeetingSessionStatusCode.Left) {
console.log('You left the session');
} else {
console.log('Stopped with a session status code: ', sessionStatusCode);
}
},
};
meetingSession.audioVideo.addObserver(observer);
meetingSession.audioVideo.stop();
Use case 28. Add an observer to get notified when a session has ended.
import { MeetingSessionStatusCode } from 'amazon-chime-sdk-js';
const observer = {
audioVideoDidStop: sessionStatus => {
const sessionStatusCode = sessionStatus.statusCode();
if (sessionStatusCode === MeetingSessionStatusCode.MeetingEnded) {
console.log('The session has ended');
} else {
console.log('Stopped with a session status code: ', sessionStatusCode);
}
},
};
meetingSession.audioVideo.addObserver(observer);
Meeting readiness checker
Use case 29. Initialize the meeting readiness checker.
import { DefaultMeetingReadinessChecker } from 'amazon-chime-sdk-js';
const meetingReadinessChecker = new DefaultMeetingReadinessChecker(logger, meetingSession);
Use case 30. Use the meeting readiness checker to perform local checks.
import { CheckAudioInputFeedback } from 'amazon-chime-sdk-js';
const audioInputDeviceInfo = ;
const audioInputFeedback = await meetingReadinessChecker.checkAudioInput(audioInputDeviceInfo.deviceId);
switch (audioInputFeedback) {
case CheckAudioInputFeedback.Succeeded:
console.log('Succeeded');
break;
case CheckAudioInputFeedback.Failed:
console.log('Failed');
break;
case CheckAudioInputFeedback.PermissionDenied:
console.log('Permission denied');
break;
}
Use case 31. Use the meeting readiness checker to perform end-to-end checks, e.g. audio, video, and content share.
import {
CheckAudioConnectivityFeedback,
CheckContentShareConnectivityFeedback,
CheckVideoConnectivityFeedback
} from 'amazon-chime-sdk-js';
const audioDeviceInfo = ;
const audioFeedback = await meetingReadinessChecker.checkAudioConnectivity(audioDeviceInfo.deviceId);
console.log(`Feedback result: ${CheckAudioConnectivityFeedback[audioFeedback]}`);
const videoInputInfo = ;
const videoFeedback = await meetingReadinessChecker.checkVideoConnectivity(videoInputInfo.deviceId);
console.log(`Feedback result: ${CheckVideoConnectivityFeedback[videoFeedback]}`);
const contentShareFeedback = await meetingReadinessChecker.checkContentShareConnectivity();
console.log(`Feedback result: ${CheckContentShareConnectivityFeedback[contentShareFeedback]}`);
Use case 32. Use the meeting readiness checker to perform network checks, e.g. TCP and UDP.
import {
CheckNetworkUDPConnectivityFeedback,
CheckNetworkTCPConnectivityFeedback,
} from 'amazon-chime-sdk-js';
const networkUDPFeedback = await meetingReadinessChecker.checkNetworkUDPConnectivity();
console.log(`Feedback result: ${CheckNetworkUDPConnectivityFeedback[networkUDPFeedback]}`);
const networkTCPFeedback = await meetingReadinessChecker.checkNetworkTCPConnectivity();
console.log(`Feedback result: ${CheckNetworkTCPConnectivityFeedback[networkTCPFeedback]}`);
Selecting an audio profile
Use case 32. Set the audio quality of the main audio input to optimize for speech or music:
Use the following setting to optimize the audio bitrate of the main audio input for fullband speech with a mono channel:
meetingSession.audioVideo.setAudioProfile(AudioProfile.fullbandSpeechMono());
Use case 33. Set the audio quality of content share audio to optimize for speech or music:
Use the following setting to optimize the audio bitrate of content share audio for fullband music with a mono channel:
meetingSession.audioVideo.setContentAudioProfile(AudioProfile.fullbandMusicMono());
Use case 34. Sending and receiving stereo audio
You can send an audio stream with stereo channels either as content or through the main audio input.
Use the following setting to optimize the main audio input and output for an audio stream with stereo channels:
meetingSession.audioVideo.setAudioProfile(AudioProfile.fullbandMusicStereo());
Use the following setting to optimize the content share audio for an audio stream with stereo channels:
meetingSession.audioVideo.setContentAudioProfile(AudioProfile.fullbandMusicStereo());
Use case 35. Redundant Audio
Starting from version 3.18.2, the SDK starts sending redundant audio data to our servers on detecting packet loss
to help reduce its effect on audio quality. Redundant audio packets are only sent out for packets containing active
audio, ie, speech or music. This may increase the bandwidth consumed by audio to up to 3 times the normal amount
depending on the amount of packet loss detected. The SDK will automatically stop sending redundant data if it hasn't
detected any packet loss for 5 minutes.
This feature requires blob:
to be in your content security policy under the worker-src
directive.
Without this, we will not be able to send out redundant audio data.
This feature is not supported on Firefox at the moment.
We were able to successfully send redundant audio from safari 16.1 onwards. 15.6.1 advertises support as well but is untested.
Chrome advertises support for redundant audio from version M96.
To disable this feature for attendee audio, you can use the following:
meetingSession.audioVideo.setAudioProfile(new AudioProfile(null, false));
If using bitrate optimization and you want to disable audio redundancy you can use the below line.
In the example below, we only use fullbandSpeechMono but you can use fullbandMusicMono and fullbandMusicStereo
depending on your use case.
meetingSession.audioVideo.setAudioProfile(AudioProfile.fullbandSpeechMono(false));
To disable this feature for content share audio, you can use any one of the following:
meetingSession.audioVideo.setContentAudioProfile(new AudioProfile(null, false));
If using bitrate optimization and you want to disable audio redundancy you can use the below line.
In the example below, we only use fullbandSpeechMono but you can use fullbandMusicMono and fullbandMusicStereo
depending on your use case.
meetingSession.audioVideo.setContentAudioProfile(AudioProfile.fullbandSpeechMono(false));
While there is an option to disable the feature, we recommend keeping it enabled for improved audio quality.
One possible reason to disable it might be if your customers have very strict bandwidth limitations.
Starting a messaging session
Use case 36. Setup an observer to receive events: connecting, start, stop and receive message; and
start a messaging session.
Note: You can remove an observer by calling messagingSession.removeObserver(observer)
.
In a component-based architecture (such as React, Vue, and Angular), you may need to add an observer
when a component is mounted, and remove it when unmounted.
const observer = {
messagingSessionDidStart: () => {
console.log('Session started');
},
messagingSessionDidStartConnecting: reconnecting => {
if (reconnecting) {
console.log('Start reconnecting');
} else {
console.log('Start connecting');
}
},
messagingSessionDidStop: event => {
console.log(`Closed: ${event.code} ${event.reason}`);
},
messagingSessionDidReceiveMessage: message => {
console.log(`Receive message type ${message.type}`);
},
};
messagingSession.addObserver(observer);
await messagingSession.start();
Providing application metadata
Amazon Chime SDK for JavaScript allows builders to provide application metadata in the meeting session configuration. This field is optional. Amazon Chime uses application metadata to analyze meeting health trends or identify common failures to improve your meeting experience.
⚠️ Do not pass any Personal Identifiable Information (PII).
Use case 37. Provide application metadata to the meeting session configuration.
import { MeetingSessionConfiguration, ApplicationMetadata } from 'amazon-chime-sdk-js';
const createMeetingResponse =
const createAttendeeResponse =
const meetingSessionConfiguration = new MeetingSessionConfiguration(
createMeetingResponse,
createAttendeeResponse
);
meetingSessionConfiguration.applicationMetadata = ApplicationMetadata.create({
appName: 'AppName',
appVersion: '1.0.0'
});
Accepted application metadata constraints
appName: string;
appVersion: string;
Notice
The use of Amazon Voice Focus. background blur, and background replacement via this SDK involves the downloading and execution of code at runtime by end users.
The use of Amazon Voice Focus. background blur, and background replacement runtime code is subject to additional notices. See this Amazon Voice Focus NOTICES file, background blur and background replacement NOTICES file, and background blur 2.0 and background replacement 2.0 NOTICES file for details. You agree to make these additional notices available to all end users who use Amazon Voice Focus, background blur and background replacement, background blur 2.0 and background replacement 2.0, runtime code via this SDK.
The browser demo applications in the demos directory use TensorFlow.js and pre-trained TensorFlow.js models for image segmentation. Use of these third party models involves downloading and execution of code at runtime from jsDelivr by end user browsers. For the jsDelivr Acceptable Use Policy, please visit this link.
The use of TensorFlow runtime code referenced above may be subject to additional license requirements. See the licenses page for TensorFlow.js here and TensorFlow.js models here for details.
You and your end users are responsible for all Content (including any images) uploaded for use with background replacement, and must ensure that such Content does not violate the law, infringe or misappropriate the rights of any third party, or otherwise violate a material term of your agreement with Amazon (including the documentation, the AWS Service Terms, or the Acceptable Use Policy).
Live transcription using the Amazon Chime SDK for JavaScript is powered by Amazon Transcribe. Use of Amazon Transcribe is subject to the AWS Service Terms, including the terms specific to the AWS Machine Learning and Artificial Intelligence Services. Standard charges for Amazon Transcribe and Amazon Transcribe Medical will apply.
You and your end users understand that recording Amazon Chime SDK meetings may be subject to laws or regulations regarding the recording of electronic communications. It is your and your end users’ responsibility to comply with all applicable laws regarding the recordings, including properly notifying all participants in a recorded session, or communication that the session or communication is being recorded, and obtain their consent.
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.