Is cloudflare R2 able to handle HLS streaming?

1.6k Views Asked by At

https://hlsbook.net/how-to-serve-hls-video-from-an-s3-bucket/

It is quite simple to setup a bucket folder on S3 to stream a video HLS download. I wonder is cloudflare R2 able to do this? I am able to setup a public folder with R2 that can deliver a single MP4, although there's obviously a loop needed in the cloudflare worker to get each .ts file for R2.

2

There are 2 best solutions below

1
On BEST ANSWER

New answer: Public buckets and CORS are now live so you should be able to setup CORS using the same CORS configuration rules and methods as described on that page. Setting up public buckets and caching is described here: https://developers.cloudflare.com/r2/data-access/public-buckets/

ACLs aren't supported via R2 itself but you can use Cloudflare Access or other enforcement mechanisms on the zone that fronts your public bucket using normal Cloudflare tooling (e.g. https://community.cloudflare.com/t/firewall-rule-to-block-referers-other-than-the-sites-domain/72115 for an example on how to setup a firewall rule on your zone to allow list requiring a given referrer).

Old answer

Unless I'm misreading, most of that example page is about:

  1. Configuring a public bucket
  2. Configuring CORS for use with JS players (not needed for browsers with built-in support).
  3. Configuring ACLs

We're currently in the middle of implementing public buckets and CORS which should enable most of this. In the interim, you can make enable it today by taking the documented example (https://developers.cloudflare.com/r2/examples/demo-worker/) & add CORS headers by adjusting the response.

We also will allow you to set a virtual cname to your public bucket which then lets you control things like controlling referrer, put Access in front of the website, etc.

0
On

You need to add cors to the bucket read, which I missed. Following the code that Vitali added.

const headers = new Headers()
        object.writeHttpMetadata(headers)
        headers.set('etag', object.httpEtag)
        headers.set('Access-Control-Allow-Origin', '*') <---  THIS
        const status = object.body ? (range ? 206 : 200) : 304
        return new Response(object.body, {
          headers,
          status
        })