ProjectsVideo infrastructure
Serverless video platform
Uploads, encoding, captions and signed playback with no servers to run
Example design
- 01Ask to uploadThe app asks the Worker for an upload URL. The Worker checks that this user may upload, and how much.
- 02Upload URLThe Worker asks Stream for a one-time direct upload URL with a maximum duration set for this user.
- 03Pending videoThe video is recorded in D1 as pending, with its owner and the limits that applied.
- 04UploadThe browser uploads straight to Stream over tus, which resumes after a dropped connection. The file never passes through the Worker.
- 05Webhook: readyWhen encoding finishes, Stream calls the Worker's webhook. The Worker checks the signature and asks Stream to generate captions.
- 06Mark readyD1 now says the video is ready. The app reads state from its own database and never polls Stream.
- 07PlayA viewer opens the video. The Worker checks access and returns a signed playback token that expires.
- 08Stream with tokenThe player fetches adaptive HLS or DASH from Stream. A copied link stops working when the token expires.
- ifAn upload goes over the limitThe upload URL carries a maximum duration, so Stream rejects a file that is longer than the user's allowance. The Worker never has to inspect the file.
The problem
A product team needs video in their app: some users upload, everyone else watches. Built on servers, that means an upload service, a transcoding farm, storage, a CDN contract and a player, with someone on call for all of it. Cloudflare Stream handles the encoding, storage and delivery. That leaves the work specific to the product: who can upload, who can watch, and what happens to a video between upload and publication.
What it uses
- Stream
- Encoding, storage, adaptive delivery, the player, and generated captions
- Workers
- The API: upload URLs, webhook handling, access checks and playback tokens
- D1
- Video records, ownership and state
The decisions, and why
- Upload pathDirect creator upload over tus
- Large files go from the browser to Stream. The Worker only issues a URL, so it handles no video bytes and has nothing to scale.
- Upload limitMaximum duration per upload URL
- Stream bills by minutes stored and minutes delivered, so the duration limit on each upload is also a cost limit.
- Playback accessSigned tokens with a short expiry
- Private videos need a token that the Worker issues after checking access. Public videos can skip this.
- CaptionsGenerated, then reviewed
- Stream generates captions in 12 languages. Anything published outside the company should be checked by a person first.
- Source of truthD1, updated by webhook
- The app answers every question about a video from its own database, which the webhook keeps current.
Limits to plan around
- Caption generation covers 12 languages: Czech, Dutch, English, French, German, Italian, Japanese, Korean, Polish, Portuguese, Russian and Spanish.
- A video has to finish encoding before captions can be generated, so captions arrive a little after the video is playable.
What you get
- Worker API with upload, webhook and playback routes
- D1 schema for videos, owners and limits
- Player integration with signed playback
- Caption generation and a review step
- Tests for the access rules and the webhook
- Runbook covering limits, costs and failure cases
Related product
Playback Signal: quality of experience telemetry from the player out.
Read about Playback SignalOther projects
More video work on Cloudflare.
- Thumbnails and previews by URLHover previews, thumbnails and storyboards for a clip library, with no batch jobs
- Private video delivery from R2Pre-encoded HLS served from R2 through a Worker, with signed links that expire
- FFmpeg encoding on Cloudflare ContainersYour own ladder and packaging, started by an upload, served from R2
- Sub-second live with WHIP and WHEPLive auctions, Q&A and watch-alongs where a few seconds of delay is too much
- Searchable video archiveFind the moment in hours of recordings by what was said
- Instant clips from a live streamViewers clip the moment they just saw and share it while the event is still on
DRM solutions
Three corporate use cases, each with a Widevine demo that runs in your browser and checks what your device supports.
Talk about your video project
Tell us what you are building, or what is not working in the platform you have.
128 City Road, London, EC1V 2NX, United Kingdom
17420568
Registered in England and Wales