28

<iframe width="560" height="315" src="//www.youtube.com/embed/M7lc1UVf-VE" frameborder="0" allowfullscreen></iframe>

I have a few questions on what happens when I embed a YouTube video using source code like above. The code should generate a YouTube Player object that processes the video the way users like. When I generate a Youtube Player by myself using Youtube Player API(instead of using the embed code), I can call call functions on it.

var player;
function onYouTubeIframeAPIReady() {
  player = new YT.Player('player', {
    height: '390',
    width: '640',
    videoId: 'M7lc1UVf-VE',
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
}

//player.playVideo(); will play the video.

My question is, how do I control the player object generated by the embed code? To put it in another way, from page http://www.youtube.com/watch?v=M7lc1UVf-VE, how do I play the video by calling SOMEPlayer.playVideo()? When you go to the url, ytplayer object is available, but it doesn't seem to contain the necessary functions.

This question might be a duplicate of this.

Community
  • 1
  • 1
Maximus S
  • 10,759
  • 19
  • 75
  • 154

5 Answers5

40
var player = YT.get('id-of-youtube-iframe');
user2909143
  • 411
  • 4
  • 3
  • 1
    Please explain how your answer solves the problem, it will help everyone understand your solution with more clarity and for future reference. – Aziz Apr 02 '16 at 03:47
  • 1
    Lifesaver, thank you. @Aziz, this is how you can use the YouTube API to get a reference to a player based on its element id. – Liran H Dec 14 '17 at 15:52
38

This can be done like the following.

Given a general YouTube embed source code:

<iframe width="560" height="315" src="//www.youtube.com/embed/M7lc1UVf-VE" frameborder="0" allowfullscreen></iframe>

a. Add a enablejsapi query param and set it to 1 in the src URL

<iframe width="560" height="315" src="//www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1" frameborder="0" allowfullscreen></iframe>

b. Give it a unique id

<iframe id="youtube-video" width="560" height="315" src="//www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1" frameborder="0" allowfullscreen></iframe>

c. Load YouTube iFrame API

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

d. Create a player that references the existing iFrame

var player;
function onYouTubeIframeAPIReady() {
  player = new YT.Player('youtube-video', {
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
}

function onPlayerReady() {
  console.log("hey Im ready");
  //do whatever you want here. Like, player.playVideo();

}

function onPlayerStateChange() {
  console.log("my state changed");
}
Celsiuss
  • 895
  • 7
  • 19
Maximus S
  • 10,759
  • 19
  • 75
  • 154
  • 1
    Floradu88 http://jsfiddle.net/bf7zQ/1/ It actually does nothing in `onPlayerStateChange()` and `onPlayerReady()`; Am I doing something wrong? – Alexis Rengifo Feb 28 '14 at 18:23
  • 3
    @spideep This should work: http://jsfiddle.net/bf7zQ/2/ You have to pass `?enablejsapi=1` and you have to use `https://`. – panzi Apr 09 '14 at 17:02
  • it seems that both urls have to be httpS – Ads Nov 19 '14 at 22:42
  • 1
    @Ads I believe that rather both protocols need to match. So either `http` or `https` – xyhhx Mar 09 '16 at 03:16
  • This isn't working for me. I'm getting an error (index):1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). Promise (async) (anonymous) @ scripts.js:20 dispatch @ jquery-1.12.4.js:5226 elemData.handle @ jquery-1.12.4.js:4878 scroll (async) d.getScrollTop @ skrollr.min.js:2 Aa @ skrollr.min.js:2 d.refresh @ skrollr.min.js:2 d @ skrollr.min.js:2 init @ skrollr.min.js:2 (anonymous) @ (index):493 cast_sender.js:67 Uncaught DOMException: Failed to construct 'PresentationRequest': Presentation of an insecure document [cast:233637DE? – LauraNMS Jul 26 '18 at 15:52
  • FYI: for this to work your Youtube API event callbacks cannot be nested inside another function scope. – samnau May 20 '19 at 21:51
6

Maximus S gave a perfectly correct answer. The official YouTube IFrame Player API docs suggest initialising the player through a unique id of an iframe with the video as var yPlayer = new YT.Player('unique-id');.

For the future readers of this question looking for a way to generate a YouTube Player from a reference to an iframe element without id (as myself), it is possible to do so by running var yPlayer = new YT.Player(iframeElement); if you add type="text/html" attribute to the iframe element and set enablejsapi=1 parameter in the src attribute:

<iframe type="text/html" height="360" width="640" src="https://www.youtube.com/embed/jNQXAC9IVRw?enablejsapi=1"></iframe>

Full snippet

Timur Osadchiy
  • 5,699
  • 2
  • 26
  • 28
2

A great way to do this without loading the IFrame API in the parent window is to grab the object from the IFrame

var ytplayer_window = document.getElementById("playerIFrame").contentWindow;
var player = ytplayer_window.yt.player.getPlayerByElement(ytplayer_window.player);
Thnesko
  • 108
  • 2
  • 4
0

The best answer is almost right. You have to place "enablejsapi=1" on the iframe src. Something like:

<iframe id="youtube-video" width="560" height="315" 
        src="https://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1" frameborder="0" 
        allowfullscreen>
</iframe>
techspider
  • 3,370
  • 13
  • 37
  • 61
faabiopontes
  • 106
  • 6
  • where is the docs on this variation/best practice.would be great just to clarify for the best practice. thanks – jamie Oct 25 '16 at 16:54