How to Control YouTube's Video Player with JavaScript

Demo Download

YouTube has become the standard way for delivering high quality video on the web. Sometimes, when you embed a video in your web application or landing page, you need a great deal of control on what and how is displayed. This is why we are going to show you how you can use the YouTube JavaScript Player API.

Initializing the player

The first step is to add a placeholder for the player and include the YouTube API.

<div id="video-placeholder"></div>

<script src="https://www.youtube.com/iframe_api"></script>

When the API is fully loaded, it looks for a global function called onYouTubeIframeAPIReady() which you should define. Inside it we will create a new instance of YouTube player. The first argument is the id of an HTML element we want to be replaced by the player, in our case that's video-placeholder. The second one is an object containing the player options:

  • The width and height of the player. These can be overwritten by applying CSS to #video-placeholder.
  • The id of the video we want to be embedded when the player loads. You can get this id from any YouTube link by taking the string after ?v= (e.g. youtube.com/watch?v=WwoKkq685Hk)
  • The playerVars object is a set of parameters. We made the color of the player white and created a playlist by providing two additional videos ids, separated by a coma. You can see a list of all available properties here.
  • The events object consists of event listeners and the functions they call. The API passes down an event object as the only attribute, containing the target and data. You can read more about events here.

The whole code look something like this:

var player;

function onYouTubeIframeAPIReady() {
    player = new YT.Player('video-placeholder', {
        width: 600,
        height: 400,
        videoId: 'Xa0Q0J5tOP0',
        playerVars: {
            color: 'white',
            playlist: 'taJ60kskkns,FG0fTKAqZ5g'
        },
        events: {
            onReady: initialize
        }
    });
}

The initialize() function will be called when the player fully loads. It will start an interval, updating some of our controls every second.

function initialize(){

    // Update the controls on load
    updateTimerDisplay();
    updateProgressBar();

    // Clear any old interval.
    clearInterval(time_update_interval);

    // Start interval to update elapsed time display and
    // the elapsed part of the progress bar every second.
    time_update_interval = setInterval(function () {
        updateTimerDisplay();
        updateProgressBar();
    }, 1000)

}

Displaying current time and video duration

This is done by the updateTimerDisplay(), one of the function called every second. It takes advantage of the API's methods to give us adequate information about the video length.

// This function is called by initialize()
function updateTimerDisplay(){
    // Update current time text display.
    $('#current-time').text(formatTime( player.getCurrentTime() ));
    $('#duration').text(formatTime( player.getDuration() ));
}

function formatTime(time){
    time = Math.round(time);

    var minutes = Math.floor(time / 60),
    seconds = time - minutes * 60;

    seconds = seconds < 10 ? '0' + seconds : seconds;

    return minutes + ":" + seconds;
}

Methods are called using the player object we created in the begging. We can get how many seconds into the video we are in with getCurrentTime(), and the total duration of the video with getDuration(). Both function will return second which we format correctly to look like time and then write into the DOM.

Progress Bar

This is done using the player.seekTo(sec) function, which jumps the video to the seconds provided in the parameter.

To demonstrate this we've made our own version of YouTube's progress bar, using an input field of type range. When we click anywhere on it, we take the inputs value, witch gives us a percentage. We then use this percentage to calculate what progress we want made to the video and skip to the according seconds.

$('#progress-bar').on('mouseup touchend', function (e) {

    // Calculate the new time for the video.
    // new time in seconds = total duration in seconds * ( value of range input / 100 )
    var newTime = player.getDuration() * (e.target.value / 100);

    // Skip video to new time.
    player.seekTo(newTime);

});

The code above allows us to control the video, but we also want the progress bar to move automatically as the video progresses. To understand how we do this, go back to the initialize() function and more specifically its every-second interval and updateProgressBar().

// This function is called by initialize()
function updateProgressBar(){
    // Update the value of our progress bar accordingly.
    $('#progress-bar').val((player.getCurrentTime() / player.getDuration()) * 100);
}

Playback Controls

Nothing out of the ordinary here. Just make two buttons and call the needed method on click.

$('#play').on('click', function () {
    player.playVideo();
});

$('#pause').on('click', function () {
    player.pauseVideo();
});

Sound Options

We can create a mute toggle button using the provided getter and setter methods of the player.

$('#mute-toggle').on('click', function() {
    var mute_toggle = $(this);

    if(player.isMuted()){
        player.unMute();
        mute_toggle.text('volume_up');
    }
    else{
        player.mute();
        mute_toggle.text('volume_off');
    }
});

If we want to set the volume using a percentage we can use a number input field and the setVolume() method. It will automatically validate the provided parameter, so we don't have to worry about passing it floating values or numbers out of the [0 : 100] interval.

$('#volume-input').on('change', function () {
    player.setVolume($(this).val());
});

Other Player Settings

Changing Playback Speed

The player.setPlaybackRate() method expects one of the following as its parameter:

  • 0.25
  • 0.5
  • 1
  • 1.5
  • 2

Create a <select> element in the HTML and set the speeds as it <option> children. User interaction with the select will result in change of the speed rate only for the currently playing video and will be reset to the default (speed of 1) when the next one starts.

$('#speed').on('change', function () {
    player.setPlaybackRate($(this).val());
});

Changing Video Quality

Altering the video quality works in a very similar way to altering the speed. The method for this is setPlaybackQuality() and the argument it expects is one of these strings:

  • highres
  • hd1080
  • hd720
  • large
  • medium
  • small

Note that this function only suggest what quality should be used as that highly depends on the internet connection and video itself.

$('#quality').on('change', function () {
    player.setPlaybackQuality($(this).val());
});

Playlists

We can play the next or previous video in a playlist using these methods form the API.

$('#next').on('click', function () {
    player.nextVideo()
});

$('#prev').on('click', function () {
    player.previousVideo()
});

If you want to play a specific video from the playlist, use player.playVideoAt(index), where index is an integer specifying which video to play, 0 being the first one.

Queue Video Dynamically

The last thing we are going to demonstrate, is how to dynamically add new videos to the player. If you check our our demo, in the bottom you'll see three thumbnails for cat videos. We added their YouTube links as data-attributes and when any of them gets clicked, the chosen video will be loaded into the player.

$('.thumbnail').on('click', function () {

    var url = $(this).attr('data-video-id');

    player.cueVideoById(url);

});

Conclusion

This wraps up our tutorial! We hope that you found this tutorial useful. If you wish to learn more about the YouTube API, check out these resources:

  • YouTube Iframe Player API Reference - here.
  • YouTube Player supported parameters - here.
  • YouTube Developers Live: Embedded Web Player Customization - here.
Bootstrap Studio

The revolutionary web design tool for creating responsive websites and apps.

Learn more

Related Articles

great tutorial. Thanks for sharing.

Been trying to figure out how to use the api scripts but make the size responsive for various window sizes, instead of using static width and height. Thoughts?

Mubeen Ali

Can i play video automatically, on page load?

Danny Markov

Yes, you can!
The documentation for the API has a nice example about this:

https://developers.google.com/youtube/iframe_api_reference#Events

This is great! How can we make the Youtube video a full-width responsive header and hide the usual Youtube chrome? I would just put the mute toggle button over top and be all set. I got the sound/mute button working great, just can't figure out how to make the video full-width and hide the Youtube chrome.

Hi Guys,

I just want to add my custom subtitles file along with youtube video.

It could be great for us if anyone have any suggestion on same?

Thanks
KK

Hi Danny,

Great tutorial, I finished a Youtube player today in no time thanks to your work, thank you very much.

Cheers,

Diplo

I have an existing iframe element in my html, and existing functions in javascript. I would like to allow these functions to pause and play the video in the iframe, is there a way that I can do this without generating a new iframe in the javascript?
also the iframe src has the enablejsapi=1

i'm trying to do research on whether to use gwd-youtube or iframe api.

on thing i might be stuck for the iframe api, on is if there are events to capture

viewed0percent
viewed25percent
viewed50percent
...

i can't find it in the api page, and wondering if i need to use GWD-youtube object in this case.
Might be true, considering this will be required for using video for any DCM elements.

thoughts?

Excellent tutorial man, your work helped me a lot, thank you

Hi Danny,

Great tutorial, I finished a Youtube player today, thank you very much.
Is there a any way to access youtube player "Stats for nerds" information in javascript?

hi there, nice tuto. i'd like to know how to do all this in plain js without use jquery. do you have the tuto in this version or know where i can find anything or tips on how to change this one?

Thanks for the great tutorial!!! Got it working in no time. 1 question I hoped you could help with. I have the autoplay:'1' set so that it automatically starts playing on load. I've also used the Dynamic Queuing to create "channel buttons" but when I choose one the autoplay doesn't work.

Any idea how to get those icons to not only load the video, but also get them to start automatically.

Thanks!
Marc

Hello,

great tutorial !
what if I have more than 1 video on the same page ?
the controls are only working for the first video.
do you have any idea ?
thanks a lot !

Danny Markov

Hi Mattieu!

To control more then one player you will need to create multiple YT.Player instances:

var player1 = new YT.Player('video-placeholder-1', options);
var player2 = new YT.Player('video-placeholder-2', options);

Each variable will control it's own YouTube video.

Hello,
Thank you for this amazing tutorial.

I was wondering how I can use this with an already existing iframe, meaning that an iframe player is already loaded on the page, which is similar to the first example here. https://developers.google.com/youtube/iframe_api_reference#Examples

I tried to copy and paste code but no luck.

Thanks,

Katja Hollaar

Hi Danny,
Thanks for the tutorial.
However, the demo does not seem to work (Chrome latest, Mac) - the play buttons does not do anything and so I cannot even say if other functionality does what it's supposed to do.
I've tried to implement the youtube player and face the same problems. Are there any recent changes to the API that you're aware of that influence this behavior? I cannot find anything in the documentation and the most recent SO questions on YT API are from 2015...
Thanks for your help!
Cheers, Katja