I've looked through so many questions and the youtube api stuff but for the life of me can't figure out why the onYouTubeIframeAPIReady is not working.
Here is my iframe:
<iframe id="youtube_vid" width="763" height="430" src="https://www.youtube.com/embed/dlJshzOv2cw?theme=light&showinfo=0&rel=0&enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>
And my script:
function callYTapi() {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
console.log('script loaded');
function onYouTubeIframeAPIReady() {
console.log('IframeAPI = Ready');
var player = new YT.Player('youtube_vid', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PAUSED) {
console.log("Paused");
}
if (event.data == YT.PlayerState.PLAYING) {
console.log("Playing");
}
if (event.data == YT.PlayerState.ENDED) {
end();
}
}
}
I get the console.log for the loaded script but not for Iframe ready or anything else. Any ideas? Thanks
The callback functions must be in the global scope. Just move onYouTubeIframeAPIReady
and the others outside callYTapi
.
Fortunately for me, after a lot of experimenting with console, I had something concrete. I kind of had the same issue until a day ago and figured out how to do when I was within a singleton scope.
Here is what my code looks like:
var XT = XT || {};
window.onYouTubeIframeAPIReady = function(){
setTimeout(XT.yt.onYouTubeIframeAPIReady,500);
}
XT.yt = {
/* load the YouTube API first */
loadApi: function () {
var j = document.createElement("script"),
f = document.getElementsByTagName("script")[0];
j.src = "//www.youtube.com/iframe_api";
j.async = true;
f.parentNode.insertBefore(j, f);
console.log('API Loaded');
},
/*default youtube api listener*/
onYouTubeIframeAPIReady: function () {
console.log('API Ready?');
window.YT = window.YT || {};
if (typeof window.YT.Player === 'function') {
player = new window.YT.Player('player', {
width: '640',
height: '390',
videoId: 'nE6mDCdYuwY',
events: {
onStateChange: XT.yt.onPlayerStateChange,
onError: XT.yt.onPlayerError,
onReady: setTimeout(XT.yt.onPlayerReady, 4000)
}
});
}
},
onPlayerReady: function() {
player.playVideo(); /* start the video */
player.setVolume(1); /* set volume to 1 (accepts 0-100) */
},
onPlayerStateChange: function (e) {
console.log(e.data, YT.PlayerState.PLAYING, e.data === YT.PlayerState.PLAYING);
var video_data = e.target.getVideoData();
//do something on video ends
if(e.data === YT.PlayerState.ENDED)
this.onPlayerStop();
},
onPlayerStop: function(){
//console.log('video ended');
},
onPlayerError: function (e) {
console.log( "youtube: " + e.target.src + " - " + e.data);
},
init: function () {
this.loadApi();
}
}
XT.yt.init();
Just to be clear, the accepted answer above seems to work for me in this way:
Load API (from yt documentation)
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
specify YouTube's built-in ready function "onYouTubeIframeAPIReady" on window
window.onYouTubeIframeAPIReady = this.onYTready;
So this.onYTready
is my function name and located elsewhere.
I can confirm my onYTready
function can console logs/debugger breakpoints in Chrome.
(edit) you may want to bind this to your function, example:
window.onYouTubeIframeAPIReady = this.onYTready.bind(this);
or 'this' will be for window instead of a specific view you may be using..
function playIframeVideo(iframe) {
iframe.videoPlay = true; //init state
iframe.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
}
function pauseIframeVideo(iframe) {
iframe.videoPlay = false; //init state
iframe.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
}
$('.vc_video-bg-container').on('click', function () {
var iframe = $('iframe').get(0); //iframe tag
if (iframe.videoPlay != true) {
playIframeVideo(iframe);
} else {
pauseIframeVideo(iframe);
}
});