amp-video-iframe
Displays an iframe containing a video player.
Required Script | <script async custom-element="amp-video-iframe" src="https://cdn.ampproject.org/v0/amp-video-iframe-0.1.js"></script> |
Supported Layouts | fill, fixed, fixed-height, flex-item, intrinsic, nodisplay, responsive |
When should I use this?
This component is useful if you've built your own Javascript-based video player and would like to embed it in an AMP document, or if your player is provided by a third party not supported by the AMP component library.
-
If you'd like to include a video directly on the AMP document, you should use
amp-video
. -
If you're using a common 3rd party like Youtube, Vimeo or others supported in AMP, you should use their supported component (e.g.
amp-youtube
,amp-vimeo
). -
If you've built a custom player or are using one provided by an unsupported 3rd party, you should use
amp-video-iframe
. This is different from usingamp-iframe
in that it enables Video Features on AMP. See behavior below for more details.
Behavior
amp-video-iframe
has several important differences from vanilla iframes and amp-iframe
.
-
By default, an
amp-video-iframe
is sandboxed (see details). -
amp-video-iframe
implements all Video Features, like autoplay, minimize-to-corner and rotate-to-fullscreen. -
amp-video-iframe
must only request resources via HTTPS. -
amp-video-iframe
is not scrollable.
In short, amp-video-iframe
plugs AMP video features into an embedded document that hosts a video player.
Usage of amp-video-iframe for advertising
amp-video-iframe
must not be used for the primary purpose of displaying advertising. It is OK to use amp-video-iframe
for the purpose of displaying videos, where part of the videos are advertising. This AMP policy may be enforced by not rendering the respective iframes.
Advertising use cases should use amp-ad
instead.
The reasons for this policy are that:
-
amp-video-iframe
enforces sandboxing and the sandbox is also applied to child iframes. This means landing pages may be broken, even if the ad itself appears to work. -
amp-video-iframe
has no controlled resize mechanism.
Attributes
src (required) | The src attribute behaves mainly like on a standard iframe with one exception: the #amp=1 fragment is added to the URL to allow
source documents to know that they are embedded in the AMP context. This fragment is only added if the URL specified by src does
not already have a fragment. |
poster (required) | Points to an image URL that will be displayed while the video loads. |
autoplay | If this attribute is present, and the browser supports autoplay, the video will be automatically played as soon as it becomes visible. There are some conditions that the component needs to meet to be played, which are outlined in the Video in AMP spec. |
common attributes | This element includes common attributes extended to AMP components. |
dock | Requires amp-video-docking extension. If this attribute is present and the video is playing manually, the video will be "minimized" and fixed to a corner or an element when the user scrolls out of the video component's visual area.
For more details, see documentation on the docking extension itself. |
implements-media-session | Set this attribute if the document inside the iframe implements the MediaSession API independently. |
implements-rotate-to-fullscreen | Set this attribute if the document inside the iframe implements rotate-to-fullscreen independently. |
referrerpolicy | The referrerpolicy to be set on the iframe element. |
Usage
Include an amp-video-iframe
on your AMP document:
<amp-video-iframe layout="responsive" width="16" height="16" src="/my-video-player.html" poster="/my-video-poster.jpg" > </amp-video-iframe>
Integration inside the frame
In order for the video integration to work, the embedded document (e.g. my-video-player.html
) must include a small library:
<script async src="https://cdn.ampproject.org/video-iframe-integration-v0.js" ></script> <!-- Wait for API to initialize --> <script> (window.AmpVideoIframe = window.AmpVideoIframe || []).push( onAmpIntegrationReady ); function onAmpIntegrationReady(ampIntegration) { // `ampIntegration` is an object containing the tools required to integrate. // This callback specifies how the AMP document and the iframed video document // talk to each other. // YOU NEED TO IMPLEMENT THIS. See below. } </script>
Note that this library is separate from the extension code (amp-video-iframe-0.1.js
), because
it lives on the non-AMP document that is iframed.
The provided callback specifies how the AMP document and the iframed video document talk to each other. You need to implement a set of playback methods and event dispatchers to plug these together. For common video frameworks, the integration script provides readymade playback support, but you can also write a custom integration yourself if you don't use any of the tools for which support is available.
Never play the video inside the frame automatically. Instead, you should support the integration script and use the amp-video-iframe
tag with the autoplay
attribute. The AMP component will automatically send the necessary signals to your iframe to autoplay for a better user experience.
Readymade integrations
If you're using a common video framework like JwPlayer or Video.js, you can call listenTo()
for a basic, readymade integration. These integrations support all playback and UI controls when the framework provides them, see each for supported methods.
Depending on which video framework you use, you'll call the listenTo
method differently. Read on the specific APIs below.
You can additionally use custom integration methods if you require a feature not available in readymade implementations.
For JwPlayer
Default supported events: ad_end
/ad_start
, canplay
, error
, muted
/unmuted
, pause
/playing
Default supported methods: pause
/play
, mute
/unmute
, hidecontrols
/showcontrols
, fullscreenenter
/fullscreenexit
Pass in your jwplayer
instance object
through the signature ampIntegration.listenTo('jwplayer', myJwplayer)
. The ampIntegration
object then knows how
to setup the player through the instance API.
function onAmpIntegrationReady(ampIntegration) { var myJwplayer = jwplayer('my-video'); ampIntegration.listenTo('jwplayer', myJwplayer); }
For Video.js
Default supported events: canplay
, ended
, muted
/unmuted
, pause
/playing
Default supported methods: pause
/play
, mute
/unmute
, hidecontrols
/showcontrols
, fullscreenenter
/fullscreenexit
Pass in your <video>
element
through the signature ampIntegration.listenTo('videojs', myVideo)
. Video.js overloads this element to provide methods
that the ampIntegration
object uses to setup the player.
function onAmpIntegrationReady(ampIntegration) { var myVideo = document.querySelector('#my-video'); ampIntegration.listenTo('videojs', myVideo); }
listenTo
initializes the Video.js instance on the <video>
element if required. This uses the global videojs
function by default. If your page provides the initializer differently, you must pass it in as the third argument:
function onAmpIntegrationReady(ampIntegration) { var myVideo = document.querySelector('#my-video'); // ampIntegration initializes player with `myVideojsInitializer(myVideo)` ampIntegration.listenTo('videojs', myVideo, myVideojsInitializer); }
Custom integrations
If you don't use any of the video frameworks supported by default, you must write a custom implementation to talk to AMP's video management.
These are the communication methods available:
method
to control playback.postEvent
to inform the host document about playback events.getIntersection
to get video's viewability on the host document.getMetadata
to get information about the host document.
If you use a supported framework, it's possible to have more fine-grained control over the default implementation by using these same methods.
method(name, callback)
Implements a method that calls playback functions on the video. For example:
ampIntegration.method('play', function() { myVideo.play(); });
These are methods that should be implemented:
play
pause
mute
unmute
showcontrols
hidecontrols
fullscreenenter
fullscreenexit
You can choose to only implement this interface partially, with a few caveats:
-
play
andpause
are required for either/both of playback actions or autoplay. -
mute
andunmute
are required for autoplay. -
showcontrols
andhidecontrols
are required for the best possible UX. For example, when minimizing the video to the corner, a custom controls overlay is shown. If you don't provide methods to hide and show controls, two sets of controls could be displayed at the same time, which is a poor user experience. -
fullscreenenter
andfullscreenexit
are required for best possible UX. For example, forrotate-to-fullscreen
or the fullscreen button on minimized video.
postEvent(name)
Posts a playback event to the frame. For example:
myVideoElement.addEventListener('pause', function() { ampIntegration.postEvent('pause'); });
The valid events are as follows.
Event | Description |
canplay |
Triggered when your player is ready. This event must be posted before the player can become interactive. |
playing |
Triggered when your player has started playing a video after load or pause. |
pause |
Triggered when your video has been paused. |
ended |
Triggered when your video has ended playback. Note that you must also
post a pause event alongside the ended event.
|
muted |
Triggered when your video has been muted. |
unmuted |
Triggered when your video has been unmuted. |
ad_start |
Triggered when a pre/mid/post-roll ad is playing. This hides the autoplay shim displayed on the video. |
ad_end |
Triggered when a pre/mid/post-roll ad has ended. This re-displays the autoplay shim if the user has not yet interacted with the video. |
postAnalyticsEvent(eventType[, vars])
Posts a custom analytics event to be consumed by amp-analytics
. The
eventType
must be prefixed with video-custom-
to prevent naming collisions
with other analytics event types.
This method takes an optional vars
param that should define an object with
custom variables to log. These are available as VIDEO_STATE
, keyed by name
prefixed with custom_
, i.e. the object {myVar: 'foo'}
will be available as
{'custom_myVar': 'foo}
.
getIntersection(callback)
Gets the intersection ratio (between 0 and 1) for the video element. This is useful for viewability information, e.g.
// Will log intersection every 2 seconds setInterval(function() { integration.getIntersection(function(intersection) { console.log('Intersection ratio:', intersection.intersectionRatio); }); }, 2000);
The callback
passed to the function will be executed with an object that looks
like this:
{"time": 33333.33, "intersectionRatio": 0.761}
⚠ This should be considered a low-fidelity reading. Currently, the value for
intersectionRatio
will be 0 as long as the video is under 50% visible. This
value is bound to change at any time, and the callbacks may be delayed or
debounced.
getMetadata()
Returns an object containing metadata about the host document:
{ "canonicalUrl": "foo.html", "sourceUrl": "bar.html" }
You've read this document a dozen times but it doesn't really cover all of your questions? Maybe other people felt the same: reach out to them on Stack Overflow.
Go to Stack Overflow Found a bug or missing a feature?The AMP project strongly encourages your participation and contributions! We hope you'll become an ongoing participant in our open source community but we also welcome one-off contributions for the issues you're particularly passionate about.
Go to GitHub