Attach parameters to the Youtube iframe URL to modify its behaviour
We can make some changes to an embedded Youtube video's behavior just by attaching parameters to the end of the Youtube URL inside the iframe. The following for example causes the video to automatically play when it's loaded:
<iframe width="560" height="315" src="https://www.youtube.com/embed/96kI8Mp1uOU?autoplay=1" frameborder="0" allowfullscreen></iframe>
We attach autoplay=1
to a question mark following
the original Youtube URL in this case. Refer to Google's
Youtube Embedded Players Parameters page for the full list of
supported parameters. Here are some of them:
Parameter | Description |
---|---|
autoplay | Set this parameter to 1 to auto play video. Default is 0, which disables auto playing. Note that auto playing a video is disabled on certain mobile platforms and browser combinations such as Chrome and Safari mobile. |
controls | Sets whether the video player controls are displayed:
|
start | The time in seconds from the beginning of the video to start playing. |
end | The time in seconds from the beginning of the video to end playing. |
loop | In the case of a single video player, a setting of
1 causes the player to loop the initial
video when playing *. In the case of a playlist player (or custom
player), the player plays the entire playlist and then starts again at
the first video.*Note: This parameter has limited
support in the AS3 player and in IFrame embeds, which could load either
the AS3 or HTML5 player. Currently, the <iframe width="560" height="315" src="https://www.youtube.com/embed/SbQc_JLUH7k?loop=1&playlist=SbQc_JLUH7k" frameborder="0" allowfullscreen></iframe> |
playlist | A comma-separated list of video IDs to play. If you
specify a value, the first video that plays will be the video originally
specified in the iframe's URL, and the videos specified in the
playlist parameter will play after
that. |
The next example does of all the following just by attaching parameters to the iframe video URL:
- Automatically plays the Youtube video when it's ready (
autoplay=1
andplaylist
parameter defined) - Starts playing the video at the 5 second mark (
start
parameter) - Stops playing the video at the 8 second mark (
end
parameter) - Automatically plays another video after the first video has
stopped playing (
loop=1
andplaylist
parameter defined)
<iframe width="560" height="315" src="https://www.youtube.com/embed/SbQc_JLUH7k?autoplay=1&loop=1&start=5&end=8&playlist=96kI8Mp1uOU" frameborder="0" allowfullscreen></iframe>
Try modifying the parameters to see the difference.
A quick overview of using Youtube API to embed and manipulate a video
Attaching parameters to the Youtube Iframe's URL can only get you so far in manipulating the video. For more serious shenanigans, we'll want to tap into Youtube iframe Player's API. The API works on an existing Youtube Iframe or one that's dynamically served using JavaScript instead. For maximum versatility, however, go the later route, which lets you dynamically add or remove the Youtube iframe on demand.
Loading the Youtube Player API and a video dynamically
Firstly, to load a Youtube video dynamically using Youtube Player API, we do the following 3 things:
Step 1: Add an empty DIV on the page where you wish the Youtube iframe to appear on the page. The iframe will replace this temporary DIV when loaded:
<div id="player"></div>
Step 2: Load the Youtube Player API asynchronously in JavaScript, following the DIV above:
<script> // load Youtube API code asynchronously var tag = document.createElement('script') tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0] firstScriptTag.parentNode.insertBefore(tag, firstScriptTag) </script>
This is similar to loading the Youtube API synchronously by physically adding a <script> tag to your page:
<script src="https://www.youtube.com/iframe_api"></script>
except the former code is non blocking.
Step 3: And finally, define a onYouTubeIframeAPIReady()
function that the Youtube API will call automatically once the API
has loaded, and initialize a new Youtube Player inside it to show
the Youtube video in place of the DIV of step 1:
<script> // load Youtube API code asynchronously var tag = document.createElement('script') tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0] firstScriptTag.parentNode.insertBefore(tag, firstScriptTag) var player // variable to hold new YT.Player() instance // define onYouTubeIframeAPIReady() function and initialize a Youtube video player when the API has loaded function onYouTubeIframeAPIReady() { player = new YT.Player('player', { height: '390', width: '640', playerVars: {autoplay:1, loop:1}, videoId: 'SbQc_JLUH7k', events: { 'onReady': function(event){}, 'onStateChange': function(event){} } }) } </script>
Do not modify the onYouTubeIframeAPIReady()
function name, as
this is what the API expects and will call once it's properly
loaded. Inside onYouTubeIframeAPIReady()
, invoke new YT.Player()
and assign it to an arbitrary but unique variable (ie: "player
") so
we can manipulate this player further afterwards. In the above demo,
we've passed the following parameters to YT.Player():
- "
player
": The very first parameter, this should be the ID (string) of the empty DIV on your page the Youtube iframe will load and replace it with. You can also pass in a DOM reference to the empty DIV instead of its ID value. - Object literal: The second parameter should be an
object literal containing additional options. In the example
above, we've defined the following options:
width:int
andheight:int
: The dimensions of the iframe. We'll use CSS to override these settings.videoId:string
: The ID of the video we wish to playplayerVars:{}
: A comma separated list of parameters to pass into the player to modify its behaviour. These are the same supported list of parameters discussed earlier that you can attach to the Youtube URL instead.events:{}
: An object literal containing a list of event handlers of Youtube API you wish to tap into. In this case, we've defined "onReady
" and "onStateChange
", which are called when the player instance is ready, and also whenever it changes states (ie: has stopped playing), respectively.
Keeping track of the video state
Once a Youtube video has been loaded via the API, a vital piece of information to know is the current player's state. For example, by default when the video has just loaded but isn't playing, its state is "unstarted" (-1). When it's playing, its state changes to "playing" (1) etc. Knowing the current player's state allows you to react accordingly. The possible state values are:
-1
- unstarted0
- ended1
- playing2
- paused3
- buffering5
- video cued
There are two ways to get the current state of the player- using
the method player.getPlayerState()
, or by checking the
parameter event.data
inside any of the API event handlers, for
example:
events: { 'onReady': function(event){ console.log(event.data) }, 'onStateChange': function(event){ console.log(event.data) } }
Try adding console.log()
to these two events
handlers inside the original
Youtube API Player example and view your console to see the
value returned based on the current state of the player.
Youtube Player API methods
Once a Youtube video has been loaded via the Youtube API, you can call methods on the player instance to perform operations on it, such as:
player.playVideo()
: Plays the videoplayer.pauseVideo()
: Pauses the videoplayer.stopVideo()
: Stops the videoplayer.nextVideo()
: Plays the next video()player.previousVideo()
: Plays the previous video()player.mute()
: Mutes the current video playingplayer.unMute()
: Unmutes the current video playingplayer.getPlayerState()
: Gets the current state of the player (int).player.destroy()
: Removes the<iframe>
containing the player
In the above case, "player
" is the variable you
assigned new YT.Player()
when initializing it.
Refer to the documentation for a full list of supported
methods. When
calling these methods, make sure the Youtube player in question has
initialized first- one way to ensure this is to call these methods
inside the 'onReady
' event handler of the player.
The following example loads a Youtube Player that automatically plays when the page loads. Furthermore, if the user scrolls down the page and past the video it pause the video, and resumes playing if the video is scrolled back up into view We'll enlist the help of jQuery to easily determine the coordinates of the player on the page
function onYouTubeIframeAPIReady() { player = new YT.Player('player', { height: '390', width: '640', playerVars: {autoplay:1}, videoId: 'SbQc_JLUH7k', events: { 'onReady': function(event){ var $player = $('#player') // jQuery ref to Youtube iframe var playerTop = $player.offset().top $(window).on('scroll', function(){ var playerState = player.getPlayerState() // get player state if ($(window).scrollTop() > (playerTop + $player.height())){ // if user scrolls down and past the video completely if (playerState == 1) // if video is playing player.pauseVideo() } else{ // if user scrolls back up where video shows even a little bit if (playerState != 1) // if video is NOT playing player.playVideo() } }) }, 'onStateChange': function(event){} } }) }
As you can see, inside the "onReady
" event of the Youtube Player
instance, we get the vertical offset of the youtube iframe relative
to the document, and as the user scrolls the page, compare that
value to the current vertical scrollbar position. Based on whether
the user has scrolled past the video or not on the page, we either
play or pause the video, taking into account the video's current
state as well using player.getPlayerState()
.
Playing a video on Mobile Devices- in particular iOS devices- issue and workaround
YouTube API's documentation mentions the limitation of its player on mobile devices:
"The HTML5<video>
element, in certain mobile browsers (such as Chrome and Safari), only allows playback to take place if it's initiated by a user interaction. Due to this restriction, functions and parameters such asautoplay
,playVideo()
,loadVideoById()
won't work in all mobile environments."
This seems fairly innocuous- it simply tells us that Youtube API's "play" related methods on mobile devices will have no effect when called, with an explicit action by the user required to play a video. HOWEVER, we've found that on iOS devices (iPhone, iPad etc), there is currently a nasty side effect when calling any of Youtube API's play methods, such as:
player.playVideo()
player.loadVideobyID()
player.loadVideoByID()
player.loadVideoByUrl()
On iOS devices (at time of writing), calling these methods not only doesn't play the video (as expected), but seems to put the video in perpetual "buffering" mode, with the "spinning" loader always appearing above the video and rendering it inoperable.
To work around the above debilitating bug, whenever we need to call a "play" related Youtube method, we should first detect whether the device is iOS, and if so, use Youtube API's "cueing" methods instead, such as:
player.cueVideoById()
player.cueVideoByUrl()
These methods do not attempt to play the video in question, merely loads it into the video player, ready for the user to manually play it. The following example shows how this looks like in practice:
var isiOS = navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)/i) != null //boolean check for iOS devices if (isiOS){ // if iOS device player.cueVideoById('video_id') } else{ // non iOS devices, just try to play video player.playVideo() }
- Tutorial introduction- using CSS to make a Youtube iframe responsive and vertically centered
- Controlling a Youtube video via URL parameters and the Youtube Player API
- Creating a simple Youtube lightbox