We use cookies to improve your experience. No personal information is gathered and we don't serve ads. Cookies Policy.

ExpressionEngine Logo ExpressionEngine
Features Pricing Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University
Log In or Sign Up
Log In Sign Up
ExpressionEngine Logo
Features Pro new Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University Blog
  • Home
  • Add-Ons
default app icon

Cloudflare Stream

By Blair Liikala
Integrations Media Publishing

Description

Integration for using Cloudflare Stream to host and deliver secure on-demand videos.

Features

  • Easy uploading and management of video within ExpressionEngine.
  • No-cost encoding.
  • Fast uploading.
  • Global CDN delivery network.
  • Easy import/export between the native EE File Manager to get started, or return to self-host.

Limitations

Cloudflare limitations:

  • Max file size is 30 GB.
  • Max video data rate is 200 Mb/s (careful with ProRes).
  • 4k ingest is possible, but output streams are limited to 1080p.

Add-on Limitations:

  • Captions will need to be uploaded through the CF dashboard.
  • VOD only. This does not yet implement Cloudflare Live streaming.

Demo

  • Contact me to arrange a demo or get a demo copy.
  • Cloudflare Stream requires a paid subscription to use.

Installation

(1) Copy files to both the system and themes folder and install in the control panel.

  • /system/user/addons/[cloudflarestream]
  • /themes/user/[cloudflarestream]

(2) In Cloudflare’s control panel copy the customer ID into the addon settings, and create a token and also copy into the control panel. Unfortunately these are in two different locations.

  • Tokens are created under My Profile. This link may work https://dash.cloudflare.com/profile/api-tokens
  • Account ID (also called customer ID) is located in the Stream video list in the top right corner.

(3) Create a field using the Cloudflare Stream field type and add it to a channel.

A Note about Webhooks

The add-on listens for webhooks to update status of videos so that pinging is not required. Cloudflare sends a webhook only when the video has finished processing.

During development you may need to route webhooks to your local development instance using something like https://smee.io/ and the EE Action URL (/index.php?ACT=xx)

If webhooks fail to reach the add-on, video ready state might be delayed or out of sync until the next time they are requested in the EE control panel or from a tag.

Actions outside the addon

A copy of the Cloudflare video information is stored locally in the EE database for speed and searchability. However cloudflare’s control panel is able to add, modify and delete videos as well, and not all of these changes are pushed to the add-on:

  • If webhooks are enabled, videos added through the Cloudflare dashboard will be added to the add-on when the processing is complete. It may be missing metadata.
  • Edited videos will not update instantly in EE.
  • Deleted videos will not update instantly in EE.

Due to this, try to avoid working in the Cloudflare dashboard after development.

Tokens

By default, secure URLs are turned on. Most use cases will need this enabled, and converting from one to another can take some effort.

This can be disabled by setting requireSignedURLs to false in the /config/config.php file and will apply to all new videos. Future versions may include this option in the control panel.

Secure streaming is a way to limit the access time for a URL, or add other restrictions such as domain locking. The default setting is 8 hours till the link expires from when it was generated. This means each viewer would have 8 hours to watch the video from the time they opened the page, unless the page was refreshed. Keep in mind this means any caching needs to be under 8 hours as well.

Templates

exp:cloudflarestream:get and fieldtype

Parameters

Name Description
id Cloudflare Stream UID
readyToStream True/False if the stream is ready to play.
status One of the status types such as ready or quened
keyword A search keyword, url-encoded. Will search all metadata.

Tags

Name Description
uid Cloudflare Stream UID
hls URL to hls video stream. If secured, includes token.
dash URL to dash video stream. If secured, includes token.
filename Metadata for filename. Optional.
aspectratio width / height for video as number (ex 1.777)
thumbnail URL to image thumbnail jpg. If secured, includes token.
created Timestamp to when the video was created.
updated Timestamp to when the video was last updated in Cloudflare
preview URL to preview link
signed True/False if signed (secure) URLs are required and being used.
duration Length in seconds.
size Size in bytes
percent_complete When processing, the percentage completed.
state The state the video is in such as ready or quened
token The security token used to play a signed URL.
customercode A code used to build playback URLs.
raw JSON (as text) of the full video object.
raw:pretty JSON, but formatted nicely.
<!-- Inside an Entries loop -->
{exp:channel:entries channel="blog"}
  <h1>Title</h1>
  {my_video_field}
    <h2>{filename}</h2>
    <img src="{thumbnail}">
    <fake-video-player src="{hls}"></fake-video-player>
  {my_video_field}
{/exp:channel:entries}

<!-- Stand-alone -->
{exp:cloudflarestream:get id="xxxxx"}
  <h2>{filename}</h2>
  <img src="{thumbnail}">
  <fake-video-player src="{hls}"></fake-video-player>
{/exp:cloudflarestream:get}

exp:cloudflarestream:image

Helper to create ad-hoc thumbnails from the video with transformations. While this can also be done using “hard-coded” URLs with the other video tags, this tag simply makes it easier to generate additional thumbnail transformations.

See Cloudflare’s guide on image options.

Note that images can also be created by simplying manually adding URLs in a template with query parameters. Just be sure to use the correct ID; UID or token.

Parameters

Name Description
id UID of the Cloudflare video. Required
format Format, jpg or gif Default jpg

Tags

Name Description
width Width of image, default 640
height Height of image, defualt 640
time time in seconds from the start
fit What to do when requested height and width doesn’t match the original upload, which should be one of: crop clip scale fill (default crop)
duration Default 5s (animated GIF only)
fps Default 8s (animated GIF only)

Playing Videos

Like most video API services, Cloudflare uses the streaming protocol HLS (http live streaming) to deliver video in chunks and at multiple quality levels. However only Safari knows how to play this format natively, and so we use javascript to make this format work on other browsers. Luckily this is easily done by using a video player project, and there are several to choose from, open-source to commercial. Players also differ in cost, features, and tracking analytics.

DASH is also available.

Cloudflare has a guide for playing videos here.

Below is a list of other video player options. Each can play the HLS stream provided by the {hls} tag as a source.

Core Open Source Players

  • HLS.js is the core most video players use under-the-hood and can be used by itself, though a bit technical.
  • Video.js is the leading open source video player, and used as a base for many other video players. It also uses hls.js.

Open Source

  • Vidstack.io is a new web component player.
  • Mux Elements Similar to vidstack, is a collection of components to build a video player.

Commercial Players

  • JW Player
  • THEOplayer

Example with Cloudflare’s player iFrame:

{exp:channel:entries channel="blog"}
  {cloudflare}
    <iframe
      src="https://customer-{customercode}.cloudflarestream.com/{if token}{token}{if:else}{uid}{/if}/iframe"
      style="border: none"
      height="720"
      width="1280"
      allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
      allowfullscreen="true"
    ></iframe>
  {/cloudflare}
{/exp:channel:entries}

Exmple with Vidstack

<html>
  <head>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/@vidstack/player@next/cdn/bundle.js"
    ></script>
  </head>
  <body>
    <vds-media>
      <vds-hls controls poster="{thumbnail}">
        <video controls src="{hls}" preload="none"></video>
      </vds-hls>
    </vds-media>
  </body>
</html>

Example with Video.js

<html>
  <head>
    <link
      href="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.20.3/video-js.min.css"
      rel="stylesheet"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.20.3/video.min.js"></script>
  </head>
  <body>
    <video-js id="vid1" controls preload="auto">
      <source src="{hls}" type="application/x-mpegURL"/>
    </video-js>
    <script>
      const vid = document.getElementById('vid1');
      const player = videojs(vid);
    </script>
  </body>
</html>
Information
Version 0.5.0
Last Update 2 years ago
Compatibility EE 7
License Commercial
Links
  • Support
ExpressionEngine Home Features Pro Contact Version Support
Learn Docs University Forums
Resources Support Add-Ons Partners Blog
Privacy Terms Trademark Use License

Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.