{"id":19337329,"url":"https://github.com/infobip/infobip-rtc-js","last_synced_at":"2026-02-06T05:04:45.043Z","repository":{"id":131805429,"uuid":"603202383","full_name":"infobip/infobip-rtc-js","owner":"infobip","description":null,"archived":false,"fork":false,"pushed_at":"2025-11-04T14:44:09.000Z","size":322,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-11-04T15:12:39.948Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/infobip.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-02-17T20:51:32.000Z","updated_at":"2025-02-07T11:10:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"3dd13c39-3dd7-4c2f-9ebf-bd47ed51edee","html_url":"https://github.com/infobip/infobip-rtc-js","commit_stats":null,"previous_names":[],"tags_count":128,"template":false,"template_full_name":null,"purl":"pkg:github/infobip/infobip-rtc-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-rtc-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-rtc-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-rtc-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-rtc-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/infobip","download_url":"https://codeload.github.com/infobip/infobip-rtc-js/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infobip%2Finfobip-rtc-js/sbom","scorecard":{"id":488200,"data":{"date":"2025-08-11","repo":{"name":"github.com/infobip/infobip-rtc-js","commit":"3438623e4237e90761133e5a760bb41774772336"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.6,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}}]},"last_synced_at":"2025-08-19T18:21:16.152Z","repository_id":131805429,"created_at":"2025-08-19T18:21:16.152Z","updated_at":"2025-08-19T18:21:16.152Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29151664,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T02:39:25.012Z","status":"ssl_error","status_checked_at":"2026-02-06T02:37:22.784Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T03:14:05.797Z","updated_at":"2026-02-06T05:04:45.024Z","avatar_url":"https://github.com/infobip.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"### Introduction\n\nInfobip RTC is a JavaScript SDK which enables you to take advantage of Infobip platform,\ngiving you the ability to enrich your web applications with real-time communications in minimum time,\nwhile you focus on your application's user experience and business logic.\nWe currently support WebRTC calls between two web or app users, phone calls between a web or app user and an actual \nphone, Viber calls, calls to the Infobip Conversations platform, as well as room calls - calls with multiple \nparticipants.\n\nHere you will find an overview, and a quick guide on how to connect to Infobip platform.\nThere is also in-depth reference documentation available.\n\n### Prerequisites\n\nInfobip RTC SDK requires ES6. Also secure connection over HTTPS is required, except for localhost address.\n\n### First-time setup\n\nIn order to use Infobip RTC, you need to have Web and In-app Calls enabled on your account and that's it!\nYou are ready to make Web and In-app calls. To learn how to enable them\nsee [the documentation](https://www.infobip.com/docs/voice-and-video/webrtc#set-up-web-and-in-app-calls).\n\n### Getting SDK\n\nThere are a few ways in which you can get our SDK.\nWe publish it as an NPM package and as a standalone JS file hosted on a CDN.\n\nIf you want to add it as an NPM dependency, run the following:\n\n```bash\nnpm install infobip-rtc --save\n```\n\nAlternatively, you can include our distribution file directly in your JavaScript from our CDN:\n\n```html\n\u003cscript src=\"//rtc.cdn.infobip.com/2.2.7/infobip.rtc.js\"\u003e\u003c/script\u003e\n```\n\nThe latest tag is also available:\n\n```html\n\u003cscript src=\"//rtc.cdn.infobip.com/2/latest/infobip.rtc.js\"\u003e\u003c/script\u003e\n```\n\n### Authentication\n\nSince Infobip RTC is an SDK, it means you develop your own application, and you only use Infobip RTC as a dependency.\nYour application has your own users, which we will call subscribers throughout this guide.\nSo, in order to use Infobip RTC, you need to register your subscribers on our platform.\nThe credentials your subscribers use to connect to your application are irrelevant to Infobip.\nWe only need the identity they will use to present themselves. When we have the subscriber's identity,\nwe can generate a token assigned to that specific subscriber.\nWith that token, your subscribers can connect to our platform (using Infobip RTC SDK).\n\nTo generate these tokens for your subscribers, you need to call our\n[`/webrtc/1/token`](https://dev.infobip.com/webrtc/generate-token) HTTP API method using proper parameters.\nThere you authenticate yourself against Infobip platform, so we can relate the subscriber's token to you.\nTypically, generating a token occurs after your subscribers are authenticated inside your application.\nYou will receive the token in a response that you will use to instantiate\n[`InfobipRTC`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC) client in your web application.\n\n### Infobip RTC Client\n\nAfter you have received a token via HTTP API,\nyou are ready to create an instance of the [`InfobipRTC`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC) \nclient. You can do that using the [`createInfobipRtc`](https://github.com/infobip/infobip-rtc-js/wiki/Creating-InfobipRTC-Client)\nglobal function.\n\n```javascript\nlet token = obtainToken(); // here you call '/webrtc/1/token'\nlet options = {debug: true}\nlet infobipRTC = createInfobipRtc(token, options);\n```\n\nNote that this doesn't actually connect to Infobip platform,\nit just creates a new instance of [`InfobipRTC`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC).\nConnection is made via the [`connect`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#connect) method.\nBefore connecting, it is useful to set up event handlers, so you can perform something when the connection is set up,\nwhen the connection is lost, etc.\nEvents are set up via [`on`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#on) method:\n\n```javascript\ninfobipRTC.on('connected', function (event) {\n    console.log('Connected with identity: ' + event.identity);\n});\ninfobipRTC.on('disconnected', function (event) {\n    console.log('Disconnected!');\n});\n```\n\nNow you are ready to connect:\n\n```javascript\ninfobipRTC.connect();\n```\n\n### Making a WebRTC call\n\nYou can call another WebRTC endpoint if you know their identity.\nIt is done via the [`callWebrtc`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#call-webrtc) method:\n\n```javascript\nlet webrtcCall = infobipRTC.callWebrtc('Alice');\n```\n\nOr if you want to initiate a call with video:\n\n```javascript\nlet webrtcCall = infobipRTC.callWebrtc('Alice', WebrtcCallOptions.builder().setVideo(true).build());\n```\n\nAs you can see, the [`callWebrtc`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#call-webrtc) method\nreturns an instance of [`WebrtcCall`](https://github.com/infobip/infobip-rtc-js/wiki/WebrtcCall) as the result.\nWith it, you can track the status of your call and respond to events. Similar to the client,\nyou can set up event handlers, so you can do something when the called subscriber answers the call,\nrejects it, the call is ended, etc. You set up event handlers with the following code:\n\n```javascript\nwebrtcCall.on(CallsApiEvents.RINGING, function (event) {\n    console.log('Call is ringing on Alice\\'s device!');\n});\n\nwebrtcCall.on(CallsApiEvents.ESTABLISHED, function (event) {\n    console.log('Alice answered call!');\n});\n\nwebrtcCall.on(CallsApiEvents.HANGUP, function (event) {\n    console.log('Call is done! Status: ' + JSON.stringify(event.errorCode));\n});\n\nwebrtcCall.on(CallsApiEvents.ERROR, function (event) {\n    console.log('Oops, something went very wrong! Message: ' + JSON.stringify(event.errorCode));\n});\n```\n\nThe most important part of the call is definitely the media that travels between the subscribers.\nIt can be handled in an `ESTABLISHED` event where you have the remote media which can be streamed into your HTML page.\nThis is an example of how you can use it:\n\n```javascript\n\u003caudio id=\"remoteAudio\" autoplay/\u003e\n\nwebrtcCall.on(CallsApiEvents.ESTABLISHED, function (event) {\n    console.log('Alice answered call!');\n    document.getElementById('remoteAudio').srcObject = event.stream;\n});\n```\n\n\u003e **Note**: When using JS SDK in Safari, please note that having `autoplay` attribute for `\u003cvideo\u003e` tag isn't enough for iOS devices. Video elements that include this attribute play automatically only if those elements also include the `playsinline` attribute.\n\u003e You can refer to the [autoplay video policy for Safari](https://developer.apple.com/documentation/webkit/delivering_video_content_for_safari/#3030251) for more information.\n\nAt any time during the WebRTC call, users can add or remove their camera videos. In order to handle the video media, you\nshould set the event handlers for `CAMERA_VIDEO_ADDED`, `CAMERA_VIDEO_UPDATED` and `CAMERA_VIDEO_REMOVED` events.\n\n```javascript\nwebrtcCall.on(CallsApiEvents.CAMERA_VIDEO_ADDED, function (event) {\n    $('#localVideo').srcObject = event.stream;\n});\n\nwebrtcCall.on(CallsApiEvents.CAMERA_VIDEO_UPDATED, function (event) {\n    $('#localVideo').srcObject = event.stream;\n});\n\nwebrtcCall.on(CallsApiEvents.CAMERA_VIDEO_REMOVED, function (event) {\n    $('#localVideo').srcObject = null;\n});\n```\n\nThen, you can turn on the camera using the \n[`cameraVideo`](https://github.com/infobip/infobip-rtc-js/wiki/WebrtcCall#camera-video) method.\n\n```javascript\nwebrtcCall.cameraVideo(true);\n```\n\nUsers can also start or stop sharing their screen. As was the case with camera video, first you should add handlers for\nthe following events: `SCREEN_SHARE_ADDED` and `SCREEN_SHARE_REMOVED`:\n\n```javascript\nwebrtcCall.on(CallsApiEvents.SCREEN_SHARE_ADDED, function (event) {\n    $('#localScreenShare').srcObject = event.stream;\n});\n\nwebrtcCall.on(CallsApiEvents.SCREEN_SHARE_REMOVED, function (event) {\n    $('#localScreenShare').srcObject = null;\n});\n```\n\nThen, you can use the [`screenShare`](https://github.com/infobip/infobip-rtc-js/wiki/WebrtcCall#screen-share) method to \nstart or stop sharing your screen.\n\n```javascript\nwebrtcCall.screenShare(true);\n```\n\nIn order to handle camera and screen share media from the other side, you should add event handlers for \n`REMOTE_CAMERA_VIDEO_ADDED`, `REMOTE_CAMERA_VIDEO_REMOVED`, `REMOTE_SCREEN_SHARE_ADDED` and \n`REMOTE_SCREEN_SHARE_REMOVED` events.\n\n```javascript\nwebrtcCall.on(CallsApiEvents.REMOTE_CAMERA_VIDEO_ADDED, function (event) {\n    $('#remoteCameraVideo').srcObject = event.stream;\n});\n\nwebrtcCall.on(CallsApiEvents.REMOTE_CAMERA_VIDEO_REMOVED, function (event) {\n    $('#remoteCameraVideo').srcObject = null;\n});\n\nwebrtcCall.on(CallsApiEvents.REMOTE_SCREEN_SHARE_ADDED, function (event) {\n    $('#remoteScreenShare').srcObject = event.stream;\n});\n\nwebrtcCall.on(CallsApiEvents.REMOTE_SCREEN_SHARE_REMOVED, function (event) {\n    $('#remoteScreenShare').srcObject = null;\n});\n```\n\nBesides adding and removing camera and share screen, there are a few more things that you can do with the actual call.\nOne of them, of course, is to hang up.\nThat can be done via the [`hangup`](https://github.com/infobip/infobip-rtc-js/wiki/WebrtcCall#hangup) method on the call,\nand after that, both parties will receive the `HANGUP` event upon hang up completion.\n\n```javascript\nwebrtcCall.hangup();\n```\n\nYou can simulate digit press during the call by sending DTMF codes (Dual-Tone Multi-Frequency).\nThis is achieved via [`sendDTMF`](https://github.com/infobip/infobip-rtc-js/wiki/Call#send-dtmf) method.\nValid DTMF codes are digits from `0-9`, `*` and `#`.\n\n```javascript\nwebrtcCall.sendDTMF('*');\n```\n\nDuring the call, you can also mute (and unmute) your audio:\n\n```javascript\nwebrtcCall.mute(true);\n```\n\nTo check if the audio is muted, call the\n[`muted`](https://github.com/infobip/infobip-rtc-js/wiki/Call#muted) method in the following way:\n\n```javascript\nlet audioMuted = webrtcCall.muted();\n```\n\nAlso, you can check the [`call status`](https://github.com/infobip/infobip-rtc-js/wiki/CallStatus):\n\n```javascript\nlet status = webrtcCall.status();\n```\n\nAlso, you can check information such as [`duration`](https://github.com/infobip/infobip-rtc-js/wiki/Call#duration),\n[`start time`](https://github.com/infobip/infobip-rtc-js/wiki/Call#start-time),\n[`establish time`](https://github.com/infobip/infobip-rtc-js/wiki/Call#establish-time) and\n[`end time`](https://github.com/infobip/infobip-rtc-js/wiki/Call#end-time) by calling these methods:\n\n```javascript\nlet duration = webrtcCall.duration();\nlet startTime = webrtcCall.startTime();\nlet establishTime = webrtcCall.establishTime();\nlet endTime = webrtcCall.endTime();\n```\n\n### Receiving a call\n\nBesides making outgoing calls, you can also receive incoming calls.\nIn order to do that, you need to register the `incoming-webrtc-call` event handler of\n[`InfobipRTC`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC) client.\nThat is where you define the behavior of the incoming call.\nOne of the most common things to do is to show Answer and Reject options on the UI.\nFor the purpose of this guide, let's look at an example that answers the incoming call as soon as it arrives:\n\n```javascript\ninfobipRTC.on('incoming-webrtc-call', function (incomingWebrtcCallEvent) {\n    const incomingCall = incomingWebrtcCallEvent.incomingCall;\n    console.log('Received incoming call from: ' + incomingCall.source().identifier);\n\n    incomingCall.on(CallsApiEvents.ESTABLISHED, function () {\n    });\n    \n    incomingCall.on(CallsApiEvents.HANGUP, function () {\n    });\n\n    incomingCall.accept(); // or incomingCall.decline();\n});\n```\n\n### Calling phone number\n\nIt is similar to calling the regular WebRTC user, you just use the\n[`callPhone`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#call-phone) method instead of\n[`callWebrtc`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#call-webrtc).\nThis method accepts an optional second parameter, where you define the `from` parameter.\nIts value will be displayed on the calling phone device as the Caller ID.\nThe result of the [`callPhone`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#call-phone) is the\n[`PhoneCall`](https://github.com/infobip/infobip-rtc-js/wiki/PhoneCall) with which you can do a few things such as\nmuting the call, hanging it up, checking its start time, answer time, duration and more. See reference \n[documentation](https://github.com/infobip/infobip-rtc-js/wiki/PhoneCall)\nfor a full list of available actions.\n\n* Example of calling phone number with `from` defined:\n\n```javascript\nlet phoneCall = infobipRTC.callPhone('41793026727', PhoneCallOptions.builder().setFrom('33712345678').build());\n```\n\n* Example of calling phone number without `from` defined:\n\n```javascript\nlet phoneCall = infobipRTC.callPhone('41793026727');\n```\n\n### Calling Viber\n\nCalling Viber is very similar to calling a phone number, except the call will arrive to the destination through\nthe Viber application. In order to call Viber, you can use the [`callViber`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#call-viber) method,\nwhich returns an instance of [`ViberCall`](https://github.com/infobip/infobip-rtc-js/wiki/ViberCall)\n\n```javascript\nlet viberCall = infobipRTC.callViber('41793026727', '33712345678');\n```\n\nPlease note that unlike in the [`callPhone`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#call-phone) method,\n`from` is required and passed in as a second parameter to the [`callViber`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#call-viber) method.\n\n### Room call\n\nRoom calls are types of calls that can have up to 15 participants.\nThe room call will start as soon as at least one participant joins.\n\nJoining the room is done via the\n[`joinRoom`](https://github.com/infobip/infobip-rtc-js/wiki/InfobipRTC#join-room) method:\n\n```javascript\nlet roomCall = infobipRTC.joinRoom('room-demo');\n```\n\nOr if you want to join the room with your video:\n\n```javascript\nlet roomCall = infobipRTC.joinRoom('room-demo', RoomCallOptions.builder().setVideo(true).build());\n```\n\nAs you can see, that method returns an instance of\n[`RoomCall`](https://github.com/infobip/infobip-rtc-js/wiki/RoomCall) as the result.\nWith it, you can track the status of your room call,\ndo some actions (mute, share the screen, turn your camera on) and respond to events.\n\nAfter the user successfully joined the room, the `ROOM_JOINED` event will be emitted.\nIt contains an id of the joined room, its name, participants and stream. You should implement an event handler for it, \nso that the user could be notified about joining the room, and the other participants might be shown to the user.\n\nHere is an example of how to\nhandle [`room events`](https://github.com/infobip/infobip-rtc-js/wiki/RoomCall#on).\n\nLet's assume that we have an audio HTML element with the id `roomAudio` and video HTML elements with the ids\n`localVideo` and `localScreenShare`.\n\n```javascript\nroomCall.on(CallsApiEvents.ROOM_JOINED, function (event) {\n    $('#remoteAudio').srcObject = event.stream;\n    var participants = event.participants.map(participant =\u003e participant.endpoint.identifier).join(\", \");\n    console.log(`You have joined the room with ${event.participants.length} more participants: ${participants}`);\n});\n\nroomCall.on(CallsApiEvents.ROOM_LEFT, function (event) {\n    console.log(`You have left the room with error code: ${event.errorCode.name}.`);\n});\n\nroomCall.on(CallsApiEvents.ERROR, function (event) {\n    console.log(`Error! ${event.errorCode.name}`);\n});\n\nroomCall.on(CallsApiEvents.PARTICIPANT_JOINED, function (event) {\n    console.log(`${event.participant.endpoint.identifier} joined the room call.`);\n});\n\nroomCall.on(CallsApiEvents.PARTICIPANT_LEFT, function (event) {\n    console.log(`${event.participant.endpoint.identifier} left the room call.`);\n});\n\nroomCall.on(CallsApiEvents.PARTICIPANT_MUTED, function (event) {\n    console.log(`${event.participant.endpoint.identifier} muted.`);\n});\n\nroomCall.on(CallsApiEvents.PARTICIPANT_UNMUTED, function (event) {\n    console.log(`${event.participant.endpoint.identifier} unmuted.`);\n});\n\nroomCall.on(CallsApiEvents.CAMERA_VIDEO_ADDED, function (event) {\n    $('#localVideo').srcObject = event.stream;\n});\n\nroomCall.on(CallsApiEvents.CAMERA_VIDEO_UPDATED, function (event) {\n    $('#localVideo').srcObject = event.stream;\n});\n\nroomCall.on(CallsApiEvents.CAMERA_VIDEO_REMOVED, function (event) {\n    $('#localVideo').srcObject = null;\n});\n\nroomCall.on(CallsApiEvents.SCREEN_SHARE_ADDED, function (event) {\n    $('#localScreenShare').srcObject = event.stream;\n});\n\nroomCall.on(CallsApiEvents.SCREEN_SHARE_REMOVED, function (event) {\n    $('#localScreenShare').srcObject = null;\n});\n```\n\nThe next two events are fired when another participant adds or removes the video.\nYou should implement these event handlers in order to add and/or remove an HTML video element with a media stream.\n\n```javascript\nroomCall.on(CallsApiEvents.PARTICIPANT_CAMERA_VIDEO_ADDED, function (event) {\n    // add a new HTML video element with id remoteVideo-event.participant.endpoint.identifier\n    $('#remoteVideo-' + event.participant.endpoint.identifier).srcObject = event.stream;\n});\n\nroomCall.on(CallsApiEvents.PARTICIPANT_CAMERA_VIDEO_REMOVED, function (event) {\n    console.log(`Participant ${event.participant.endpoint.identifer} removed their camera`)\n    // remove the HTML video element with id remoteVideo-event.participant.endpoint.identifier\n});\n```\n\nThe next two events are fired when another participant starts or stops sharing screen.\nYou should implement these event handlers in order to add and/or remove an HTML video element with a media stream.\n\n```javascript\nroomCall.on(CallsApiEvents.PARTICIPANT_SCREEN_SHARE_ADDED, function (event) {\n    // add a new HTML video element with id remoteScreenShare-event.participant.endpoint.identifier\n    $('#remoteScreenShare-' + event.participant.endpoint.identifier).srcObject = event.stream;\n});\n\nroomCall.on(CallsApiEvents.PARTICIPANT_SCREEN_SHARE_REMOVED, function (event) {\n    // remove the HTML video element with id remoteScreenShare-event.participant.endpoint.identifier\n});\n```\n\nWhen event handlers are set up and the room call is established,\nthere are a few things that you can do with it.\n\nOne of them, of course, is to leave the room. That can be done via the\n[`leave`](https://github.com/infobip/infobip-rtc-js/wiki/RoomCall#leave) method at the room call.\nOther participants will receive the `PARTICIPANT_LEFT` event upon leave completion.\n\n```javascript\nroomCall.leave();\n```\n\nDuring the room call, you can also mute (and unmute) your audio, by calling the\n[`mute`](https://github.com/infobip/infobip-rtc-js/wiki/RoomCall#mute) method in the following way:\n\n```javascript\nroomCall.mute(true);\n```\n\nDuring the room call, you can start or stop sending your video, by calling the\n[`cameraVideo`](https://github.com/infobip/infobip-rtc-js/wiki/RoomCall#camera-video) method in the following way:\n\n```javascript\nroomCall.cameraVideo(true | false);\n```\n\nAfter this method, the `CAMERA_VIDEO_ADDED` or `CAMERA_VIDEO_REMOVED` event is fired.\n\nDuring the room call, you can start or stop sharing your screen, by calling the\n[`screenShare`](https://github.com/infobip/infobip-rtc-js/wiki/RoomCall#screen-share) method in the following way:\n\n```javascript\nroomCall.screenShare(true | false);\n```\n\nAfter this method, the `SCREEN_SHARE_ADDED` or `SCREEN_SHARE_REMOVED` event is fired.\n\n### Media Device information\n\nBeside getting the information about one's media devices anytime after the user is registered to Infobip's platfom,\nor during the call, you can get these infos using the static methods\nin [`RTCMediaDevice`](https://github.com/infobip/infobip-rtc-js/wiki/RTCMediaDevice).\n\n```javascript\nlet RTCMediaDevice = require('infobip-rtc');\n```\n\nFor audio input devices you can use the static\n[`RTCMediaDevice.getAudioInputDevices`](https://github.com/infobip/infobip-rtc-js/wiki/RTCMediaDevice#getAudioInputDevices)\nmethod:\n\n```javascript\nRTCMediaDevice.getAudioInputDevices().then(\n    mediaDevices =\u003e {\n        mediaDevices.forEach(device =\u003e {\n            console.log(device.label);\n        });\n    }\n);\n```\n\nFor audio output devices you can use the static\n[`RTCMediaDevice.getAudioOutputDevices`](https://github.com/infobip/infobip-rtc-js/wiki/RTCMediaDevice#getAudioOutputDevices)\nmethod:\n\n```javascript\nRTCMediaDevice.getAudioOutputDevices().then(\n    mediaDevices =\u003e {\n        mediaDevices.forEach(device =\u003e {\n            console.log(device.label);\n        });\n    }\n);\n```\n\nFor video input devices you can use the static\n[`RTCMediaDevice.getVideoInputDevices`](https://github.com/infobip/infobip-rtc-js/wiki/RTCMediaDevice#getVideoInputDevices)\nmethod:\n\n```javascript\nRTCMediaDevice.getVideoInputDevices().then(\n    mediaDevices =\u003e {\n        mediaDevices.forEach(device =\u003e {\n            console.log(device.label);\n        });\n    }\n);\n```\n\nAlso, you can get the stream of a specific device using the static\n[`RTCMediaDevice.getMediaStream`](https://github.com/infobip/infobip-rtc-js/wiki/RTCMediaDevice#getMediaStream) method:\n\n```javascript\nlet mediaDevices = await RTCMediaDevice.getAudioInputDevices();\nlet device = mediaDevices[0];\nlet stream = await RTCMediaDevice.getMediaStream(device.deviceId);\n$('#audio').srcObject = stream;\n//...\nRTCMediaDevice.closeMediaStream(stream);\n```\n\n### Browser Compatibility\n\nWe support up to 5 most recent versions of these browsers (unless otherwise indicated):\n\n|             |                                      | ![chrome](assets/icons/chrome.png) | ![firefox](assets/icons/firefox.png) | ![safari](assets/icons/safari.png) | ![edge](assets/icons/edge.png) | ![opera](assets/icons/opera.png) | ![explorer](assets/icons/explorer.png) | ![mi](assets/icons/mi.png) |\n|------------:|-------------------------------------:|:----------------------------------:|:------------------------------------:|:----------------------------------:|:------------------------------:|:--------------------------------:|:--------------------------------------:|:--------------------------:|\n|             |                                      |         **Google Chrome**          |         **Mozilla Firefox**          |            **Safari***             |      **Microsoft Edge****      |            **Opera**             |         **Internet Explorer**          |       **Mi Browser**       |\n| **Android** | ![android](assets/icons/android.png) |    ![yes](assets/icons/yes.png)    |     ![yes](assets/icons/yes.png)     |     ![no](assets/icons/no.png)     |  ![yes](assets/icons/yes.png)  |   ![yes](assets/icons/yes.png)   |       ![no](assets/icons/no.png)       | ![no](assets/icons/no.png) |\n|  **iOS***** |         ![ios](assets/icons/ios.png) |    ![yes](assets/icons/yes.png)    |     ![yes](assets/icons/yes.png)     |    ![yes](assets/icons/yes.png)    |  ![yes](assets/icons/yes.png)  |   ![yes](assets/icons/yes.png)   |       ![no](assets/icons/no.png)       | ![no](assets/icons/no.png) |\n|   **Linux** |     ![linux](assets/icons/linux.png) |    ![yes](assets/icons/yes.png)    |     ![yes](assets/icons/yes.png)     |     ![no](assets/icons/no.png)     |   ![no](assets/icons/no.png)   |   ![yes](assets/icons/yes.png)   |       ![no](assets/icons/no.png)       | ![no](assets/icons/no.png) |\n|   **macOS** |       ![macOs](assets/icons/mac.png) |    ![yes](assets/icons/yes.png)    |     ![yes](assets/icons/yes.png)     |    ![yes](assets/icons/yes.png)    |  ![yes](assets/icons/yes.png)  |   ![yes](assets/icons/yes.png)   |       ![no](assets/icons/no.png)       | ![no](assets/icons/no.png) |\n| **Windows** | ![windows](assets/icons/windows.png) |    ![yes](assets/icons/yes.png)    |     ![yes](assets/icons/yes.png)     |     ![no](assets/icons/no.png)     |  ![yes](assets/icons/yes.png)  |   ![yes](assets/icons/yes.png)   |       ![no](assets/icons/no.png)       | ![no](assets/icons/no.png) |\n\n\\* WebRTC support in Safari started with version 11.\n\n\\** WebRTC support in Microsoft Edge for Android, iOS and macOS started with Chromium-based version 79.\nInfobipRTC is supported only for Chromium-based Microsoft Edge versions for Windows also.\n\n\\*** WebRTC support in browsers other than Safari started with iOS version 14.3.\n\n\u003e **Note**: Mobile browsers are not able to receive calls and maintain call connectivity in the background.\n\u003e We recommend using [iOS](https://github.com/infobip/infobip-rtc-ios)\n\u003e and [Android](https://github.com/infobip/infobip-rtc-android) SDKs\n\u003e for creating mobile WebRTC Applications.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfobip%2Finfobip-rtc-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfobip%2Finfobip-rtc-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfobip%2Finfobip-rtc-js/lists"}