Youtube's IFrame API is not working for me anymore. Both onYouTubeIframeAPIReady() and onYouTubePlayerReady() gets executed. However, when try loading/playing a video, I receive the following error:
base.js:2575 Uncaught TypeError: Cannot read property 'g' of null
at jL (base.js:2575)
at nL (base.js:2567)
at PU.g.h.nh (base.js:5853)
at E0 (base.js:3841)
at q1.g.h.Lr (base.js:6904)
at q1.g.h.Dy (base.js:6905)
at r1 (base.js:3909)
at L1.g.h.Vn (base.js:6937)
at L1.g.h.nN (base.js:6679)
at g.bD.g.h.V (base.js:5529)
Here is how I use the IFrame API
// Load YouTube 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);
// Create YouTube Player
var jukeBoxYoutubePlayer;
function onYouTubeIframeAPIReady() {
console.log("iframe api ready");
jukeBoxYoutubePlayer = new YT.Player('youtube_player', {
height: '400px',
width: '400px',
events: {
'onReady': onYouTubePlayerReady
}
});
}
// On Ready Event
function onYouTubePlayerReady(event) {
console.log("player ready");
jukeBoxYoutubePlayer.unMute();
jukeBoxYoutubePlayer.setVolume(75);
}
Here is how I load and play a video:
jukeBoxYoutubePlayer.loadVideoById("ubtbkgUmHHE", 0, "large");
jukeBoxYoutubePlayer.playVideo();
I don't see why my code is not working. It has been working for months. I also re-checked the docs (https://developers.google.com/youtube/iframe_api_reference) for any new changes, but can't find any.
It seems the issue was that my "youtube_player" iframe was hidden by CSS display:none. Apparently, YouTube requires the iframe to be visible. However, sizing the iframe to 1x1 px solved it for me.
Related
I'm playing 3 videos from Dailymotion by JavaScript SDK. This is my code:
var tag = document.createElement('script');
tag.src = "https://api.dmcdn.net/all.js";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.dmAsyncInit = function () {
var player = DM.player("divplayer",
{ video: VideoId, width: "100%", height: "100%", params: { "endscreen-enable": 0,"ui-logo":0 } });
};
}
The first video is played with no problem but after that I get this Error:
Uncaught Error: Invalid first argument sent to DM.player(), this element is already a player: divplayer
divplayer is a div element.
I tried to empty the div content before calling my function but that did not work.
Thanks in advance
We apology for the error you've encountered. This error is due to a regression we introduced in our SDK and fixed right after. You shouldn't have this error displayed again. Can you confirm this?
We have a number of clients who have youtube video advertisements. These are currently in a YouTube playlist, but by embedding the playlist, the same video is always displayed first on the website so we want to randomise which video is displayed on pageload from the playlist. I have a code snippet which will load a random video from the input video url however when the video is finished it does not move on to the next video in the list. Could anyone suggest how I can accomplish what I am trying to do? My code is below.
<!-- Youtube video loop playlist -->
<script>
var videos = ["https://www.youtube.com/embed/9bZkp7q19f0", "https://www.youtube.com/embed/dQw4w9WgXcQ", "https://www.youtube.com/embed/CzJ-h7W1hVw"];
window.onload = function () {
var playerDiv = document.getElementById("random_player");
var player = document.createElement("IFRAME");
var randomVideoUrl = videos[Math.floor(Math.random() * videos.length)];
player.setAttribute('width', '528');
player.setAttribute('height', '330');
player.setAttribute('src', randomVideoUrl);
playerDiv.appendChild(player);
};
onStateChange: function(e){
var id = 'qzZuBWMnS08';
if(e.data === YT.PlayerState.ENDED){
player.loadVideoById(videos);
}
}
</script>
<div id="random_player"></div>
Thank you in advance.
Donna
The function loadVideoById can either get a single ID or a single video in an object syntax. It can't receive an array of videos or a playlist.
Here's my implementation
http://jsfiddle.net/thatkookooguy/e11oy0eu/2247/
(code also embedded at the end)
Notice that the setTimeout is used since there's a bug with the youtube API. if you set either setShuffle or playVideoAt immediately, nothing happens (or the playlist resets and starts from the beginning).
You can add anything else you want to change in the player's playback options (shuffle, loop). If it doesn't work as is, try to add those parameters to the setTimeout as well.
reference: youtube API - setShuffle don't work
// This code loads the IFrame Player API code asynchronously.
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;
// load the playlist
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
events: {
'onReady': onPlayerReady
},
playerVars: {
listType: 'playlist',
list: 'PLOy0j9AvlVZPto6IkjKfpu0Scx--7PGTC'
}
});
}
// when the video player is ready, generate a random number, and play from that
function onPlayerReady(event) {
// create a random number between 0 and 149
num = Math.floor(Math.random() * 150);
// the timeout is set because of a bug with the youtube API. if you do any of this line without it, it won't affect anything
// see: https://stackoverflow.com/questions/12916017/youtube-api-setshuffle-dont-work
setTimeout(() => {
player.playVideoAt(num);
}, 1000);
}
<div id="player"></div>
My page has several youtube player, it caused the page loading slowly.
This is my code↓
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player1', {
height: '100%',
width: '100%',
videoId: 'mCx3oxXBmGA'
});
player2 = new YT.Player('player2', {
height: '100%',
width: '100%',
videoId: 'SpWR0sSEgMc'
});
the HTML↓
<div id="player6"></div>
There are 12 video in this page, how can I optimized it?
Do not embed all 12 players at once. Instead present some cover image of the YouTube movie (static img) and bind click event on it.
When user will click specific image, remove it from the DOM and create player instead of it.
This is very weird. I'm using youtube JavaScript API to embed a playlist on my website. It would be all good except my recent check what's happening in my workers. It seems that the API decided to send it's messages to one of it.
here's the data which my worker is receiving.
bubbles: falsecancelBubble: falsecancelable: falsecurrentTarget: Windowdata: "{"event":"infoDelivery","info":{"currentTime":109.455757,"videoBytesLoaded":1,"videoLoadedFraction":1},"id":1}"defaultPrevented: falseeventPhase: 0lastEventId: ""origin: "https://www.youtube.com"path: Array[1]ports: Array[0]returnValue: truesource: WindowsrcElement: Windowtarget: WindowtimeStamp: 1428083437641type: "message"__proto__: MessageEvent
Also as I've seen in another question Youtube API does this
www-embed-player.js:167 GET chrome-extension://enhhojjnijigcajfphajepfemndkmdlo/cast_sender.js net::ERR_FAILED
I wasn't expecting Google to create such faulty API. Is there a way to disable those things?
Quick experiment rendered a solution. Moved all youtube code to a separate html and embedded in my parent page.
<iframe id="youtubePlayer" src="mediaPlayer.html">
You can still access youtube api from your main page like that
var mediaPlater = document.getElementById('youtubeFrame').contentWindow.player;
// i.e. skip to next video
mediaPlayer.nextVideo();
This solved totally unexpected worker activity. This console error remained but after reading that it's a won't-fix it doesn't bother me.
www-embed-player.js:167 GET chrome-extension://
Content of my mediaPlayer.html
<div id="ytplayer" class="musicPlayer"></div>
<script>
var player = null;
// 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);
// Replace the 'ytplayer' element with an <iframe> and
// YouTube player after the API code downloads.
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer', {
height: '180',
width: '280',
playerVars: {
autoplay: 1,
controls: 0,
listType: 'playlist',
list: 'RD4-OlYiH1DXI'
},
events: {
'onReady': onPlayerReady,
'onError': function () {
setTimeout(function () {
player.nextVideo();
}, 200);
}
}
});
}
function onPlayerReady() {
// fixes firefox ignoring first onerror if the first video is faulty
player.nextVideo();
}
</script>
Having problems getting a Chromeless player with autoplay to work. The code I am trying was copied directly from the developers.google.com documentaiton:
https://developers.google.com/youtube/youtube_player_demo
IFRAME Example: http://jsfiddle.net/BN6Sa/
<iframe width="720" height="405" src="//www.youtube.com/embed/M7lc1UVf-VE?feature=player_embedded&autoplay=1&controls=0&loop=1&modestbranding=1&rel=0&showinfo=0&theme=light" frameborder="0" allowfullscreen></iframe>
JS Example: http://jsfiddle.net/7DWTU/
<div id="ytplayer"></div>
<script>
// 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);
// Replace the 'ytplayer' element with an <iframe> and
// YouTube player after the API code downloads.
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer', {
height: '405',
width: '720',
videoId: 'M7lc1UVf-VE',
autoplay:1,
controls:0,
loop:1,
rel:0,
showinfo:0,
theme:'light'
});
}
</script>
When using the iFrame API, anything that's a player object parameter (i.e. something that you might append as a URL parameter if you were to embed the player just as an iFrame rather than with the API) needs to be set as part of the playerVars parameter object rather than as a direct parameter to the YT.Player argument. Specifically, your code should look like this:
<div id="ytplayer"></div>
<script>
// 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);
// Replace the 'ytplayer' element with an <iframe> and
// YouTube player after the API code downloads.
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer', {
height: '405',
width: '720',
videoId: 'M7lc1UVf-VE',
playerVars: {
autoplay:1,
controls:0,
loop:1,
rel:0,
showinfo:0,
theme:'light'
}
});
}
</script>