Videos from other domains
Using videos from a CDN or storage bucket, and the headers that make them work well.
src can be any direct link to a video file: on your own site, on a CDN, or in
a storage bucket. This example loads the docs video from jsDelivr, a public CDN:
import { useState } from "react";
import { ScrollVideo } from "vidscroll";
const src = "https://cdn.jsdelivr.net/gh/nikhilswain/vidscroll@v0.3.2/demo/public/train.mp4";
export default function Example() {
const [source, setSource] = useState("loading");
return (
<ScrollVideo src={src} length="400vh" onLoad={(info) => setSource(info.source)}>
<p style={{ position: "absolute", top: 16, left: 16, margin: 0, color: "#fff", font: "500 18px monospace" }}>
served as: {source}
</p>
</ScrollVideo>
);
}<ScrollVideo
src="https://cdn.jsdelivr.net/gh/nikhilswain/vidscroll@v0.3.2/demo/public/train.mp4"
length="400vh"
onLoad={(info) => console.log(info.source)}
/>What the server needs to send
| Header | Why | Without it |
|---|---|---|
Access-Control-Allow-Origin | Lets your site read the file, so vidscroll can check and re-encode it | The video is streamed directly instead: it plays, but isn’t optimized or cached |
Accept-Ranges: bytes | Lets the browser request parts of the file, which streaming and seeking rely on | Streaming and seeking can break, especially in Safari |
ETag, Last-Modified or Content-Length | Identifies the file, so an optimized copy can be cached | The re-encode runs on every visit |
Content-Type: video/mp4 (or video/webm) | Says it’s a video | An HTML response is rejected with a clear error |
jsDelivr sends all of these. For a bucket on S3, Cloudflare R2, Google Cloud
Storage or similar, add a CORS rule that allows GET from your site’s origin;
the other headers are usually sent already.
When CORS is missing
If the file can’t be read, vidscroll logs this and streams it instead:
[vidscroll] Couldn't read "https://…/hero.mp4" (network error or CORS). Streaming it directly instead — scrubbing will be slow unless the file is already encoded for it. If it's on another domain, the server must send Access-Control-Allow-Origin for this site.A streamed video plays, but vidscroll can’t check its keyframes, re-encode it
or cache it. So for files without CORS, prepare them with the CLI
before uploading: a prepared file scrubs well even when streamed. onLoad
reports source: "stream" in this case.
Checking a URL
Run this to see the headers a server sends:
curl -sI https://cdn.example.com/videos/hero.mp4Look for access-control-allow-origin, accept-ranges: bytes and an etag or
last-modified line.
Related
- Automatic optimization: what CORS enables.
- Pre-encoding with the CLI: files that scrub well anywhere.