it seems that I am missing something obvious here but I can not get
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('player1');
// here everything is fine and I can see the
// function as part of player
console.log(player);
// but here it says "player.loadVideoByUrl()" undefined
player.loadVideoByUrl("https://youtu.be/bHQqvYy5KYo");
player.playVideo();
}
to work. Any ideas?
Thanks in advance!
I assume that player is not initialized while you're calling the loadVideoByUrl function. In documentation, they use
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
events of player. It seems player object constructs asynchronously. So if you use those events, code becomes like below:
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('player1', {
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(){
player.loadVideoByUrl("https://youtu.be/bHQqvYy5KYo");
player.playVideo();
}
Related
im customizing my youtube player, but im getting a error, i already check if the problem was not wrapping in a ready function, but still getting the error
"Uncaught ReferenceError: YT is not defined"
Js:
//youtube script
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
onYouTubeIframeAPIReady = function () {
player = new YT.Player('player', {
height: '193',
width: '284',
videoId: 'jGa2J3RBPtQ', // youtube video id
playerVars: {
'autoplay': 0,
'rel': 0,
'showinfo': 0
},
events: {
'onStateChange': onPlayerStateChange
}
});
}
onPlayerStateChange = function (event) {
if (event.data == YT.PlayerState.ENDED) {
$('.start-video').fadeIn('normal');
}
}
$(document).on('click', '.start-video', function () {
$(this).fadeOut('normal');
player.playVideo();
});
html:
<div id="player"></div>
<button class="start-video">Play</button>
Have you tried switching to the HTTPS protocol?
Worked for me here
tag.src = "https://www.youtube.com/iframe_api";
I have one Youtube video which has 6 episodes and I have six buttons which onclick will skip to the start of that particular episode.
Here is the working fiddle for that.
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', {
height: '360',
width: '640',
videoId: 'L6cVcbkx8l8',
events: {
'onReady': onPlayerReady,
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
$('#episode1').click(function(evt){
console.log($(evt.currentTarget).val());
player.seekTo(50)
})
$('#episode2').click(function(evt){
console.log($(evt.currentTarget).val());
player.seekTo(100)
})
$('#episode3').click(function(evt){
console.log($(evt.currentTarget).val());
player.seekTo(150)
})
}
What I am actually trying to do is when someone is clicking on episode2, it should play between only that time code (say xx.yy to aa.bb). So, how do I mention the end time for each episode onclick.
I want to mute a video after it plays for 9 seconds. I tested various things including cuePlaylist and other stuff.
Following is the code -
<div id="topplayer" align="center"></div>
<script>
jQuery(document).ready(function( $ ) {
var done = false;
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 onYouTubeIframeAPIReady() {
topplayer = new YT.Player('topplayer', {
height: '315',
width: '560',
events: {
'onReady': onTopPlayerReady,
'onStateChange': onTopPlayerStateChange
}
});
}
function onTopPlayerReady(event) {
event.target.loadPlaylist({
listType:'playlist',
list: 'PL55713C70BA91BD6E',
index: 0,
});
event.target.playVideo();
}
function onTopPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(muteVideo, 9000);
done = true;
}
}
function muteVideo() {
topplayer.mute();
}
</script>
Now, with this code Video Playlist loads and autoruns (which I want) but it never mutes.
PS. I tried default example provided in official developers.google.com for YouTube API and changed player.stopVideo() to player.mute() and it works. So, I believe the problem is somewhere coming when am trying to load a playlist instead of a single video. The following code works well (it autoruns and mutes the video too) -
<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', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.mute();
}
</script>
You have a syntax error in your javascript; you define the done variable as local inside jQuery's ready method, and hence that variable is not available to any of the other methods (you can verify this by opening Chrome's dev tools while you run your code; you'll see that the onPlayerStateChange method is complaining that there is no done variable).
The solution would be to move the declaration of that variable outside of the ready method, like this:
var done = false;
jQuery(document).ready(function( $ ) {
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});
Everything else can stay the same.
My coding knowledge is mostly self-taught and limited.
I have a forum which I have set to replace youtube URLs in posts with iframe embeds of the video. The one unique aspect to it was that it was forcing the embeds to play at 720p quality (if available) even if the player was smaller than youtube recommends. The "why" is a long story but I want to keep doing it that way. I'm trying to get the same thing working with the new API.
In the sample code below I can get it working for one video on a page but not both on the same page. I imagine it has something to do with duplicate functions or something along those lines.
<html><body>
<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 xyzplayer;
function onYouTubeIframeAPIReady() {
xyzplayer = new YT.Player('xyzplayer', {
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
event.target.setPlaybackQuality('hd720');
}
}
</script>
<iframe id="xyzplayer" type="text/html" width="832" height="468" src="http://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1&html5=1" frameborder="0"></iframe>
<br><br><br>
<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 abcplayer;
function onYouTubeIframeAPIReady() {
abcplayer = new YT.Player('abcplayer', {
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
event.target.setPlaybackQuality('hd720');
}
}
</script>
<iframe id="abcplayer" type="text/html" width="832" height="468" src="http://www.youtube.com/embed/IwfUnkBfdZ4?enablejsapi=1&html5=1" frameborder="0"></iframe>
</body></html>
Because your code is loading the library twice, the second load overrides the functions you're defining in the first and hence events from the first one will never be handled. Try combining the player creation into a single method ... something like this (so that players for both embeds get their events listened to):
<html><body>
<iframe id="xyzplayer" type="text/html" width="832" height="468" src="http://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1&html5=1" frameborder="0"></iframe>
<br/><br/><br/>
<iframe id="abcplayer" type="text/html" width="832" height="468" src="http://www.youtube.com/embed/IwfUnkBfdZ4?enablejsapi=1&html5=1" frameborder="0"></iframe>
<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 abcplayer,xyzplayer;
function onYouTubeIframeAPIReady() {
abcplayer = new YT.Player('abcplayer', {
events: {
'onStateChange': onPlayerStateChange
}
});
xyzplayer = new YT.Player('xyzplayer', {
events: {
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
event.target.setPlaybackQuality('hd720');
}
}
</script>
</body></html>
I am using the iFrame Youtube API with the following code. I call this view with Ajax to render it and append it in a div.yt-player within my page. It works the first time I call the view, but after I close the video (it empties the div.yt-player) and click on another link that calls my view, the video doesn't load at all (blank). I've been struggling and still don't see why it happens, especially that it works the first time. Any kind of help would be much appreciated.. Thanks.
PS: Both the html and the javascript are rendered by the view.
Html
<div id="player"></div>
Javascript:
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', {
height: '486',
width: '864',
videoId: '#{#media['youtube_url']}',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
},
playerVars: {
'showinfo': 0,
'iv_load_policy': 3,
'color': 'white',
'fs': 1,
'autoplay': 1,
'vq': 'hd720'
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
Just check if the script has been defined.
if(document.getElementById('iframe_api') === null){
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
tag.id = "iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
else
runPlayer();
function runPlayer(){
var player;
player = new YT.Player(element.children()[0], {
playerVars: {
autoplay: 1,
html5: 1,
controls: 1,
showsearch: 0,
showinfo: 0
},
height: scope.height,
width: scope.width,
videoId: scope.videoid,
events: {
onStateChange: function (event) {
if (event.data == YT.PlayerState.ENDED) {
scope.$emit('VideoEnded');
}
}
}
});
}
$window.onYouTubeIframeAPIReady = function () {
runPlayer();
};
I debugged the problem. onYouTubeIframeAPIReady() is called only the first time the YouTube API is loaded (when the user refreshes the page and clicks on the link to the view for example), and because I'm calling my views in Ajax, it didn't get fired up the following times.
So I replaced the first block of code by wrapping it in a conditional:
if (typeof youtube_api_init == '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);
}
and
if (typeof youtube_api_init != 'undefined') {
onYouTubeIframeAPIReady();
}
and at the end of the script, I set the youtube_api_init for the browser to remember the YouTube API has already been loaded:
var youtube_api_init = 1;
PS: the first time I tried, I called my variable yt_api_init instead of youtube_api_init, and it didn't work cause it happens that's a name YouTube already uses in its api...