Synento docs

Browser support

Which browsers can run a Synento session, how the SDK reports it, and what has actually been verified.

View as Markdown

Browser support

Synento encodes in the browser with WebCodecs and ships frames over a WebSocket. There is no WebRTC fallback — that is a deliberate architectural choice, not a gap: every frame is written to a durable stream, which is what makes each session its own recording — so a browser either has the APIs or it cannot publish. The SDK checks before connecting and tells you which piece is missing.

Requirements

A browser needs all four:

CapabilityUsed for
WebSocketTransport for media, chat and control
VideoEncoder / VideoDecoder / VideoFrame (WebCodecs)Encoding your camera, decoding everyone else's
navigator.mediaDevicesCamera and microphone capture (requires a secure context)
AudioWorkletNodeMicrophone capture at 16 kHz mono
AudioEncoder / AudioDecoder (Opus)Optional. Compresses audio ~8x. Without it the call falls back to uncompressed PCM and works exactly the same, so this does not affect whether a browser is supported — checkSupport() reports it as webCodecsAudio for visibility only.

navigator.mediaDevices only exists on HTTPS or localhost. On a plain HTTP origin — including a LAN IP such as http://192.168.1.10:3000 — capture is unavailable no matter which browser you use.

Matrix

BrowserPublish + subscribeNotes
Chrome / Edge 94+YesThe reference target. H.264, VP9 and VP8 all negotiate.
Safari 16.4+ (macOS)YesWebCodecs shipped in 16.4. Verified manually, not in CI.
Safari 16.4+ (iOS / iPadOS)Publish + subscribe, with caveatsSee iOS below.
Firefox 133+YesWebCodecs enabled by default from 133.
Firefox < 133NoVideoEncoder is absent; the SDK reports it and refuses to connect.
Any browser over plain HTTPNoNo mediaDevices outside a secure context.

What has actually been verified

Being precise about this matters more than the table looking green.

  • Chromium — automated, every CI run. A two-party call with synthetic camera and microphone hardware: both sides decode the other's video, chat is delivered, and both participants' camera and microphone tracks are checked for recorded data in S2. See e2e/tests/live-call.spec.ts.
  • Playwright WebKit — automated, non-media flows only. It runs sign-in, the dashboard, recording and export. A WebKit pass is not a Safari pass. Playwright's WebKit is a build of the engine, not the shipping browser: its WebCodecs support and media handling differ from Safari's, and it has no equivalent of Chromium's fake-device switch. Treating it as Safari coverage would be exactly the false assurance the suite exists to prevent.
  • Safari on macOS and iOS — manual. Run the checklist below before a release. The result belongs in this table, not in a test report.

Manual Safari pass

Against a deployed environment over HTTPS (not localhost, so the iOS device can reach it):

  1. Open the demo in Safari, join a session, and confirm the local preview shows.
  2. Join the same session from a second device or browser. Confirm video appears both ways and that you can hear audio in both directions.
  3. Send a chat message each way.
  4. Lock the phone / switch apps for ~15 seconds, then return: the SDK should reconnect and resume publishing without a reload.
  5. Leave, then open the recording in the dashboard: replay should show both participants with audio.
  6. Export to MP4 and play the file.

iOS

Two behaviours are worth knowing about, and both are platform behaviour rather than Synento bugs:

  • Backgrounding stops capture. iOS suspends media capture when the tab is not frontmost. The connection resumes on return, but the recording has a gap.
  • Autoplay of remote audio needs a gesture. Audio playback starts from a user interaction (the join tap counts). A page that connects on load without any tap may render video silently until the user touches something.

What your code should do

checkSupport() returns a structured report, and SynentoRoom.connect() refuses to open a socket when it fails, rather than half-joining a call:

import { SynentoRoom } from '@synento/client'

const support = SynentoRoom.checkSupport()
if (!support.supported) {
  // support.reason is written for humans and names the missing capability.
  showUnsupportedMessage(support.reason)
  return
}

The individual booleans (webSocket, webCodecsVideo, mediaDevices, audioWorklet) are all on the report, so you can tell "update your browser" apart from "this page needs HTTPS" — a distinction users can act on.

On this page