I want to be able to control iframe based YouTube players. This players will be already in the HTML, but I want to control them via the JavaScript API.
I've been reading the documentation for the iframe API which explain how to add a new video to the page with the API, and then control it with the YouTube player functions:
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('container', {
height: '390',
width: '640',
videoId: 'u1zgFlCw8Aw',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
That code creates a new player object and assigns it to 'player', then inserts it inside the #container div. Then I can operate on 'player' and call playVideo()
, pauseVideo()
, etc. on it.
But I want to be able to operate on iframe players which are already on the page.
I could do this very easily with the old embed method, with something like:
player = getElementById('whateverID');
player.playVideo();
But this doesn't work with the new iframes. How can I assign a iframe object already on the page and then use the API functions on it?
You can do this with far less code:
Working example: http://jsfiddle.net/kmturley/g6P5H/296/
Fiddle Links: Source code - Preview - Small version
Update: This small function will only execute code in a single direction. If you want full support (eg event listeners / getters), have a look at Listening for Youtube Event in jQuery
As a result of a deep code analysis, I've created a function:
function callPlayer
requests a function call on any framed YouTube video. See the YouTube Api reference to get a full list of possible function calls. Read the comments at the source code for an explanation.On 17 may 2012, the code size was doubled in order to take care of the player's ready state. If you need a compact function which does not deal with the player's ready state, see http://jsfiddle.net/8R5y6/.
Usage:
Possible questions (& answers):
Q: It doesn't work!
A: "Doesn't work" is not a clear description. Do you get any error messages? Please show the relevant code.
Q: I have embedded a YouTube video using
<iframe src="http://www.youtube.com/embed/As2rZGPGKDY" />
but the function doesn't execute any function!A: You have to add
?enablejsapi=1
at the end of your URL:/embed/vid_id?enablejsapi=1
.Q: I get error message "An invalid or illegal string was specified". Why?
A: The API doesn't function properly at a local host (
file://
). Host your (test) page online, or use JSFiddle. Examples: See the links at the top of this answer.Q: How did you know this?
A: I have spent some time to manually interpret the API's source. I concluded that I had to use the
postMessage
method. To know which arguments to pass, I created a Chrome extension which intercepts messages. The source code for the extension can be downloaded here.Q: What browsers are supported?
A: Every browser which supports JSON and
postMessage
.document.readyState
was implemented in 3.6)Related answer / implementation: Fade-in a framed video using jQuery
Full API support: Listening for Youtube Event in jQuery
Official API: https://developers.google.com/youtube/iframe_api_reference
Revision history
Implemented
onYouTubePlayerReady
:callPlayer('frame_id', function() { ... })
.Functions are automatically queued when the player is not ready yet.
Updated and successully tested in the supported browsers (look ahead).
callPlayer
forces a check of readiness. This is needed, because whencallPlayer
is called right after the insertion of the iframe while the document is ready, it can't know for sure that the iframe is fully ready. In Internet Explorer and Firefox, this scenario resulted in a too early invocation ofpostMessage
, which was ignored.&origin=*
in the URL.&origin=*
to the URL.My own version of Kim T's code above which combines with some jQuery and allows for targeting of specific iframes.
Looks like YouTube has updated their JS API so this is available by default! You can use an existing YouTube iframe's ID...
...in your JS...
...and the constructor will use your existing iframe instead of replacing it with a new one. This also means you don't have to specify the videoId to the constructor.
See Loading a video player