In this codelab, you'll learn how to embed and integrate YouTube videos in your app. You'll be able to control the player and retrieve data from the iFrame API as well as setup and implement event listeners for player events.

What you'll learn

What you'll need

How will you use this tutorial?

Read it through only Read it and complete the exercises

How would rate your experience with building websites?

Novice Intermediate Proficient

Download the Code

You can download all of the code for this codelab, by clicking the following button:

Download source code

Unpack the downloaded zip file. This will unpack a root folder (api-samples-master), which contains samples for all YouTube APIs. We'll be working with the player folder for this codelab, which contains all of the resources you will need.

Setup your work area

Change your current directory to player in your api-samples-master project folder (this is where you'll do all your work for this codelab). On a Linux or Mac OS X system, the following command sequence will do the trick:

$ cd api-samples-master/player
$ ls
index.html demo.js controls.html controls.js events.html events.js

Install and verify web server

While you're free to use your own web server, this codelab is designed to work well with the Chrome Web Server. If you don't have that app installed yet, you can install it from the Chrome Web Store.

Install Web Server for Chrome

After installing the Web Server for Chrome app, click on the Apps shortcut on the bookmarks bar:

Screen Shot 2016-04-11 at 4.01.20 PM.png

In the ensuing window, click on the Web Server icon:

Screen Shot 2016-02-18 at 11.45.19 AM.png

You'll see this dialog next, which allows you to configure your local web server:

Screen Shot 2016-02-18 at 11.48.14 AM.png

Click the choose folder button, and select the player folder in the repository you just downloaded. This will enable you to serve your work in progress via the URL highlighted in the web server dialog (in the Web Server URL(s) section).

Under Options, check the box next to "Automatically show index.html", as shown below:

Screen Shot 2016-02-18 at 11.56.30 AM.png

Then stop and restart the server by sliding the toggle labeled "Web Server: STARTED" to the left and then back to the right.

Screen Shot 2016-02-18 at 12.22.18 PM.png

Now visit your work site in your web browser (by clicking on the highlighted Web Server URL) and you should see a page that looks like this:

Go ahead and try out the demo to see how player parameters change when you trigger changes from the player as well as through the API using the tables below. The page uses the iFrame API to interact with the YouTube player on the page to perform basic commands (play/pause, mute, rate, quality, etc.) as well as retrieve information like the percentage of the video that has been loaded.

Load a new video

You can also load and cue other videos by entering the YouTube video's ID. You can find any YouTube video's ID by inspecting the URL and selecting the value of the "v" parameter:

Try using me91AGSVsyo to change the video being displayed or find your favorite video on and copy it's video ID. Paste the video ID into the textbox next to the button labeled LOAD and then click on the LOAD or CUE button. The new video should now be loaded and playing or cued with the thumbnail of the video displayed in the YouTube player.

Now that you've seen the YouTube iFrame API in action, it's time to dig deeper into how it works. First let's look at some basic player controls and data. When you're ready to go click on the link labeled Player Controls and Data at the top of the demo app page.

4 (1).gif

Alright. Let's take a look at what just happened. You should have seen a video start playing, pause after a couple seconds, a new video start playing and then that video stop playing after a couple seconds. You can find the code for this page in the player_control.html and player_control.js files in the player directory. Let's dive in!

Code Setup


<!DOCTYPE html>
    <!-- page title -->
    <title>YouTube in Your App</title>
    <!-- Style imports for Material Design Lite -->
    <link rel="stylesheet" href=""><link rel="stylesheet" href=""><meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- This code loads the iFrame Player API code asynchronously.-->
    <script src = ""></script>
    <!-- This is the source of the Javascript for the demo -->
    <script src="player_control.js"></script>

    <!-- Header -->
    <div class="mdl-layout mdl-js-layout mdl-layout--fixed-header"><header class="mdl-layout__header"><div class="mdl-layout__header-row"><span class="mdl-layout-title">YouTube in Your App</span><div class="mdl-layout-spacer"></div><nav class="mdl-navigation"><a class="mdl-navigation__link" href="index.html">Demo</a><a class="mdl-navigation__link" href="#">Player Controls and Data</a><a class="mdl-navigation__link" href="event_listeners.html">Event Listeners</a></nav></div></header>
    <!-- Page contents -->
    <main class="mdl-layout__content">
    <!-- The iframe video player will replace this <div> tag. -->  <div class="mdl-cell mdl-cell--7-col">
    <div id="player"></div></div>

    <!-- Table for displaying data from a function you will implement -->
    <div class="mdl-cell mdl-cell--7-col"><table class="mdl-data-table"><tr><td>Content:</td><td><span id="content">(None)</span></td></tr></table></div></div>

At first glance player_control.html is just some boiler plate HTML but there are 3 important lines here to enable the YouTube player to work its magic. The first is:

This line loads the YouTube player onto the page and replaces div with the ID of player with the a YouTube iFrame player. The extra control magic that automated playback, pausing, stopping and video loading is in the external Javascript file player_control.js.

Player Configuration


var player;
// Callback for when the YouTube iFrame player is ready
function onYouTubeIframeAPIReady() {
  player = new YT.Player('player', {
    // Set Player height and width
    height: '390',
    width: '640',
    // Set the id of the video to be played
    videoId: 'M7lc1UVf-VE',
    // Setup event listeners
    // These are covered in the next section
    events: {
      'onReady': onPlayerReady

The first part of player_control.js sets up the YouTube player. The line

in player_control.html imports the YouTube player but it doesn't tell it what video to play, or even what size the player should be! The first line sets up the variable player as a global variable so functions can access it later on.

Next, the function onYouTubeIframeAPIReady is defined. onYouTubeIframeAPIReady is a special function that is called once the iFrame has loaded and is ready for API calls. Once the iFrame API is ready a new YT.Player with a defined height and width and videoId is created. The events object sets up event listeners which are covered in the next section. For now all we need to know is that once the player is ready the function onPlayerReady will be called.

Calling the iFrame API


function onPlayerReady (){
  setTimeout(pauseVideo, 4000);
  setTimeout(loadNewVideo, 6000);
  setTimeout(stopVideo, 8500)

The next part of player_control.js is where the automated playback and video loading is implemented. The function onPlayerReady is called when the player is ready and calls player.playVideo();. This statement does exactly what you'd think it would: it plays the video! Next the functions pauseVideo , loadNewVideo and stopVideo are called with increasing timeouts. These functions are defined as the simple player statements player.pauseVideo(); , player.loadVideoById("me91AGSVsyo"); and player.stopVideo(); respectively.


Use the scaffolding present in the getContent function to implement one the the APIs documented below:

Player Function



Usage: player.getVideoLoadedFraction()

Returns a number between 0 and 1 corresponding to the fraction of the video that is loaded.


Usage: player.getCurrentTime()

Returns a number corresponding to number of seconds that have elapsed in the current video.


Usage: player.getVolume()

Returns a number between 0 and 100 corresponding to current volume level.


Usage: player.getPlaybackRate()

Returns a number corresponding to the rate of the play of the video. Default is 1, options may include 0.5, 2, etc.

If you've done everything properly you should see the data you've retrieved from the iFrame API just below the YouTube player. For all the methods supported by the iFrame API take a look at the documentation.

The first step in creating dynamic video experiences in your app is handling player events. Let's do that now. Take a look at the event_listeners.html and event_listeners.js files (Click on the link "Event Listeners" on the top of the demo page to see how the files are rendered)


var player;
// Callback for when the YouTube iFrame player is ready
function onYouTubeIframeAPIReady() {
  player = new YT.Player('player', {
    // Set Player height and width
    height: '390',
    width: '640',
    // Set the id of the video to be played
    videoId: 'M7lc1UVf-VE',
    events: {
      'onReady': onPlayerReady
      // You can add more event listeners here

function onPlayerReady (){
  //add onStateChange event handler

  //add your own rate listener below:


There are two ways to create event listeners and the code above demonstrates both of them. You can list the event and the event handler function name as the attributes of the events object passed to a new player or call the addEventListener method on the player object after it has been created. addEventListener take two string arguments: the name of the event and the name of the function to handle the event. You can also remove event listeners using the removeEventListener function using the same parameters. The following events are available for event listener registration:




This event fires whenever a player has finished loading and is ready to begin receiving API calls. Your application should implement this function if you want to automatically execute certain operations, such as playing the video or displaying information about the video, as soon as the player is ready.


This event fires whenever the player's state changes. The data property of the event object that the API passes to your event listener function will specify an integer that corresponds to the new player state. Possible values are:


This event fires whenever the video playback quality actually changes and not when quality change is requested.


This event fires whenever the video playback rate changes and not when a rate change is requested.


This event fires if an error occurs in the player. The API will pass an event object to the event listener function.


This event is fired to indicate that the player has loaded (or unloaded) a module with exposed API methods.

Some events like onStateChange include a data property of the event object that the API passes to your event listener function that specifies data about the event. In the case of onStateChange an integer is passed that corresponds to the new player state. Possible values are:












Video cued

Namespaced variables are also available for this as seen in event_listeners.js:


function onPlayerStateChange(event){
  // Get current state
  var state = "Current state: "
  if ( == YT.PlayerState.ENDED){
    state += "Ended";
  else if ( == YT.PlayerState.PLAYING){
    state += "Playing";
  else if ( == YT.PlayerState.PAUSED){
    state += "Paused";
  else if ( == YT.PlayerState.BUFFERING){
    state += "Buffering";
  else if ( == YT.PlayerState.CUED){
    state += "Cued";
  } else{
    state += "Unknown";

  // Update video state div
  document.getElementById('currentState').innerText = state;

When the player first loads a video, it will broadcast an unstarted (-1) event. When a video is cued and ready to play, the player will broadcast a video cued (5) event.

Create Your Own Event Listener

Implement the onPlaybackRateChange function in event_listener.js including creating an event listener that points to onPlaybackRateChange using the events object or the addEventListener function.

You're new ready to put YouTube into your app!

What we've covered

Next Steps

Learn More