Categories:

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:
  • controls=0: Player controls do not display in the player. For IFrame embeds, the Flash player loads immediately.
  • controls=1 (default): Player controls display in the player. For IFrame embeds, the controls display immediately and the Flash player also loads immediately.
  • controls=2: Player controls display in the player. For IFrame embeds, the controls display and the Flash player loads after the user initiates the video playback.
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 loop parameter only works in the AS3 player when used in conjunction with the playlist parameter. To loop a single video, set the loop parameter value to 1 and set the playlist parameter value to the same video ID already specified in the Player API URL, for example:

<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 and playlist 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 and playlist 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>

Play With Code

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>

See Example

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 and height:int: The dimensions of the iframe. We'll use CSS to override these settings.
    • videoId:string: The ID of the video we wish to play
    • playerVars:{}: 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 - unstarted
  • 0 - ended
  • 1 - playing
  • 2 - paused
  • 3 - buffering
  • 5 - 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 video
  • player.pauseVideo(): Pauses the video
  • player.stopVideo(): Stops the video
  • player.nextVideo(): Plays the next video()
  • player.previousVideo(): Plays the previous video()
  • player.mute(): Mutes the current video playing
  • player.unMute(): Unmutes the current video playing
  • player.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){}
		}
	})
}

See Example

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 as autoplay, 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()
}

Creating a simple Youtube lightbox