Click here to see your recently viewed pages and most viewed pages.
Google Developers Academy

Embedding a YouTube Video Using the iframe Player

Learning objectives
  • Load the iframe Player API’s JavaScript code dynamically.
  • Queue up one or more callback functions to be invoked when the iframe Player API has loaded.
  • Use the onYouTubePlayerAPIReady callback to invoke the queued callback functions.
  • Load an embedded YouTube player on the current page and set specific player parameters.

The iframe Player is the preferred method of embedding YouTube videos, and it supports a JavaScript API for creating new embeds on a page. In this sample application, the iframe Player API will load dynamically at runtime, and, once it's available, it will invoke one or more callbacks to insert YouTube embedded players into the current page.

Load the iframe Player API at runtime

The YT.Player methods that make up the iframe Player API are defined in a JavaScript file located at You could statically link to the file with a <script> tag or load it dynamically when it's needed, as shown in the example below. The most efficient method for your application to retrieve the JavaScript file will depend on your use case.

We recommend that you check to see whether the iframe Player API has loaded by using the following expression: 'YT' in window && 'Player' in window.YT. That expression will evaluate to true if the iframe Player API is already available, in which case it does not need to be loaded again.

// Dynamic <script> tag insertion will load the iframe Player API on demand.
var scriptTag = document.createElement('script');
// This scheme-relative URL will use HTTPS if the host page is accessed via HTTPS,
// and HTTP otherwise.
scriptTag.src = '//';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag);

Queue callbacks to the invoked later

Since the chapter marker player might appear multiple times on a page, we queue up an array of callback functions that are invoked once the window.onYouTubePlayerAPIReady() function has been called. This works around the asynchronous nature of the JavaScript code while ensuring that each callback is only invoked once.

An anonymous function wraps the call to the insertPlayerAndAddChapterMarkers(params) function since we don’t want to execute the method right away. This technique saves the relevant state information for later execution.

// This code handles the situation where multiple ChapterMarkerPlayer.insert() calls are made
// before the iframe Player API has loaded. The code does so by maintaining an array of
// functions, each of which adds a specific player and chapters. The functions will be
// executed when onYouTubePlayerAPIReady() is invoked by the API.
window.ChapterMarkerPlayer.onYouTubePlayerAPIReadyCallbacks.push(function() {

Invoke queued callbacks after the API loads

When the iframe Player API loads, it automatically invokes the window.onYouTubePlayerAPIReady() function. Once that function is called, your application can safely call the methods exposed in the YT.Player namespace.

window.onYouTubePlayerAPIReady = function() {
  for (var i = 0; i < window.ChapterMarkerPlayer.onYouTubePlayerAPIReadyCallbacks.length; i++) {

Load a player on the page

Now that YT.Player is available, the code can create instances of the YouTube player on the page. Various parameters control the player's behavior, but in this example, videoId is the only required parameter. The other parameters all have default values, though those can be overridden by setting values in the params.playerOptions object.

// Calls the YT.Player constructor with the appropriate options to add the iframe player
// instance to a parent element.
// This is a private method that isn't exposed via the ChapterMarkerPlayer namespace.
function initializePlayer(containerElement, params) {
  var playerContainer = document.createElement('div');

  // Attempt to use any custom player options that were passed in via params.playerOptions.
  // Fall back to reasonable defaults as needed.
  var playerOptions = params.playerOptions || {};
  return new YT.Player(playerContainer, {
    // Maintain a 16:9 aspect ratio for the player based on the width passed in via params.
    // Override can be done via params.playerOptions if needed
    height: playerOptions.height ||
    width: playerOptions.width || width,
    // Unless playerVars are explicitly provided, use a reasonable default of { autohide: 1 },
    // which hides the controls when the mouse isn't over the player.
    playerVars: playerOptions.playerVars || { autohide: 1 },
    videoId: params.videoId,
    events: {
      onReady: playerOptions.onReady,
      onStateChange: playerOptions.onStateChange,
      onPlaybackQualityChange: playerOptions.onPlaybackQualityChange,
      onError: playerOptions.onError

Try it out

View Full Source Code

Live Demo