Multiple iframe embeds with youtube api - javascript

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>

Related

How can I detect if YouTube videos have been removed using their iFrame API

Is it possible to detect if a video has been removed or is no longer available on Youtube using the iFrame API?
The following code will detect changes to the youtube iframe but the only data point I can find thats remotely close is -3 which means unstarted but this could be applicable to any working video as well.
CodePen
<iframe id="yt-iframe" width="630" height="354" src="http://www.youtube.com/embed/Rlm8YH2i9gY?enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>
<script type="text/javascript">
var tag = document.createElement('script');
tag.id = 'yt-script';
tag.src = 'https://www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
console.log('yt scripts loaded');
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('yt-iframe', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
console.log('video player ready');
}
function onPlayerStateChange(event) {
console.log(event.data);
}
</script>
You can detect before playing the video by checking the duration of the video, if duration of the video is 0 seconds then it is highly likely to be deleted/can't be played
<iframe id="yt-iframe" width="630" height="354" src="http://www.youtube.com/embed/tPEE9ZwTmy0?enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>
<script type="text/javascript">
var tag = document.createElement('script');
tag.id = 'yt-script';
tag.src = 'https://www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
console.log('YT scripts loaded');
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('yt-iframe', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
console.log('Video player ready');
if (event.target.getDuration() <= 0) {
console.log('Video likely to be removed');
}
}
function onPlayerStateChange(event) {
console.log(event.data);
}
</script>
Setup an onError event handler and check for event.data === 100. The YouTube IFrame Player API describes all of the player error events.
No, atleast not straightforward.

YouTube onPlayerReady is never triggered

Any idea why this script doesn't work? All I want is to track onStateChanged event, but that is never called either.
When I open the html document with below code, I have no errors, the youtube script loads just fine, the player object is not undefined, looks fine too.
$(document).ready(function(){
loadScript();
});
function loadScript() {
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
}
});
alert(player);
}
var done = false;
function onPlayerStateChange(event) {
alert('state changed');
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 3000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
function onPlayerReady(event) {
event.target.playVideo();
}
My iframe:
<iframe id="player width="400" height="300" src="https://www.youtube.com/embed/j0pJekWgeFE" frameborder="0" allowfullscreen></iframe>
See fiddle: https://jsfiddle.net/rg2uy1f8/
I found an answer here: How do I get the reference to an existing YouTube player?
The reason my solution didn't work, was that my iframe was missing an attribute: enablejsapi="1" and also I was missing: ?enablejsapi=1 in YouTube video url.
You may find the working solution here: http://jsfiddle.net/bf7zQ/2/

Cannot fire "loadVideoByUrl('...')" of Youtube's Iframe-API – undefined

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();
}

player.mute() not working in YouTube API with playlist

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.

Youtube API how to play video from 0 seconds when video ends? Iframe, Javascript

So I have My code it detects when the player has stopped the problem is I can't get it to play from 0 seconds when the end has come I'm using the Iframe embed that holds a html5 video, Here is the code!
<div id="youtube-fs"><iframe id="youtube-iframe" type="text/html" src="http://www.youtube.com/embed/LYL0lzmrvk8?enablejsapi=1&html5=1&autoplay=1&showinfo=0&controls=0&rel=0&wmode=transparent&vq=hd1080&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;
function onYouTubePlayerAPIReady() { player = new YT.Player('youtube-iframe', { events: { 'onStateChange': onPlayerStateChange } }); }
function onPlayerReady(event) { event.target.playVideo(); }
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) { player.playVideoAt(0); } // Play from 0 seconds
}
-->
</script>
</div>
Any idea's? maybe seekTo? or something
Thank you in advance!
Used player.seekTo(1, true); that worked
Try this
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
player.seekTo(0);
player.playVideo();
} // Play from 0 seconds
}
http://plnkr.co/aoSupfT7vXGGoM99sNwl

Categories

Resources