Join us for EEConf 2023, October 4-5 in Orlando. Speakers. Networking. Community powered. Awesome.
Join us for EEConf 2023, October 4-5 in Orlando.
Register Now!Integration for using Cloudflare Stream to host and deliver secure on-demand videos.
Cloudflare limitations:
Add-on Limitations:
(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.
(3) Create a field using the Cloudflare Stream field type and add it to a channel.
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.
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:
Due to this, try to avoid working in the Cloudflare dashboard after development.
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.
exp:cloudflarestream:get
and fieldtype
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. |
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.
Name | Description |
---|---|
id |
UID of the Cloudflare video. Required |
format |
Format, jpg or gif Default jpg |
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) |
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.
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>
Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.