Skip to content

Full Example: RTC Video Chat ​

The RTC Video Chat page is a video call between two users, straight from one browser to the other, with the screen, a text chat and file transfer on the same connection. Skapi does the signaling over its realtime connection. It needs a logged-in user, and WebRTC works over HTTPS or on localhost. Open it in another browser or device with a second account and call each other.

Enter your project ID to open the demo.

You need your project ID to open the demo.

The RTC Video Chat page of the template: a short explanation and the table of users online with a call button per user

webrtc.html before a call: the other users on the page, each with a call button. The camera and the microphone are always on a call.

The page during a call with both users sharing their screens: four tiles in the order your camera, the other user's camera, your screen and theirs, the buttons, and the chat with its input above the newest message

During a call with both screens shared: each side's screen is its own track, so both can share at once. Every tile is 4:3 with the picture centered inside, and the chat keeps the newest message on top, right under the input.

The call in fullscreen on a wide screen: the chosen video fills the left, the other videos are thumbnails on the right above the call buttons and the chat

Fullscreen, after clicking a tile: the chosen video on the stage, the others as thumbnails, then the call buttons and the chat, with the input at the bottom. On a phone the layout changes to one video per user; Escape or the Back button leaves fullscreen.

What it demonstrates ​

FeatureHow the page does it
Finding each otherEvery visitor of the page joins the realtime group RTCCall; getRealtimeUsers() and the USER_JOINED and USER_LEFT notices keep a table of the other users online, with their connection IDs.
CallingconnectRTC() with the other user's connection ID and media: { audio: true, video: true }. meta names the kind of call. The call's connection promise resolves once the other side accepts.
Receiving a callThe callee gets an rtc:incoming realtime message. Its meta and sources fill the dialog, connectRTC() on the message accepts, hangup() rejects. An rtc:closed message closes the dialog when the caller cancels.
The tilesFour tiles in a fixed order: your camera, the other user's camera, your screen, theirs. Each shows when its track exists. Every track event carries source, which routes the other user's camera and screen to their tiles; trackmute hides the screen tile when they stop sharing. The tiles are 4:3 and the picture is centered inside, never stretched.
Screen sharing during the callShare screen calls share('screen', { contentHint: 'text' }), Stop sharing calls unshare('screen'). The unshare event resets the page, also when the browser's own Stop sharing button ends the share.
MuteMute microphone and Turn camera off call mute({ audio }) and mute({ video }). The tracks stay on the call and send silence or black frames.
Text chatMessages go over the connection's default data channel and are shown with the sender's name (or email address; a guest signed in with anonymousLogin() shows as Guest), newest first, right under the input.
FilesSend a file, first in the row of call buttons, calls sendFile(); the other side gets fileprogress events and then a file event, shown in the chat as a progress bar that turns into a download link. The file goes straight between the two browsers.
FullscreenClicking a tile puts the call section in fullscreen, with the browser's Fullscreen API where it is allowed and a full-window overlay elsewhere. On a wide screen the clicked video takes the stage and the others become thumbnails above the call buttons and the chat, which then has its input at the bottom. On a phone one video per user is shown, upright on top of each other and sideways side by side, with the buttons and a three line chat; a tap on a video switches it between that user's screen and camera, and a screen the other user starts sharing takes over their view on its own. A pushState entry lets the Back button leave fullscreen instead of the page.
Hanging uphangup() on either side ends the call; the connectionstatechange event returns both pages to the user list.

Download ​

The page is part of the full template: skapi-templates.zip. See Full Examples for how to run it.