Example

Peer-to-peer video chat

Capture a camera and microphone stream, send it to the room, and attach incoming streams to video elements.

Send and receive camera streams

Set up the receiver first, then request camera access. Add the local stream to current peers and to each peer that joins later. The video elements and UI helpers in this sketch belong to your app.

import {joinRoom} from 'trystero'

const room = joinRoom({appId: 'dev.trystero.examples.videoChat'}, callId)

room.onPeerStream = (stream, peerId) => {
  const video = createPeerVideo(peerId)
  video.autoplay = true
  video.playsInline = true
  video.srcObject = stream
  video.play().catch(() => showPlayButton(video))
}

room.onPeerLeave = peerId => {
  removePeerVideo(peerId)
}

const localStream = await navigator.mediaDevices.getUserMedia({
  audio: true,
  video: true
})

localVideo.muted = true
localVideo.autoplay = true
localVideo.playsInline = true
localVideo.srcObject = localStream
room.addStream(localStream)

room.onPeerJoin = peerId => {
  room.addStream(localStream, {target: peerId})
}

leaveButton.onclick = async () => {
  localStream.getTracks().forEach(track => track.stop())
  await room.leave()
}

Use HTTPS or localhost for camera access. Handle denied permissions and give users a play button if the browser blocks autoplay. For devices on restricted networks, configure TURN. Test room sizes on real devices: each sender uploads a stream to every connected peer.