I'm using youtube iframe API for redirecting users to another link when the video ends. I've an existing iframe on my webpage. So I've written the below code which works on my local environment but in the live website it doesn't work.
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;
window.onYouTubeIframeAPIReady = function () {
window.YT.ready(function () {
player = new window.YT.Player(element_id, {
events: {
'onStateChange': onPlayerStateChange
}
});
});
};
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
if (quiz_permalink) {
window.location.href = quiz_permalink;
} else if (next_lesson_permalink) {
window.location.href = next_lesson_permalink;
}
}
}
Can anyone guide me what can be the possible reason for this not working in the live website ?
Thanks in advance
Related
Somewhat related to:
YouTube IFrame API doesn't always load?
But different in that I AM loading the YouTube script per instructions. Note, in my source, the iframe is ABOVE the script block in the load order. I based this off of these instructions (below). The example works fine if I'm on that page, but doesn't seem to work for me when I put the code on mine. I'm sure I'm missing something really simple but I'm to be missing it. Thanks!
https://developers.google.com/youtube/iframe_api_reference#Mobile_considerations
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 shows this script is loading
var player;
function onYouTubeIframeAPIReady() {
console.log("onYouTubeIframeAPIReady", arguments); //This shows in console
player = new YT.Player('js_youTubeFrame', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
console.log("onPlayerReady",event); //Never triggers
}
function onPlayerStateChange(event) {
console.log("onPlayerStateChange", event); //Never triggers
if (event.data === YT.PlayerState.PLAYING) {
console.log("YouTube Video is PLAYING!!"); //Never triggers
}
}
<div id="js_youTubeContainer" class="embed-responsive embed-responsive-16by9">
<iframe id="js_youTubeFrame" class="embed-responsive-item" src="https://www.youtube-nocookie.com/embed/u3A7bmEOtaU?enablejsapi=1&rel=0&showinfo=0" frameborder="0" allowfullscreen></iframe>
</div>
Best way to load a Youtube Video by his API, is following this sintaxis:
<div id="video-youtube"></div>
<script id="youtube-tracking-script">
var youtubeVideoId = 'u3A7bmEOtaU'; // replace with your own video id
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementById("youtube-tracking-script");
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var video;
function onYouTubeIframeAPIReady() {
video = new YT.Player('video-youtube', {
height: '352',
width: '100%',
videoId: youtubeVideoId,
playerVars: {rel: 0, showinfo: 0},
events: {
'onStateChange': videoPlay
}
});
}
function videoPlay(event) {
if (event.data == YT.PlayerState.PLAYING) {
console.log("YouTube Video is PLAYING!!");
}
if (event.data == YT.PlayerState.PAUSED) {
console.log("YouTube Video is PAUSED!!");
}
if (event.data == YT.PlayerState.ENDED) {
console.log("YouTube Video is ENDING!!");
}
}
</script>
https://jsfiddle.net/t4qwfk0d/1/
You should replace your <iframe> </iframe> to <div id= "js_youTubeFrame"> </div>, in my case it works.
I think that Youtube Iframe Api needs that div to convert it on iframe after.
So I figured I would update this with a working example. I have ditched stating the iframe tag and just used the iframe api to create an iframe and then loaded the player by id with a data attribute. Here is a working example below. So now all statechanges are passed consistently through the youtube player. So the script will load an iframe into the Div #player and you can just loadVideoByID pretty easily with jquery and javascript.
<div id="player"></div>
<script>
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;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
playerVars: { 'autoplay': 0,},
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
alert('started');
}
function onPlayerStateChange(event) {
if(event.data === 0) {
alert('done');
}
}
$( document ).on( "click", ".video-link", function(e) {
e.preventDefault();
var videoID = $(this).attr('data-videoID');
player.loadVideoById(videoID);
});
</script>
And then use a link with a data-attribute like so.
Link
Rather than having buttons to play, why not cue to playlist when the player is ready? You can hold the video ID's in an array... If this isn't what you're looking for just leave a comment below and I will change things the best I can to fit.
//Array of videos
var MyVideos=["E6RGMRamAFk","IHQr0HCIN2w","CogIXrea6A4"];
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;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
//Player is ready, cue the array of videos into the playlist.
player.cuePlaylist(MyVideos);
}
function onPlayerStateChange(event) {
}
JS Fiddle - Working Demo
YouTube JavaScript Player API Reference
If you have any questions please leave a comment below and I will get back to you as soon as possible.
I hope this help. Happy coding!
I'm using the YouTube API in conjunction with Cyclone Slider. The goal is to pause the slideshow once the YouTube starts playing. I'm using the following code which works nicely:
<script>
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
</script>
<script>
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('video', {
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
if(event.data === 1) {
$(".cycle-slideshow").cycle('pause');
}
if(event.data === 2) {
$(".cycle-slideshow").cycle('resume');
}
}
</script>
However, it only seems to work if I do a refresh of the page. If I navigate between pages and return to the homepage, it will no longer work.
Any suggestions for why this is the case? I've tried a few suggestions I found on Google but couldn't get any to work. I'm a little lost on this one.
Any help would be greatly appreciated.
Try the following code, it works for me -
function loadYouTube(targetId){
ytplayer = new YT.Player(targetId, {
events: {
'onStateChange': function(event){
/** YouTube API
-1 (unstarted)
0 (ended)
1 (playing)
2 (paused)
3 (buffering)
5 (video cued)
**/
if (event.data == 1) {
//do your work here
}
console.log(event.data)
}
}
});
}
I understand how to load the Youtube IFrame player API normally in a document:
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
How would I do this in a meteor application though? I can't just put a <script> tag inside a template and I don't know if I can access document in one of the template helpers.
Is there some way to load it globally once the user connects for the first time?
there are several packages which can be used to use youtube iframe api
using the package adrianliaw:youtube-iframe-api we can do it like below
if (Meteor.isClient) {
onYouTubeIframeAPIReady = function () {
player = new YT.Player("player", {
height: "400",
width: "600",
videoId: "LdH1hSWGFGU",
events: {
onReady: function (event) {
event.target.playVideo();
}
}
});
};
YT.load();
}
So from what I can gather one or two things are going from with my youtube video's either the seekTo function has stopped working or the hole API has....(Or youtube has changed something) Now please take in mind my codes were working flawlessly without fault untill yesterday... (code usually doesn't break over night).
Here are 2 sites with the SeekTo function that loops the video via PlayerState ENDED:
http://imvu.url.ph/aattpx/DC_MAR/Base/XML/COMPIC_X1/2014/LayDStroke/maintemp/index.html
http://imvu.url.ph/FTP/2013/System/Core/Int/Warning/Dont_Not_Touch/DKLAY2013BLUE/Layout/Infuriate/index.html
The codes for the youtube video are more or less identical so I'll just post 1 of the codes:
view-source:imvu.url.ph/aattpx/DC_MAR/Base/XML/COMPIC_X1/2014/LayDStroke/maintemp/video.html
<div id="youtube-fs"><iframe id="youtube-iframe" type="text/html" src="http://www.youtube.com/embed/o2cvRsiRkqs?enablejsapi=1&autoplay=1&showinfo=0&iv_load_policy=3&controls=0&rel=0&wmode=transparent&vq=hd720&hd=1&loop=1" frameborder="0" wmode="Opaque" ></iframe> <script type="text/javascript">
<!--
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
player.quality = 'hd720';
function onYouTubePlayerAPIReady() { player = new YT.Player('youtube-iframe', { events: { 'onStateChange': onPlayerStateChange } }); }
function onPlayerReady(event) { event.target.setPlaybackQuality('hd720'); event.target.playVideo(); }
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.BUFFERING) {
event.target.setPlaybackQuality('hd720');
}
if (event.data == YT.PlayerState.ENDED) { player.seekTo(0, true); } // end if
}
-->
</script>
</div>
</div></div>