Embedding a video player through an <iframe>
can be interesting for a number of reasons:
<iframe>
.Regardless of your use-case: you can embed THEOplayer through an iframe on first-party and third-party domains.
The goal of this guide is to help you embed THEOplayer through an <iframe>
by going through the following topics:
Implementation: which THEOplayer APIs are relevant and how can I achieve my use-case?
Just want to copy-paste code and view a live example? Skip to the demo.
An iframe is an HTML tag, the <iframe>
tag, which allows you to embed an HTML page (i.e. "a website") on your HTML page (i.e. "your website").
You come across iframes all the time when using the web.
(That YouTube video on that news website you just visited? That's an iframe. That Facebook or Twitter post which was embedded on that blog? That could also be an iframe. They are all HTML website pages which are embedded on another HTML website page.)
<iframe width="560" height="315" src="https://www.youtube.com/embed/GrOJkhIXifc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
The code snippet above represent an actual <iframe>
tag. Adding this code snippet to the HTML of your website would embed https://www.youtube.com/embed/GrOJkhIXifc, which is a YouTube video.
If you opened this link, you would see that it is a YouTube video which fits the entire size of your browser window.
As you can see, the embedded page is quite different from the "real" YouTube page.
When you design and develop a page which should be embedded through an <iframe>
, you optimize for this embedding use-case. Typically, your component (e.g. a video player) fills the entire browser window,
and thus has a width and height of 100%. (You set the width and height of the <iframe>
on your page, as can be seen from the above code snippet.)
We won't go into the pros and cons of using an <iframe>
in this article. We do argue that you should try to avoid using iframes, because iframes can be evil and can cause usability issues.
From our experience, most services and companies are trying to phase out iframes, and are instead embedding JavaScript code to render the same result.
When embedding THEOplayer through an <iframe>
tag, you need to do a couple of things:
You can easily allow embedding by setting the isEmbeddable
-flag in the THEOplayer's PlayerConfiguration
to true
, as demonstrated by the code snippet below.
let playerConfiguration = {
// ...
libraryLocation: "</path-to-library>/",
license: "your-license-here",
isEmbeddable: true,
// ...
}
let player = new THEOplayer.Player(element, playerConfiguration)
Embedding THEOplayer through an <iframe>
tag is disabled by default. Why?
<iframe>
tag.<iframe>
tag, then third-parties could
potentially piggyback for free on your (commercial) license if they reverse-engineer your approach.If you want to allow your viewers to open your iframe in fullscreen, then you must explicitly enable the allowfullscreen
-attribute.
<iframe
src="player.html"
frameborder="0"
scrolling="no"
width="100%"
height="100%"
allowfullscreen=""
>
</iframe>
On top of this, you want to configure the allow
-attribute and track its evolution.
<iframe
src="player.html"
frameborder="0"
scrolling="no"
width="100%"
height="100%"
allow="accelerometer; autoplay; encrypted-media; fullscreen; gyroscope; picture-in-picture"
allowfullscreen=""
>
</iframe>
Through this attribute, you can allow your iframe to access a set of features, like autoplay, Picture-in-Picture, DRM, and more.
The previous section explains how you can make THEOplayer compatible with an <iframe>
, but it doesn't explain the possible approaches for loading content and configurations.
What do we mean with this? When you are embedding THEOplayer, you still need a mechanism to configure a stream URL and toggle settings like autoplay and mute.
You don't want to create one HTML page per stream and combination of settings. Instead, you want to be able to embed one HTML page which is capable of dynamically configuring your stream and settings.
There are at least three approaches to pass along your stream URL and settings:
https://cdn.theoplayer.com/demos/iframe/theoplayer.html?autoplay=false&muted=false&preload=none&src=//cdn.theoplayer.com/video/elephants-dream/playlist.m3u8
.
On your iframe page, you (i.e. either your front-end or back-end) would read out these four query parameters (or GET parameters), and then use those values to set up your THEOplayer instance and configure your stream URL and settings.https://cdn.theoplayer.com/demos/iframe/video-123
.
On your iframe page, you would read out this identifier (e.g. video-123
), and do a call to a content management system (CMS) requesting data matching your identifier. This CMS would then return the actual stream URL and settings. You use this response to set up your THEOplayer instance and configure your stream URL and settings.https://cdn.theoplayer.com/demos/iframe/video-123?autoplay=false&muted=false&preload=none
.
On your iframe page, you would read out this identifier and the query parameters, and use the identifier to fetch the stream URL through a CMS, but configure your settings through the values of your query parameters.Every approach has its trade-offs. Using a CMS is useful to avoid third-parties from loading their own streams through your iframe setup, but it does require you to spend resources on a CMS.
As hinted in the <iframe>-section, using iframes can incur some limitations. Some of those limitations can be addressed, and some of those cannot due to technological platform constraints.
Styling the <iframe>
element on your page, and the actual page behind the <iframe>
, can be a challenge.
Additionally, you may want to alter your user experience by implementing messaging between your page and the embed page.
Styling your <iframe>
element is a breeze if you're using a fixed width and height: you can directly configure those through the width
and height
attributes as demonstrated below.
<iframe
src="player.html"
frameborder="0"
scrolling="no"
width="800px"
height="450px"
allowfullscreen=""
>
</iframe>
However, more common is to rely on responsive styling, and not knowing your specific width and height. On top of wanting a responsive iframe, you usually want to respect the aspect ratio of your video.
Basically, you want your <iframe>
container to automatically -and appropriately- scale when the size of your browser window changes.
<div style="position:relative;padding-bottom:56.25%;">
<iframe
src="player.html"
frameborder="0"
scrolling="no"
width="100%"
height="100%"
style="width:100%;height:100%;position:absolute;left:0;top:0;"
>
</iframe>
</div>
The above snippet demonstrates how you can achieve this.
<div>
container, and you want to give it a relative
position and configure the aspect ratio in the padding-bottom
.
We've set the value of padding-bottom
to 56.25%, because to get to an aspect ratio of 16:9, you have to divide 9/16, which is 0.5625. If you want an aspect ratio of 3:4,
you would use 75%, because 4/3=0.75. (And so on.)<iframe>
element. We've used style="width:100%;height:100%;position:absolute;left:0px;top:0px;"
to make it fit in the wrapper.frameborder="0"
and disable scrolling by specifying scrolling="no"
.width="100%"
and height="100%"
.Of course, rather than using inline styling through the style
attribute, you could also achieve the same through CSS.
And, of course: this is not the only way to style your iframe element, but just one of the many ways.
You usually want your video player to fit the full width and height of your browser window, because it should fill the entire iframe container element.
<html>
<head>
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<style>
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.theoplayer-container {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="theoplayer-container video-js theoplayer-skin"></div>
</body>
</html>
The above snippet demonstrates a way to achieve this.
width
and height
of 100%.<div>
in the above snippet, to fill the entire document by setting its width
and height
to %100.You may have a need for messaging between your parent page and your embedded page.
You can achieve this with cross-document messaging and the postMessage
API. Please refer to the resources below to learn more on this:
The video player below this paragraph is embedded through an <iframe>
tag.
We selected the "direct approach" by leveraging query parameters, as demonstrated by the code snippet below.
<div style="position:relative;padding-bottom:56.25%;">
<iframe
src="https://cdn.theoplayer.com/demos/iframe/theoplayer.html?autoplay=false&muted=false&preload=none&src=//cdn.theoplayer.com/video/elephants-dream/playlist.m3u8"
title="Embedded THEOplayer"
frameborder="0"
scrolling="no"
width="100%"
height="100%"
style="width:100%;height:100%;position:absolute;left:0;top:0;"
allow="accelerometer; autoplay; encrypted-media; fullscreen; gyroscope; picture-in-picture"
allowfullscreen=""
>
</iframe>
</div>
If we had configured a different src
-value, like https://cdn.theoplayer.com/demos/iframe/theoplayer.html?autoplay=false&muted=false&preload=none&src=//cdn.theoplayer.com/video/big_buck_bunny/big_buck_bunny_metadata.m3u8
, then it would have loaded a different video.
Note that unmuted autoplay may not be possible, and that you may have to combat autoplay policies.
You can see the code of the iframe HTML page at https://cdn.theoplayer.com/demos/iframe/theoplayer.html, or in the code snippet below.
<html>
<head>
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<link
rel="stylesheet"
type="text/css"
href="/path/to/libraryLocation/ui.css"
/>
<script src="/path/to/libraryLocation/THEOplayer.js"></script>
<style>
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.theoplayer-container {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="theoplayer-container video-js theoplayer-skin"></div>
<script>
// https://stackoverflow.com/a/901144/588833
// function to get URL query parameters by name
function getParameterByName(name, url) {
if (!url) url = window.location.href
name = name.replace(/[\[\]]/g, "\\$&")
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url)
if (!results) return null
if (!results[2]) return ""
return decodeURIComponent(results[2].replace(/\+/g, " "))
}
// initialize THEOplayer instance
var element = document.querySelector(".theoplayer-container")
var player = new THEOplayer.Player(element, {
libraryLocation: "/path/to/libraryLocation/",
license: "your-license-here",
ui: {
width: "100%",
height: "100%",
},
isEmbeddable: true,
})
// get query parameter values
var autoplay =
getParameterByName("autoplay") &&
getParameterByName("autoplay") == "true"
var muted =
getParameterByName("muted") && getParameterByName("muted") == "true"
var preload = getParameterByName("preload")
var src = getParameterByName("src")
// set settings and stream URL
player.autoplay = autoplay
player.muted = muted
player.preload = preload
player.src = src
</script>
</body>
</html>