Skip to content

DavidJKTofan/cf-stream-demo

Repository files navigation

Cloudflare Stream Demo

An interactive demo application showcasing Cloudflare Stream's video capabilities, built with Cloudflare Workers and TypeScript.

Features

Secure Video Playback

Generate signed URLs for protected video content with granular access controls:

  • Token Expiration - Set tokens to expire from 1 minute to 24 hours
  • Geo-Restrictions - Allow or block specific countries using ISO 3166-1 Alpha-2 codes
  • IP Allowlisting - Restrict playback to specific IP ranges (CIDR notation)
  • Download Control - Enable/disable MP4 downloads per token
  • Auto-Enable Privacy - Automatically enables requireSignedURLs when generating tokens

Try it: Use example video ID 911637687cf6595368a55aa984d2365d in the demo

Media Transformations

Transform videos from any origin via URL parameters - no upload required:

  • Frame Extraction - Extract still images at specific timestamps
  • Video Clipping - Create preview clips with custom start time and duration
  • Resizing - Scale videos to specific dimensions with various fit modes
  • Spritesheets - Generate sprite images from multiple frames
  • Audio Extraction - Extract audio tracks from videos

Additional Capabilities (Documentation Links)

  • Stream Player - Adaptive bitrate streaming with HLS/DASH support
  • Live Streaming - WebRTC, RTMPS, and SRT protocols
  • Video Analytics - Views, engagement, and geographic data
  • Direct Uploads - One-time upload URLs with TUS resumable support

Getting Started, Installation, Development & Deployment

Deploy to Cloudflare

Configuration

Required Environment Variables

Set STREAM_CUSTOMER_CODE in wrangler.jsonc:

{
  "vars": {
    "STREAM_CUSTOMER_CODE": "your-customer-code"
  }
}

Find your customer code in Stream URLs: customer-{CODE}.cloudflarestream.com

Required Secrets

Generate a signing key first:

curl --request POST \
  "https://api.cloudflare.com/client/v4/accounts/{account_id}/stream/keys" \
  --header "Authorization: Bearer <API_TOKEN>"

Then set the secrets:

# For signed URL generation
wrangler secret put STREAM_SIGNING_KEY_ID
wrangler secret put STREAM_SIGNING_KEY_JWK

# For video privacy controls (optional but recommended)
wrangler secret put STREAM_API_TOKEN
wrangler secret put STREAM_ACCOUNT_ID
Secret Description
STREAM_SIGNING_KEY_ID Key ID from /stream/keys API response
STREAM_SIGNING_KEY_JWK Base64-encoded JWK from /stream/keys API response
STREAM_API_TOKEN Cloudflare API token with Stream:Edit permission
STREAM_ACCOUNT_ID Your Cloudflare Account ID (32-character hex string)

Important: STREAM_ACCOUNT_ID is your Cloudflare Account ID, NOT the Stream customer code. Find it in your Cloudflare Dashboard URL: dash.cloudflare.com/{account_id}/.... It's a 32-character hexadecimal string like a1b2c3d4e5f67890a1b2c3d4e5f67890.

Usage

Secure Video Demo

  1. Navigate to the Secure Video Playback demo
  2. Enter your Stream video ID (or click "Use example" for a quick test)
  3. The demo automatically checks if requireSignedURLs is enabled on the video
  4. Configure token settings:
    • Expiration time
    • Download permissions
    • Geo-restrictions or IP allowlisting
  5. Click Generate Signed URL - this will:
    • Automatically enable requireSignedURLs on the video (if the checkbox is checked)
    • Generate a signed JWT token
  6. Use the generated URLs for iframe embed, HLS/DASH manifests, or thumbnails

Note: The "Auto-enable privacy" checkbox is on by default, ensuring your video is actually protected when you generate a signed URL.

Media Transformations Demo

  1. Navigate to the Media Transformations demo
  2. Enter a source video URL (must be publicly accessible MP4)
  3. Configure your zone domain
  4. Select transformation options:
    • Mode (video, frame, spritesheet, audio)
    • Dimensions and fit mode
    • Time and duration
  5. Click Generate URL to create the transformation URL

API Endpoints

Endpoint Method Description
/api/generate-token POST Generate a signed token for video playback
/api/set-video-privacy POST Enable/disable requireSignedURLs on a video
/api/video-info GET Get video info including privacy status
/api/config GET Check if the worker is properly configured
/api/health GET Health check endpoint

Example: Generate Token

curl -X POST https://your-worker.workers.dev/api/generate-token \
  -H "Content-Type: application/json" \
  -d '{
    "videoId": "911637687cf6595368a55aa984d2365d",
    "expiresInMinutes": 60,
    "downloadable": false,
    "restrictionType": "allowCountries",
    "countries": ["US", "CA"]
  }'

Project Structure

cf-stream-demo/
├── src/
│   ├── index.ts          # Worker entry point with API routes
│   ├── stream.ts         # Signed token generation utilities
│   └── env.d.ts          # TypeScript declarations for env/secrets
├── public/
│   ├── index.html        # Homepage with feature overview
│   ├── secure-video.html # Signed URL demo interface
│   ├── transform.html    # Media transformations demo
│   └── styles.css        # All styles (responsive)
├── test/
│   └── index.spec.ts     # Vitest tests
├── wrangler.jsonc        # Wrangler configuration
├── tsconfig.json         # TypeScript configuration
├── vitest.config.mts     # Vitest configuration
└── package.json          # Dependencies and scripts

Documentation References

Build Your Own

For full customization and building serverless, scalable real-time video applications:


Disclaimer

This demo is for educational purposes only and is not officially endorsed by Cloudflare. It demonstrates Cloudflare Stream capabilities using publicly available APIs and documentation. Use at your own risk.

This project is not affiliated with, officially maintained by, or sponsored by Cloudflare, Inc. Cloudflare and the Cloudflare logo are trademarks of Cloudflare, Inc.

About

Interactive demo showcasing Cloudflare Stream's video capabilities, built with Cloudflare Workers.

Topics

Resources

Stars

Watchers

Forks

Contributors