I am currently trying to trigger some functions, for when the embedded youtube player is being loaded, but for some reason is doesn't it seem like the API is being loaded, or the callback functions being triggered based on the API event states?
What am I doing wrong?
const $ = require('jquery');
$(document).ready( function() {
console.log( "ready!" );
loadPlayer();
});
function loadPlayer() {
if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.onYouTubePlayerAPIReady = function() {
onYouTubePlayer();
};
} else {
onYouTubePlayer();
}
}
var player;
function onYouTubePlayer() {
player = new YT.Player('player', {
height: '490',
width: '880',
videoId: 'video',
playerVars: { controls:1, showinfo: 0, rel: 0, showsearch: 0, iv_load_policy: 3 },
events: {
'onReady': window.onPlayerReadVar = function() {
onPlayerStateChange();
},
'onStateChange': window.onPlayerStateChangeVar = function() {
onPlayerStateChange();
}
}
});
console.log("youtubePlayerready")
}
var done = false;
function onPlayerStateChange(event) {
console.log("onPlayerStateChange");
done = true;
}
When the page loads I only see "ready" outputted in the console.. Nothing else?
What am I doing wrong here?
Related
I am trying to change iframe source everytime user click on the skip button and it doesn't work.
var player;
window.onYouTubePlayerAPIReady = function() {
alert('called onYouTubePlayerAPIReady');
player = new YT.Player('header-video__video-element', {
events: {
'onStateChange': ShowMe
}
});
}
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function ShowMe() {
var sStatus;
sStatus = player.getPlayerState();
if (sStatus == -1) alert("Video has not started.");
else if (sStatus == 0) {
$('#ytplayer').replaceWith('<img class="special_hover" src="image" alt="" />')
}
else if (sStatus == 1) {
} //Video is playing
else if (sStatus == 2) {
}
else if (sStatus == 3) {
} //video is buffering
else if (sStatus == 5) {
} //Video is cued.
}
//CODE TRIGGERED BY BUTTON
$(this.settings.playTrigger).on('click', function(e) {
alert('changing source');
$("#header-video__video-element").attr('src', "https://www.youtube.com/watch?v=eozsR79JjPM");
//document.getElementById('header-video__video-element').setAttribute('src', "https://www.youtube.com/embed/eozsR79JjPM");
alert('changed');
//player.loadVideoById("95CX2VL0hVY");
// e.preventDefault();
// that.appendIframe();
});
The player.loadVideoById method that you commented out should do the work. Here is a working example of a little application I did
//Code from the YouTube iFrame API doc
//https://developers.google.com/youtube/iframe_api_reference
var player;
var id = "V13MbW3oMUw";
//Init API
window.onYouTubeIframeAPIReady = function() {
player = new YT.Player('player', {
height: '720',
width: '960',
videoId: "JxfzRNA2_8M",
events: {
'onReady': onPlayerReady,
}
});
};
// Launch video as it's ready
function onPlayerReady(event) {
event.target.playVideo();
}
//Change video onclick
$("#button").click(function(id){player.loadVideoById(id);});
Removed Unwanted Code DEMO
Hey,
I am implementing Youtube Video Player Api and i see some sort of error in console.
any how the video plays perfectly, but i want to know why the error is? if i keep the code outside of Skeleton Patterns, there wont be any error.
can someone please shade some light..
Thanks!!
JS :
(function($) {
$(function(){
var cVid, ytData1;
var callFlexSlider = ({
embedVideos : function(){
function explodeSlider(){
$('.sliderNew .flexslider').flexslider({
slideshow: false
});
$('.sliderNew #carousel, .sliderNew .flex-direction-nav').hide();
}
function explodeShow(){
$('.sliderNew .flexslider').flexslider({
slideshow: true
});
$('.sliderNew #carousel, .sliderNew .flex-direction-nav').show();
}
function getArtistId() {
return window.artist_id;
}
function loadPlayer() {
if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.onYouTubePlayerAPIReady = function() {
onYouTubePlayer();
};
}
}
var player;
function onYouTubePlayer() {
player = new YT.Player('player', {
height: '335',
width: '940',
videoId: getArtistId(),
playerVars: {
controls: 1,
showinfo: 0,
rel: 0,
showsearch: 0,
iv_load_policy: 3
},
events: {
'onStateChange': onPlayerStateChange,
'onError': catchError
}
});
}
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
done = true;
} else if (event.data == YT.PlayerState.ENDED) {
location.reload();
event.target.destroy();
}
}
function onPlayerReady(event) {
console.log('playerReady Event')
}
function catchError(event) {
if (event.data == 100) console.log("...");
}
function stopVideo() {
//alert('asdsad');
//player.destroy();
player.stopVideo();
explodeShow();
}
},
init : function(){
this.embedVideos();
}
});
callFlexSlider.init();
});
})(jQuery);
Call this loadPlayer(); inside document.ready function and try.
function loadScript() {
if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
}
function loadPlayer() {
window.onYouTubePlayerAPIReady = function() {
onYouTubePlayer();
};
}
$(function () {
loadScript();
})
you can always define it manually on the top of your script links :
<script type="text/javascript" id="www-widgetapi-script" src="https://s.ytimg.com/yts/jsbin/www-widgetapi-vflS50iB-/www-widgetapi.js" async=""></script>
<script src="https://www.youtube.com/player_api"></script>
This is the way how I managed to make the iframe api work:
function loadVideo() {
window.YT.ready(function() {
new window.YT.Player("video", {
height: "390",
width: "640",
videoId: "M7lc1UVf-VE",
events: {
onReady: onPlayerReady,
onStateChange: onPlayerStateChange
}
});
});
function onPlayerReady(event) {
event.target.playVideo();
}
function onPlayerStateChange(event) {
var videoStatuses = Object.entries(window.YT.PlayerState)
console.log(videoStatuses.find(status => status[1] === event.data)[0])
}
}
$(document).ready(function() {
$.getScript("https://www.youtube.com/iframe_api", function() {
loadVideo();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="video"></div>
I'm trying to put this code in an module function:
$(document).ready(function()
{
VIDEO.onYouTubeIframeAPIReady();
}
var VIDEO = (function (my, $){
var tag = document.createElement('script');
var onPlayerStateChange;
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
my.onYouTubeIframeAPIReady =function() {
player = new YT.Player('player', {
height: '490',
width: '880',
videoId: SONG.getArtistId(),
playerVars: { controls:1, showinfo: 0, rel: 0, showsearch: 0, iv_load_policy: 3 },
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
'onError': catchError
}
});
}
function onPlayerReady(event) {
if(typeof(SONG.getArtistId()) == undefined)
{
console.log("undefineeeed");
}
event.target.playVideo();
}
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
// setTimeout(stopVideo, 6000);
done = true;
}
if(event.data == YT.PlayerState.ENDED)
{
location.reload();
}
}
function catchError(event)
{
if(event.data == 100) console.log("De video bestaat niet meer");
}
function stopVideo() {
player.stopVideo();
}
return my;
}(VIDEO || {}, jQuery));
The problem is: even it's self-executing, nothing happens and the iFrame is not shown.
I'm trying to do this because it's part of an assignment. We have to work in modules.
You need to simplify the code :
HTML
<div id="player"></div>
Javascript
$(document).ready( function() {
console.log( "ready!" );
loadPlayer();
});
function getArtistId() {
return 'l-gQLqv9f4o';
}
function loadPlayer() {
if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.onYouTubePlayerAPIReady = function() {
onYouTubePlayer();
};
} else {
onYouTubePlayer();
}
}
var player;
function onYouTubePlayer() {
player = new YT.Player('player', {
height: '490',
width: '880',
videoId: getArtistId(),
playerVars: { controls:1, showinfo: 0, rel: 0, showsearch: 0, iv_load_policy: 3 },
events: {
'onStateChange': onPlayerStateChange,
'onError': catchError
}
});
}
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
// setTimeout(stopVideo, 6000);
done = true;
} else if (event.data == YT.PlayerState.ENDED) {
location.reload();
}
}
function onPlayerReady(event) {
//if(typeof(SONG.getArtistId()) == undefined)
//{
// console.log("undefineeeed");
//}
//event.target.playVideo();
}
function catchError(event)
{
if(event.data == 100) console.log("De video bestaat niet meer");
}
function stopVideo() {
player.stopVideo();
}
And a live example : http://jsbin.com/maweqahuhi/1/ http://jsbin.com/nipogicide/2/
EDIT
Regarding your commentq i made some changement in the code.
You need to use onYouTubePlayerAPIReady() to call the player later. I edited all the previous code.
I'm working in a CMS that uses jQuery in noconflict mode (which one is not important here).
I've read multiple articles on how to use jQuery and I'm not getting the function way to work.
// the function way
(function ($){
/* plugin code */
})(jQuery);
but if I do it like beneath and then call everything with $j instead of $ it does work:
var $j = jQuery;
I kinda want the first way to work, as I don't want to rewrite all of my code to $j (how easy it might be.
The code I'm using (maybe the problem does lie there is beneath here
( function( $ ) {
// LOAD THE PLAYER
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 done = false;
var player;
var videoId = 'A3PDXmYoF5U';
var startSeconds = 5;
var endSeconds = 293;
var setVolume = 15;
var suggestedQuality = 'large';
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: ($(window).width() / 16) * 9 + 35,
width: '100%',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(evt) {
player.loadVideoById({'videoId': videoId, 'startSeconds': startSeconds, 'endSeconds': endSeconds, 'suggestedQuality': suggestedQuality });
evt.target.playVideo();
}
function onPlayerStateChange(event) {
var done = false;
// SOUNDCHECK
if (event.data == YT.PlayerState.PLAYING && !done) {
if (player.isMuted()){
$(".eq").addClass("mute");
}
if (player.getVolume() > setVolume) {
player.setVolume(setVolume);
}
done = true;
}
// LOOP
if (event.data == YT.PlayerState.ENDED && !done) {
player.seekTo(startSeconds, true);
done = true;
}
}
} )( jQuery );
Edit: after some more debugging I came to the conclusion it cannot lie to the calling function itself. It is something I'm doing wrong inside my code. The code beneath DOES work
( function( $ ) {
// FIRST WORD SELECTION
$(document).ready( function () {
var firstword = function($selector) {
$($selector).each(function() {
var node = $(this).contents().filter(function() {
return this.nodeType == 3
}).first(), text = node.text(), first = text.slice(0, text.indexOf(" "));
if (!node.length)
return;
node[0].nodeValue = text.slice(first.length);
node.before('<span>' + first + '</span>');
})
};
firstword("#masthead li a, .logo-title");
});
} )( jQuery );
Working plunker
I got it working by including all event handler functions into the global scope. That should be enough.
(function($) {
// LOAD THE PLAYER
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 done = false;
var player;
var videoId = 'A3PDXmYoF5U';
var startSeconds = 5;
var endSeconds = 293;
var setVolume = 15;
var suggestedQuality = 'large';
window.onYouTubeIframeAPIReady = function() {
player = new YT.Player('player', {
height: ($(window).width() / 16) * 9 + 35,
width: '100%',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
window.onPlayerReady = function(evt) {
player.loadVideoById({
'videoId': videoId,
'startSeconds': startSeconds,
'endSeconds': endSeconds,
'suggestedQuality': suggestedQuality
});
evt.target.playVideo();
}
window.onPlayerStateChange = function(event) {
var done = false;
// SOUNDCHECK
if (event.data == YT.PlayerState.PLAYING && !done) {
if (player.isMuted()) {
$(".eq").addClass("mute");
}
if (player.getVolume() > setVolume) {
player.setVolume(setVolume);
}
done = true;
}
// LOOP
if (event.data == YT.PlayerState.ENDED && !done) {
player.seekTo(startSeconds, true);
done = true;
}
}
})(jQuery);
It appears that the YT player API requires the onYouTubeIframeAPIReady function to be available in the global namespace. However, by wrapping your code in an anonymous function, the function is only locally available. You can solve that by returning the function from your anonymous function. Hence, the following should fix your problem:
onYouTubeIframeAPIReady = ( function( $ ) {
// LOAD THE PLAYER
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 done = false;
var player;
var videoId = 'A3PDXmYoF5U';
var startSeconds = 5;
var endSeconds = 293;
var setVolume = 15;
var suggestedQuality = 'large';
function onPlayerReady(evt) {
player.loadVideoById({'videoId': videoId, 'startSeconds': startSeconds, 'endSeconds': endSeconds, 'suggestedQuality': suggestedQuality });
evt.target.playVideo();
}
function onPlayerStateChange(event) {
var done = false;
// SOUNDCHECK
if (event.data == YT.PlayerState.PLAYING && !done) {
if (player.isMuted()){
$(".eq").addClass("mute");
}
if (player.getVolume() > setVolume) {
player.setVolume(setVolume);
}
done = true;
}
// LOOP
if (event.data == YT.PlayerState.ENDED && !done) {
player.seekTo(startSeconds, true);
done = true;
}
}
return function () {
player = new YT.Player('player', {
height: ($(window).width() / 16) * 9 + 35,
width: '100%',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
};
} )( jQuery );
I am embedding a Youtube video and using the YT JS API. The user is encouraged to use their Chromecast to view the embedded video. However, when the video is cast with the button in the player, player.getCurrentTime() and player.getPlayerState() become frozen, and the onStateChange event doesn't fire.
Is there anything I can do to work around these issues, or is this a problem only youtube can fix? Thanks!
My code:
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ytplayer', {
events:{
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event){
console.log('Player StateChange: '+event.data); //This never runs when casting a video.
}
Here's the code
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;
//execute as soon as the player API code downloads
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// execute when the onReady event fires
//starts video
function onPlayerReady(event) {
console.log("onPlayerReady");
console.log(event);
var duration = event.target.getDuration();
console.log("Duration:" + duration);
fillPlaybackRates();
}
// when the onStateChange event fires
function onPlayerStateChange(event) {
console.log("onPlayerStateChange")
console.log(event)
if (event.data == YT.PlayerState.PLAYING) {
console.log(YT);
}
}
var pause = $("#pause"),
start = $("#start"),
mute = $("#mute");
pause.on('click', function () {
player.pauseVideo();
});
start.on('click', function () {
player.playVideo();
});
var fillPlaybackRates = function () {
var playbackDropdownMenu = $(".dropdown-menu");
var playbackRates = player.getAvailablePlaybackRates();
console.log(playbackRates);
for (var i = 0; i < playbackRates.length; i++) {
playbackDropdownMenu.append('<li role="presentation"><a role="menuitem" tabindex="-1" href="#">' + playbackRates[i] + '</a></li>');
}
}
var playbackRatesButton = $("#playback-rates");
$(document).on('click','.dropdown-menu > li > a', function () {
var option = $(this).text();
playbackRatesButton.text(option);
player.setPlaybackRate(option);
});
Here's the full gist: iFrameYouTubeApi.html
You can also have a look here: Continuing with Chromecast: Embedding YouTube into Custom Receivers