Orange Meets is a demo application built using Cloudflare Calls. To build your own WebRTC application using Cloudflare Calls, get started in the Cloudflare Dashboard.
Simpler examples can be found here.
Go to the Cloudflare Calls dashboard and create an application.
Put these variables into .dev.vars
CALLS_APP_ID=<APP_ID_GOES_HERE>
CALLS_APP_SECRET=<SECRET_GOES_HERE>
The following variables are optional:
MAX_WEBCAM_BITRATE(default1200000): the maximum bitrate for each meeting participant's webcam.MAX_WEBCAM_FRAMERATE(default:24): the maximum number of frames per second for each meeting participant's webcam.MAX_WEBCAM_QUALITY_LEVEL(default1080): the maximum resolution for each meeting participant's webcam, based on the smallest dimension (i.e. the default is 1080p).
To customise these variables, place replacement values in .dev.vars (for development) and in the [vars] section of wrangler.toml (for the deployment).
npm install
npm run devOpen up http://127.0.0.1:8787 and you should be ready to go!
- Make sure you've installed
wranglerand are logged in by running:
wrangler login-
Update
CALLS_APP_IDinwrangler.tomlto use your own Calls App ID -
You will also need to set the token as a secret by running:
wrangler secret put CALLS_APP_SECRETor to programmatically set the secret, run:
echo REPLACE_WITH_YOUR_SECRET | wrangler secret put CALLS_APP_SECRET-
Optionally, you can also use Cloudflare's TURN Service by setting the
TURN_SERVICE_IDvariable inwrangler.tomlandTURN_SERVICE_TOKENsecret usingwrangler secret put TURN_SERVICE_TOKEN -
Also optionally, you can include
OPENAI_MODEL_ENDPOINTandOPENAI_API_TOKENto use OpenAI's Realtime API with WebRTC to invite AI to join your meeting. -
Finally you can run the following to deploy:
npm run deployA secure, end-to-end encrypted video conferencing application built with Remix, WebRTC, and MLS (Message Layer Security).
- End-to-End Encryption: Uses MLS protocol for secure communication
- Screen Sharing: Share your screen with encrypted transmission
- WebRTC: Real-time video and audio communication
- Cloudflare Workers: Serverless deployment on the edge
- Party Tracks: Advanced track management and routing
Fixed MLS ratchet errors during screen sharing that were causing:
- "Frame decryption failed: Cannot create decryption secrets from own sender ratchet..."
- "This is the wrong ratchet type" errors
- "Ciphertext generation out of bounds" errors
Solution: Implemented proper video sender transform management to ensure only one video encryption stream is active at a time, preventing sequence number conflicts in the MLS ratchet system.
See screenshare-e2ee-fix.md for detailed technical information.
- Frontend: React with Remix framework
- Backend: Cloudflare Workers with Durable Objects
- Encryption: Rust/WASM implementation of MLS protocol
- Media: WebRTC with custom transforms for E2EE
- Database: Cloudflare D1 (SQLite)
# Install dependencies
npm install
# Build E2EE worker (requires wasm-pack)
npm run build:e2ee-worker
# Start development server
npm run dev
# Run tests
npm test
# Type checking
npm run typecheckThe application uses a sophisticated E2EE system:
- MLS Protocol: Provides forward secrecy and post-compromise security
- Rust Worker: WASM-based encryption/decryption processing
- Transform Management: Careful handling of WebRTC sender/receiver transforms
- Track Lifecycle: Proper management of video track changes during screen sharing
# Deploy to Cloudflare Workers
npm run deployPlease ensure all tests pass and TypeScript compiles without errors:
npm run check
