Youtube iFrame API Passing data from onYouTubeIframeAPIReady to onPlayerStateChange function - javascript

I am required to initialize list of Youtube iframe video
because there is many youtube video and the list are changeable from admin site I am required to make it dynamic, which is using class instead of id
this is the current code
const players = [];
onYouTubeIframeAPIReady(0);
onYouTubeIframeAPIReady(1);
function onYouTubeIframeAPIReady(index) {
players[index] = new YT.Player($('.wow_youtube_video')[index], {
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
// play
if(event.data == 1){
action = 'play';
}
// pause
if(event.data == 2){
action = 'pause';
}
if(event.data == 1 || event.data == 2){
dataLayer.push({
'event': 'trackEvent',
'eventDetails.category': 'videos',
'eventDetails.action': action,
'eventDetails.label': players[0].getVideoData().title // players[0] supposedly be players[index] but don't know how to pass the index balue from above function to this function
'videoName': players[0].getVideoData().title, //video name
'videoType': 'video on demand' //video type
});
}
}
as you can see above, the 8th line from the bottom
'eventDetails.label': players[0].getVideoData().title,
this code here the
players[0] supposedly be players[index] but I don't know how to pass the index value from
players[index] = new YT.Player($('.wow_youtube_video')[index], {
events: {
'onStateChange': onPlayerStateChange
}
});
to the onPlayerStateChange function
the purpose of this is to be able to carry the index value so that the code can be dynamic, thus I only need to put class name wow_youtube_video on any youtube iframe to make it works
Any help is appreciated, thank you

on function onYouTubeIframeAPIReady add this
players[index] = new YT.Player($('.wow_youtube_video')[index], {
events: {
'onStateChange': onPlayerStateChange.bind(index)
}
});
now you can get index in onPlayerStateChange by
function onPlayerStateChange(event) {
let index = this;
console.log(index);
}

Related

Youtube embedded player works <no wrap> but not onload

I have a player with a for loop counter underneath.
When I set the window to onload, the for loop works, but the youtube video does not display.
http://jsfiddle.net/ajLg0wf9/
When I set the window to no wrap - bottom of <head>, the youtube player works but the for loop doesn't.
http://jsfiddle.net/b8rha571/1/
What's the best way to resolve this?
You need to place youtube api functions at global level not inside onLoad event, something like this:
<script>
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'wQxmK1CZwik',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
loopStart();
player.playVideo();
}
function loopStart() {
player.seekTo(7); // Start at 7 seconds
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
setTimeout(loopStart, 30000); // After 5 seconds, restart the loop
}
}
document.addEventListener("DOMContentLoaded", function(event) {
var button = document.getElementById("clickme"),
count = 0;
button.onclick = function() {
count += 1;
button.innerHTML = "Click me: " + count;
};
});
</script>
I'm not sure how to do it correctly in jsfiddle but this works: http://jsfiddle.net/ajLg0wf9/10/

Youtube javascript load another video when video ends

I want to play another video, which I will get from my database, but I try it with some sample, which is not working at all, here is my sample code:
<script>
// create youtube player
var player;
function onYouTubePlayerAPIReady(id) {
if (id == null) {var t = '0Bmhjf0rKe8';}
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: t,
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// autoplay video
function onPlayerReady(event) {
event.target.playVideo();
}
// when video ends
function onPlayerStateChange(event) {
if(event.data === 0) {
// Here I want to call function again, function executes, but video will not played
onYouTubePlayerAPIReady('yeDkcSZta2Y');
}
}
There you can see, when video ends I call onYouTubePlayerAPIReady() with new video ID, it executes as well, but video do not play. I think it will be because the onPlayerReady() do not executes, or something.
How to fix this, or what change to work it properly?
Here is an example that works. Call queueVideo() to load a string containing comma separated video ids of all the videos that you want to play or just one video. When there are no video left in the queue, this plays the default video '0Bmhjf0rKe8'. I never use onPlayerReady(). In fact, if I remember correctly, it was never called so I implemented using the technique shown below.
<script type="text/javascript">
// Load the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
//
// Replaces the 'ytplayer' element with an <iframe> and
// YouTube player after the API code downloads.
var player;
var videosQueuedCount;
function onYouTubePlayerAPIReady() {
videosQueuedCount = 1;
var vars = {
autoplay: 1,
enablejsapi: 1,
controls: 1
}
player = new YT.Player('ytplayer', {
height: '390',
width: '640',
playerVars: vars,
videoId:'0Bmhjf0rKe8',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(evt) {
}
function playVideo(VID) {
window.top.scrollTo(0,410);
videosQueuedCount = 1;
player.loadVideoById(VID);
}
function queueVideo(queuedCount,VID) {
window.top.scrollTo(0,410);
videosQueuedCount = queuedCount;
player.loadPlaylist(VID);
player.playVideo();
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
videosQueuedCount -= 1;
if (videosQueuedCount < 1) {
videosQueuedCount = 1;
playVideo('0Bmhjf0rKe8');
}
}
}
</script>
<div class="video-container"><div id="ytplayer"></div></div>

Youtube iFrame API how do I invoke IframeAPIReady function after getting list of videos

I am making simple Youtube Video Player myself, and I'd like to know how to invoke onYouTubeIframeAPIReady() after I get a list of videos.
What I like to do is display the first video in list as initial video.
In my html somewhere:
<script src="//www.youtube.com/iframe_api"></script>
This is initial iframe embed code from official sample code:
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player-box', {
// height: '390',
// width: '640',
videoId: {FIRST_VIDEO_ID},
events: {
'onReady': onPlayerReady,
// 'onStateChange': onPlayerStateChange
}
});
}
Here is how I get a list of vids:
$.getJSON(
'https://www.googleapis.com/youtube/v3/videos',
{
part: 'snippet',
id: {VIDEO_IDs},
key: {MY_API_KEY},
},
function(data) {
var items = data.items;
console.log(data);
// cannot put onYouTubeIframeAPIReady here...
}
);
I guess I cannot put onYouTubeIframeAPIReady() as $.getJSON's callback, since it is called outside the script.
I kinda solve this problem myself.
I wrapped everything inside var onYouTubeIframeAPIReady = function() {...
Here's how I done:
var onYouTubeIframeAPIReady = function() {
var videos = '{VIDEO_ID1}, {VIDEO_ID2}, {VIDEO_ID3}';
$.getJSON(
'https://www.googleapis.com/youtube/v3/videos',
{
part: 'snippet',
id: videos,
key: {MY_API_KEY},
},
function(data) {
var items = data.items;
console.log(items);
$.each(items, function(i, video){
console.log(video);
});
var player;
player = new YT.Player('player-box', {
// height: '390',
// width: '640',
videoId: {INITIAL_VIDEO_ID},
events: {
'onReady': onPlayerReady,
// 'onStateChange': onPlayerStateChange
}
});
function onPlayerReady(event) {
event.target.playVideo();
}
var done = false;
function onPlayerStateChange(event) {
// console.log(event.data);
// if (event.data == YT.PlayerState.PLAYING && !done) {
// everytime change vids playing for 6secs then stop
if (event.data == YT.PlayerState.PLAYING) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
}//$.getJSON callback
}

Youtube api event only applies to first element

I'm making a slider with youtube videos in it that i want muted so i made this:
window.onYouTubePlayerAPIReady = function() {
player = new YT.Player('video', {
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
event.target.mute();
}
This works! But only on the first video. Check the jsfiddle. If you pause the second video you can see the first one is muted. I tried looping the event but no luck
JSfiddle
You need to apply this for every video.
You also need to use unique id values for the iframe elements.
So after changing the id to video for the first and video2 for the second, the script
window.onYouTubePlayerAPIReady = function() {
player = new YT.Player('video', {
events: {
'onReady': onPlayerReady
}
});
player2 = new YT.Player('video2', {
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
event.target.mute();
}
now works
Update demo at http://jsfiddle.net/gaby/mre4dvbe/2/
Updated version after comments
window.onYouTubePlayerAPIReady = function() {
var videos = document.querySelectorAll('.yt-video');
[].forEach.call(videos, function(video) {
new YT.Player(video, {
events: {
'onReady': onPlayerReady
}
});
});
}
function onPlayerReady(event) {
event.target.mute();
}
This will work with any number of videos (which share the same class yt-video)
Demo at http://jsfiddle.net/gaby/mre4dvbe/5/

Youtube IFrame api getVideoLoadedFraction() not called in iOS

I read links about YouTube IFrame API and doing a sample which has iFrame in HTML.
I need the below function to be called:
player.getVideoLoadedFraction();
I am using the below code for creating player object.
var player;
function onYouTubeIframeAPIReady()
{
alert('onYouTubeIframeAPIReady');
player = new YT.Player('player', {
height: '432',
width: '768',
videoId: 'tNpd9LCaG8',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
alert('player created');
}
and for testing purpose I added the player.getVideoLoadedFraction() in the onStateChange event.
function onPlayerStateChange(event)
{
alert("onStateChange has fired!\nNew state:" + event.data);
var progress = player.getVideoLoadedFraction();
alert (progress);
}
this method is not getting called. Even if I put any alert after var progress = player.getVideoLoadedFraction(); this line, alert is not displaying.
Can anyone help me to solve this.
Thank you
Don't call player.getVideoLoadedFraction(), call event.target.getVideoLoadedFraction().

Categories