{"id":26182702,"url":"https://github.com/100mslive/100ms-web-v1","last_synced_at":"2025-04-14T23:15:52.655Z","repository":{"id":38756938,"uuid":"313547813","full_name":"100mslive/100ms-web-v1","owner":"100mslive","description":"JavaScript Video Conferencing SDK \u0026 React Sample App","archived":false,"fork":false,"pushed_at":"2023-10-03T09:12:46.000Z","size":19906,"stargazers_count":26,"open_issues_count":29,"forks_count":18,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-14T23:15:46.596Z","etag":null,"topics":["100mslive","audio","hmsvideo","javascript-sdk","remote-peers","room","sfu","video-streams","webrtc"],"latest_commit_sha":null,"homepage":"https://100ms.live","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/100mslive.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-11-17T08:00:58.000Z","updated_at":"2024-06-04T04:47:36.000Z","dependencies_parsed_at":"2023-02-15T04:02:32.387Z","dependency_job_id":null,"html_url":"https://github.com/100mslive/100ms-web-v1","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/100mslive%2F100ms-web-v1","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/100mslive%2F100ms-web-v1/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/100mslive%2F100ms-web-v1/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/100mslive%2F100ms-web-v1/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/100mslive","download_url":"https://codeload.github.com/100mslive/100ms-web-v1/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248975329,"owners_count":21192210,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["100mslive","audio","hmsvideo","javascript-sdk","remote-peers","room","sfu","video-streams","webrtc"],"created_at":"2025-03-11T22:23:47.820Z","updated_at":"2025-04-14T23:15:52.639Z","avatar_url":"https://github.com/100mslive.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e :warning: We have deprecated this older version of our sample web app. Kindly refer to [our new sample app](https://github.com/100mslive/100ms-web-v2)\n\n\n# 100ms Sample React App\n\nThis is an example web app to demo 100ms' web SDK\n\n## Prerequisites\n\nYou will need [Node.js](https://nodejs.org) version v12.13.0 or greater installed on your system\n\n## Setup\n\nGet the code by cloning this repo using git\n\n```\ngit clone git@github.com:100mslive/sample-app-web.git\n```\n\nOnce cloned, open the terminal in the project directory, and install dependencies with:\n\n```\nnpm install\n```\n\nCreate a new file `.env` and copy the values from `example.env`\n\n```\ncp example.env .env\n```\n\n### Token generation\n\nHost your token generation service [following this guide](https://docs.100ms.live/helpers/runkit)\n\nUpdate the `TOKEN_ENDPOINT` in `.env` file with your token generation service endpoint (eg. `https://ms-services-29qzq06nzogv.runkit.sh/`)\n\n### [Optional] Firebase config\n\nTo turn on the remote-mute feature, update the following values in `.env` file from your firebase project settings:\n\n```\n# Firebase config\nFIREBASE_API_KEY=\u003cfirebaseConfig.apiKey\u003e\nFIREBASE_AUTH_DOMAIN=\u003cfirebaseConfig.authDomain\u003e\nFIREBASE_DATABASE_URL=\u003cfirebaseConfig.databaseURL\u003e\nFIREBASE_PROJECT_ID=\u003cfirebaseConfig.projectId\u003e\nFIREBASE_STORAGE_BUCKET=\u003cfirebaseConfig.storageBucket\u003e\nFIREBASE_MESSAGING_ID=\u003cfirebaseConfig.messagingSenderId\u003e\nFIREBASE_APP_ID=\u003cfirebaseConfig.appId\u003e\n```\n\nThen start the app with:\n\n```\nnpm start\n```\n\nThe app should now be up and running at http://localhost:8080 🚀\n\n![Screenshot](/public/screenshot.png?raw=true)\n\n# SDK Documentation\n\nThis guide provides an overview of the key objects you'll use with 100ms' JavaScript SDK to build a live audio/video application.\n\n## Supported Devices\n\n| Platform | Chrome | Firefox | Opera | Safari |\n|----------|--------|---------|-------|--------|\n|Android 4.4 or later| Version 66 or later |Version 66 or later | Version 45 or later| No\n|MacOS 10 or later| Version 66 or later | Version 66 or later |Version 45 or later |Version 11 or later | \n|Windows 7 or later | Version 66 or later | Version 66 or later | Version 45 or later |No |\n| iOS  |No  |No |No |Version 12 or later|\n\n## Concepts\n\n- `Room` - A room represents a real-time audio, video session, the basic building block of the 100mslive Video SDK\n- `Stream` - A stream represents real-time audio, video streams that are shared to a room. Usually, each stream contains a video track and an audio track (except screenshare streams, which contains only a video trac)\n- `Track` - A track represents either the audio or video that makes up a stream\n- `Peer` - A peer represents all participants connected to a room. Peers can be \"local\" or \"remote\"\n- `Publish` - A local peer can share its audio, video by \"publishing\" its tracks to the room\n- `Subscribe` - A local peer can stream any peer's audio, video by \"subscribing\" to their streams\n- `Broadcast` - A local peer can send any message/data to all remote peers in the room.\n\n## Pre-requisites\n\n### 1. Get the 100ms JavaScript SDK\n\n`npm install --save @100mslive/hmsvideo-web@latest`\n\n### 2. Get Access Keys\n\nSign up on https://dashboard.100ms.live/register \u0026 visit `Developer` tab to get your access credentials\n\n### 3. Generate a server-side token\n\nTo generate a server-side token, follow the steps described here - https://docs.100ms.live/server-side/generate-server-side-token\n\n### 4. Create a room\n\nTo create a room, follow the steps described here - https://docs.100ms.live/server-side/create-room\n\n### 5. Generate a client-side token\n\nTo generate a client-side token, follow the steps described here - https://docs.100ms.live/server-side/authentication\n\n## Import modules \u0026 instantiate 100ms Client (HMSClient)\n\n```import { HMSPeer, HMSClientConfig, HMSClient } from \"@100mslive/hmsvideo-web';\n\nconst peer = new HMSPeer(userName:\"\u003cuserName here\u003e\",authToken:\"\u003cauthToken here\u003e\")\n\nconst config = new HMSClientConfig({\n    endpoint: \"wss://prod-in.100ms.live\"\n})\n\nconst client = new HMSClient(peer, config)\n\n```\n\n\u003e authTokenis the client-side token generated by your token generation service.\n\n## Connect to 100ms' server\n\nAfter instantiating `HMSClient`, connect to 100ms' server\n\n```\ntry {\n    await client.connect()\n} catch(err) {\n    // Handle error\n}\n```\n\n## Setup listeners\n\nAdd listener functions to listen to peers joining, establishing a connection to the server, peers publishing their streams etc.\n\n```\nclient.on('connect',() =\u003e {\n    // This is where we can call `join(room)`\n});\n\nclient.on('disconnect', () =\u003e {});\n\nclient.on('peer-join', (room, peer) =\u003e {\n    // Show a notification or toast message in the UI\n});\n\nclient.on('peer-leave', (room, peer) =\u003e {\n    // Show a notification or toast message in the UI\n});\n\nclient.on('stream-add', (room,  peer, streamInfo) =\u003e {\n    // subscribe to the stream if needed\n});\n\nclient.on('stream-remove', (room, peer, streamInfo) =\u003e {\n    // Remove remote stream if needed\n});\n\nclient.on('broadcast', (room, peer ,message) =\u003e {\n    // Show a notification or update chat UI\n});\n\nclient.on('disconnected', () =\u003e {\n    // If there is a temporary websocket disconnection, then execute code\n    // to re-publish and subscribe all streams. eg. location.reload();\n});\n```\n\n\u003e Always wait for `connect` message listener after creating client before subscribing/publishing any streams.\n\n\u003e If say, 4 streams were already published when client connects to the room, then client receives `stream-add` messages for all those 4 streams as soon as client joins\n\n\u003e Remember to add `disconnected` message handler. Temporary websocket disconnections are common and trying to reconnect on disconnection will ensure the user sees the conference continuing instead of freezing up\n\n\n\n## Join a room\n\n```\ntry {\n    await client.join(roomId);\n} catch(err) {\n    // Handle error\n}\n```\n\n\u003e This roomId should be generated using `createRoom` API\n\n## Get a local stream\n\nThis method prompts the user for permission to use a media input which produces audio/video tracks such as a camera, screen, microphone\n\n### Connect to default devices\n\n```\nconst localStream = await client.getLocalStream({\n    resolution: \"vga\",\n    bitrate: 256,\n    codec: \"VP8\",\n    frameRate: 20,\n    shouldPublishAudio:true,\n    shouldPublishVideo:true\n});\n```\n\n### Connect to specific device\n\nIn order to connect to a specific camera/mic, you can use the advancedMediaConstraints key which accepts browser's native [MediaStreamConstraints](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints) as shown below. To get deviceIDs, use [enumerateDevices](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices)\n\n```\nconst localStream = await client.getLocalStream({\n\t\tresolution: \"vga\", //This defines the video height and width. Can be qqvga, qvga, shd, hd\n\t\tbitrate: 256, //This is the maximum bitrate to cap the video at \n\t\tcodec: \"VP8\",\n\t\tframeRate: 20,\n\t\tshouldPublishAudio:true,\n\t\tshouldPublishVideo:true,\n\t\tadvancedMediaConstraints: {\n\t\t\t\tvideo: {\n\t\t\t\t\t\tdeviceId: \"e82934fe80bdd62ed2aac541f5fd53e53d98abb0b738c6f52edea4f5014d32d8\"\n\t\t\t\t},\n\t\t\t\taudio: {\n\t\t\t\t\t\tdeviceId: \"756814e591e116616c740e39b307a8015cac4c2511950e0240cf7fbe62736dfd\"\n\t\t\t\t}\n\t\t}\n});\n```\n\n\u003e For advanced use cases: all `stream` objects returned by `getLocalStream` extends browser's native MediaStream class and implements all its [methods](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream)\n\n\u003e The settings above are recommended settings for most use cases. You can increase resolution to hd and bandwidth to 1024 to get higher quality video.\n\n## Get local media for screenshare\n\nThis method prompts the user for permission to share their screen and choose the screnshare source\n\n```\nconst localScreen = await client.getLocalScreen({\n    bitrate: 0,\n    codec: \"VP8\",\n    frameRate: 10,\n});\n\n//If your primary usecase is sharing text\n\nlocalScreen.getVideoTracks().forEach(track =\u003e {\n    if ('contentHint' in track) {\n        track.contentHint = 'text';\n    }\n});\n```\n\n## Display local stream\n\nAll `stream` objects can be attached to HTML video elements. eg. The local stream from the user's camera\n\n```\n//This is React implementation. \n//Replace ref, useRef with id, getElementById for native HTML implementation.\n\n//Create a reference for the video element to which the local stream will be attached\nconst localVideo = useRef();\n\n//Attach local stream to the video element\nlocalVideo.current.srcObject = local;\n\n\n//Add video element\n\u003cvideo autoPlay muted ref={localVideo}\u003e\n\u003c/video\u003e\n```\n\n\u003e Remember to set `muted` to `true` and mirror the local webcam stream\n\n## Publish local stream to room\n\n```\ntry {\n    await client.publish(local, roomId);\n} catch(err) {\n    // handle the error\n}\n```\n\n\u003e A client can publish multiple streams eg. a screenshare, an in-built webcam and an external webcam all together\n\n\n## Subscribe to a remote peer's stream\n\nThis method \"subscribes\" to a remote peer's stream. This should ideally be called in the `stream-add` message listener.\n\n```\ntry {\n    const remote = await client.subscribe(mid, roomId);\n    // Do something with remote stream\n} catch(err) {\n    // Handle error\n}\n```\n\n## Unsubscribe to a peer's stream\n\n```\ntry {\n    await client.unsubscribe(remoteStream, roomId);\n} catch(err) {\n    // Handle error\n}\n```\n\n## Broadcast a payload to the room\n\n```\ntry {\n    await client.broadcast(payload, roomId);\n} catch(err) {\n    // Handle error\n}\n```\n\n## Disconnect client\n\n```\nclient.disconnect();\n```\n\n## Mute/unmute local video/audio\n\n100ms SDK's `Stream` interface has `mute` and `unmute` methods provided to mute and unmute video or audio respectively.\n\n```\n// To mute local stream audio\nlocal.mute('audio')\n\n// To unmute local stream audio\nlocal.unmute('audio')\n\n// To mute local stream video\nlocal.mute('video')\n\n// To unmute local stream video\nlocal.unmute('video')\n```\n\n## Change quality of audio/video mid-stream\n\nYou can use `applyConstraints` to change the quality/source of the video mid-stream.\n\n### Change quality\n\n```\nclient.applyConstraints({\n      bitrate: 0,\n      codec: \"VP8\",\n\t\t\tresolution:\"hd\",\n      frameRate: 10,\n},\nlocalStream)\n```\n\nRefer the full SDK Documentation here - https://docs.100ms.live/client-side/web\n\n\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F100mslive%2F100ms-web-v1","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F100mslive%2F100ms-web-v1","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F100mslive%2F100ms-web-v1/lists"}