Youtube - onStateChange working on one video but not another - javascript

The same code behaves differently, when you change the YouTube video ID.
The issue is that when you pull the progress slider, it fires the onStateChange event on one video, but not the other. Check the two examples below, and try to pull the timeslider on both examples and watch your console.log.
Why does only one of the videos react to onStateChange when you pull the time slider?
Both videos react fine to the play/pause button, but not the time slider... only one is working.
Am I missing something? Any help really appreciated
Youtube code 1 (working):
(http://jsfiddle.net/2t9omgwm/)
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. 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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
iv_load_policy: 3,
showinfo:0,
//videoId: 'Fj73JF_bhjc',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
//event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
console.log('state changed');
//player.seekTo(0, true);
if (event.data == YT.PlayerState.PLAYING && !done) {
done = true;
}
}
</script>
And with another video its not working:
(http://jsfiddle.net/ctgomt7t/)
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. 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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: '0Bmhjf0rKe8',
iv_load_policy: 3,
showinfo:0,
//videoId: 'Fj73JF_bhjc',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
//event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
console.log('state changed');
//player.seekTo(0, true);
if (event.data == YT.PlayerState.PLAYING && !done) {
done = true;
}
}
</script>
`

The onPlayerStateChange event is fired for one of the following reasons:
-1 = unstarted
0 = ended
1 = playing
2 = paused
3 = buffering
5 = video cued
I think what you are seeing on the longer video is the event firing for (3) buffering when you move the slider. However, on the shorter video there is no buffering so you don't see the event.
You can see this by changing your code to read console.log('state changed : ' + event.data).

Related

Add video to page using YouTube Player API

I want to load a YouTube video on a button click using the Player API. The goal is that a user can input a video url, click a button, and then the video loads below (I excluded the form input below to make it a little simpler).
I've tried using location.reload(); to force reload the page, and checked out some other similar questions which aren't entirely helpful because they don't use the API (which I need to use for later when functionality added)
This example from the docs works fine:
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. 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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
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();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
I want to get something like this (very similar version) to work. I'm not sure why it doesn't currently.
<!DOCTYPE html>
<html>
<body>
<input type="submit" value="Submit" id="submit">
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
document.getElementById("submit").addEventListener("click", function() {
location.reload();
// 2. 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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
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();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
});
</script>
</body>
</html>
You have two issues.
1) onYouTubeIframeAPIReady is never called because it is defined after the youtube API loads. You can see this by adding a console.log.
2) When you reload the page, the page reloads; i.e. your previous variables and video and everything are gone.
Here's a minimal example to load & play a youtube video on button click:
<input type="submit" value="Submit" id="submit">
<div id="player"></div>
<script src="https://www.youtube.com/iframe_api"></script>
<script>
document.getElementById('submit').addEventListener('click', () => {
new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
onReady: e => e.target.playVideo()
}
});
});
</script>
Note, the youtube code samples are either trying to be backwards compatible or just haven't been rigorously updated. They don't follow modern styles (e.g. they use var instead of let, == instead of ===, " instead of ', etc.

Youtube's onStateChange is not fired if play is triggered by postMessage

If the youtube playVideo is triggered by postMessage, the onStateChange will not be fired. (http://jsfiddle.net/nedvedyy/smx92nq0/). Any one runs into it before?
<script src="jquery-1.10.2.min.js"></script>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<button class="button">BUTTON</button>
<script>
// 2. 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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: '0Bmhjf0rKe8',
playerVars: {
'controls': 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
var playerReady = false;
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
playerReady = true;
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
function onPlayerStateChange(event) {
alert(event);
}
$(".button").on("click", function() {
document.getElementById('player').contentWindow.postMessage(JSON.stringify({
'event': 'command',
'func': 'playVideo',
'args': []
}), "*");
});
</script>
Strangely, if the playVideo is called like below, the onStageChange can be captured.
onPlayerReady=function(event) {
console.log("hey Im ready");
event.target.playVideo();
}
Did you complete your homework here? Go through complete manual, your solution is there from where you pasted.
https://developers.google.com/youtube/iframe_api_reference

simple Youtube iframe API right out of the documentation, what am I doing wrong?

http://jsfiddle.net/y2Y5k/
I'm trying to make a simple youtube player with the javascript API and I'm doing something wrong.
In that fiddle, Im just using the exact code snippets from the documentation provided by google.
I loaded the api as a source.
I placed a div with the id 'player'.
What did I do wrong here?
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. 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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
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();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
It is because Fiddle. All JavaScript you put in there is encapsulated in other functions (probably window.onload or something).
Therefore Youtube can't get to your onYouTubeIframeAPIReady function.
Just try this outside Fiddle. It will work.
On the top left side, from Frameworks & Extensions, select No wrap - in instead of onLoad.
That will give you the result as expected.

YouTube API to play random video from tag

I have YouTube API which I got from this link...
https://developers.google.com/youtube/iframe_api_reference
It's working okay, but I am looking for a way for it to play a random video based on a tag...is this possible? Is there a tutorial on it?
Here is my code
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. 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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'u1zgFlCw8Aw',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
Make Ajax function call to handle the request
function request_yt_videoID(vid)
{
// Some Code
player.loadVideoById(vid);
}
Visit Google Developer Site: https://developers.google.com/youtube/iframe_api_reference#loadVideoById

Youtube iframe player doesn't embed using Youtube's Player API

I am referring to the example code provided by Youtube seen below. The sample code is suppose to ....
The sample HTML page below creates an embedded player that will load a
video, play it for six seconds, and then stop the playback.
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'u1zgFlCw8Aw',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
Here's jsFiddle link for the code above.
Can you tell why this isn't working?

Categories

Resources