AMP

Important: this documentation is not applicable to your currently selected format email!

amp-video-iframe

Description

Embeds an iframe containing a video player.

 

Required Scripts

<script async custom-element="amp-video-iframe" src="https://cdn.ampproject.org/v0/amp-video-iframe-0.1.js"></script>

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.

  1. If you'd like to include a video directly on the AMP document, you should use amp-video.

  2. 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).

  3. 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 using amp-iframe in that it enables Video Features on AMP. See behavior below for more details.

  4. If you're a 3rd party video vendor, you can use amp-video-iframe to provide a simple way for authors to embed video.

Behavior

amp-video-iframe has several important differences from vanilla iframes and amp-iframe.

  • By default, an amp-video-iframe is sandboxed.

  • 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 URL to an image displayed while the video loads. It's recommended to always set this attribute for best perceived performance.
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.
data-param-* All data-param-* attributes are added as query parameters to the iframe's src. They may be used to pass custom values through to the player document.
Keys and values will be URI encoded. Keys will be camel cased.
  • data-param-foo="bar" becomes &foo=bar
  • data-param-channel-id="SOME_VALUE" becomes &channelId=SOME_VALUE

Usage

Include an amp-video-iframe on your AMP document:

<amp-video-iframe
  layout="responsive"
  width="16"
  height="9"
  src="/my-video-player.html"
  poster="/my-video-poster.jpg"
>
</amp-video-iframe>

my-video-player.html is the inner document loaded inside the frame that plays the video. This document must include and bootstrap an integration script so that the AMP document including the <amp-video-iframe> can coordinate the video's playback.

Third-party video vendors

If you're a vendor that does not provide a custom video player component, you can integrate with AMP in the form of an amp-video-iframe configuration, so authors can embed video provided through your service.

For most video providers, amp-video-iframe provides enough tools for common playback actions (see methods and events). Refer to the vendor player spec for more details on whether you can use amp-video-iframe or you should build a third-party player component instead.

As a vendor, you can serve a generic integration document that references provided videos via URL parameters. AMP authors who use your video service only need to include an <amp-video-iframe> tag in their documents:

<!--
  data-param-* attributes are added to src and poster, so this would use the
  following composed urls:

  src: https://vendor.example/amp-video-iframe
      ?videoid=MY_VIDEO_ID
      &channelid=MY_CHANNEL_ID

  poster: https://vendor.example/poster.jpg
      ?videoid=MY_VIDEO_ID
      &channelid=MY_CHANNEL_ID
-->
<amp-video-iframe
  layout="responsive"
  width="16"
  height="9"
  src="https://vendor.example/amp-video-iframe"
  poster="https://vendor.example/poster.jpg"
  data-param-videoid="MY_VIDEO_ID"
  data-param-channelid="MY_CHANNEL_ID"
>
</amp-video-iframe>

The src and poster URLs are appended with data-param-* attributes as query string.

The /amp-video-iframe document bootstraps the integration script so that the AMP document can coordinate with the player.

If you're a vendor hosting an integration document, feel free to contribute a code sample to this page, specifying your provided src and usable data-param-* attributes.

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 JW Player 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 JW Player

Default supported events: ad_end/ad_start, canplay, error, muted/unmuted, pause/playing

Default supported methods: pause/play, mute/unmute, hidecontrols/showcontrols, fullscreenenter/fullscreenexit

The amp object knows how to setup a JwPlayer instance by using listenTo('jwplayer'). If you're embedding your player using a video-specific script, you only need to register Jwplayer usage:

<script src="https://cdn.jwplayer.com/players/UVQWMA4o-kGWxh33Q.js"></script>
<script>
  (window.AmpVideoIframe = window.AmpVideoIframe || []).push(function (
    ampIntegration
  ) {
    ampIntegration.listenTo('jwplayer');
  });
</script>

Otherwise, pass in your JwPlayer instance through the signature amp.listenTo('jwplayer', instance):

(window.AmpVideoIframe = window.AmpVideoIframe || []).push(function (
  ampIntegration
) {
  ampIntegration.listenTo('jwplayer', jwplayer('my-video'));
});
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 and pause are required for either/both of playback actions or autoplay.

  • mute and unmute are required for autoplay.

  • showcontrols and hidecontrols 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 and fullscreenexit are required for best possible UX. For example, for rotate-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}.

getConsentData(callback)

The iframe document can request user consent data when the host document uses amp-consent.

If you only require to block the iframe from loading when consent is not given, it's preferable to set the data-block-on-consent attribute instead of calling getConsentData()

The callback passed to the function will be executed with an object containing the following properties:

{
  "consentMetadata": {
    "consentStringType": 2,
    "additionalConsent": "additional-consent-string",
    "gdprApplies": true,
    "purposeOne": true
  },
  "consentString": "accept-string",
  "consentPolicyState": 1,
  "consentPolicySharedData": {
    "tfua": true,
    "coppa": true
  }
}

For example, a video could be blocked from loading until consentPolicyState is available:

// Create and listen to video once consent is given on the parent page:
integration.getConsentData(function(consent) {
  if (
    consent.consentPolicyState !== /* SUFFICIENT */ 1 &&
    consent.consentPolicyState !== /* UNKNOWN_NOT_REQUIRED */ 3
  ) {
    integration.postEvent('error');
    return;
  }

  // You can use other consent values to map video consent logic as well.
  console.log(consent);

  // Initialize video and integration once consent is available.
  var video = document.createElement(video);
  video.style = "width: 100vw; height: 100vh";
  video.src = document.body.getAttribute('data-videoid');
  document.body.appendChild(video);

  integration.method('play', function() {
    video.play();
  });

  // etc...
});

A complete example using getConsentData is available as well.

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": "https://example.com/canonical.html",
  "sourceUrl": "https://example.com/amp.html",
  "title": "My host document's title",
  "lang": "en"
}
  • canonicalUrl is the canonical URL.

  • sourceUrl is the AMPHTML URL.

  • title is the source URL's document title at the time the <amp-video-iframe> is initialized. null when the component is loaded in a shadow root.

  • lang is the source URL's language specified in <html ⚡️ lang="en">. null when the component is loaded in a shadow root.

  • jsonLd includes the parsed content of a JSON-LD tag, if present.

Need more help?

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