I am trying to use the YouTube iframe API to fire an event after a video is finishing playing. The iframe containing the YouTube video is loaded with the document and has the enablejsapi=1 parameter in the URL like so:
<iframe id="myytplayer" src="http://www.youtube.com/v/8mmd_eHYmMY?enablejsapi=1&playerapiid=ytplayer&version=3" allowfullscreen="" frameborder="0"></iframe>
I have successfully implemented the onYouTubeIframeAPIReady function but I cannot add an event listener to the YouTube object once it is ready. The player state alert does not show when playing/pausing the video. Here is my javascript code:
function onytplayerStateChange(newState) {
alert("Player's new state: " + newState);
// check player ended
}
function onYouTubeIframeAPIReady() {
alert("ready");
ytplayer = document.getElementById("myytplayer");
ytplayer.addEventListener("onStateChange", onytplayerStateChange);
}
I also had to load the following resource in order to get the "ready" alert to show up.
<script src="http://www.youtube.com/player_api" type="text/javascript"></script>
I have created a jsFiddle here.
You can't add an event listener just to the DOM element (as you could do in the older javascript API); with the iframe API you have to create a YT.player object based on the DOM element first, and then add the event listener there. Something like this:
function onYouTubeIframeAPIReady() {
ytplayer = YT.Player("myytplayer", {
events: {
'onStateChange': onPlayerStateChange
}
}
Also, be a bit careful loading the player_api via a script tag ... there's no guarantee that your onYouTubeIframeAPIReady function will be defined when that's fully loaded. Better to do something like this, before defining your ready function:
<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);
Related
Good day,
I know this question has been asked many times. I searched high and low to get it to work but it seems that something has changed that the answers are not working anymore.
On YouTube, when I run this simulateClick function in the console. It works.
function simulateClick() {
var evt = new MouseEvent("click", {
bubbles: true,
cancelable: true,
view: window
});
var cb = document.getElementsByClassName("ytp-play-button")[0]; //element to click on
var canceled = !cb.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
That is because there is a button called "ytp-play-button".
However, when I take that to YouTube TV (formerly leanback). It does not work. The div function there has a "role=button".
This is the div responsible for the play button.
<div class="toggle-button selected material-icon-play-arrow toggle-selected transport-controls-toggle-button" tabindex="-1" role="button" style=""> <div class="background"></div> <span class="label">Pause</span></div>
So I changed the "ytp-play-button" to the "material-icon-play-arrow" but even though it gets the class right. It does not work.
Any pointers would be truly appreciated it. Thank you.
P.S.: This is a pure JavaScript question not a jQuery one.
Edit#1: When I tried to run the onclick like this in the console
document.getElementsByClassName("material-icon-play-arrow")[0].onclick()
I got this error.
Uncaught TypeError: document.getElementsByClassName(...)[0].onclick is not a function
at :1:64
(anonymous) # VM7969:1
You can use YouTube Iframe Player API for set a embed YouTube video and control the way you can interact with the video.
For your specific case, you need play/pause a YouTube video by clicking an HTML element (in this case, a div element).
For achieve this functionality, you can use the following code - see the working sample in this jsfiddle.
There, basically I have a div element (called playButton) and (using the onPlayerStateChange function) I set the click event as follows:
When the video is playing, the div playButton will have its text as "Pause" and its click event allows pause the video.
When the video is paused, the div playButton will have its text as "Play" and its click event allows play the video.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// Variables of the divs (where the YouTube iframe will load):
var player;
function onYouTubeIframeAPIReady() {
// Div player:
player = new YT.Player('player', {
height: '360',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
// After loading the iframe, set the "playVideo" onclick event on "playButton" anchor element.
document.getElementById('playButton').onclick = function() {
player.playVideo();
};
}
// 5. The API calls this function when the player's state changes.
function onPlayerStateChange(event) {
// If the video is PLAYING, set the onclick element for pause the video.
// Once the "playButton" is clicked, the video will be paused.
if (event.data == YT.PlayerState.PLAYING) {
document.getElementById('playButton').innerHTML = 'Pause';
// Set the onclick event to the button for pause the YouTube video.
document.getElementById('playButton').onclick = function() {
player.pauseVideo();
};
}
// If the video is PAUSED, set the onclick element for pause the video.
// Once the "playButton" is clicked, the video will resume the video = continue playing the video.
if (event.data == YT.PlayerState.PAUSED) {
document.getElementById('playButton').innerHTML = 'Play';
document.getElementById('playButton').onclick = function() {
player.playVideo();
};
}
}
// Div "player" - The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
<!-- In this div, the YouTube video will be loaded with YouTube iframe Player API. -->
<div id="player"></div>
<!-- N.B this is the div element used for play or pause the current video loaded with YouTube iframe Player API. -->
Play
Here is the "Playback controls and player settings" in the official documentation for further details.
OK, this has been asked many times before – but Youtube seems to change things up every other day. I can't find a way to force a Youtube embed to start playing a HD source from the beginning. The switch to HD always happens after 5-10 seconds.
Methods that don't work (anymore):
Adding &hd=1 parameter to the iframe src
Adding &vd=hd720 or &vd=hd1080 parameters to the iframe src. Described here: Force youtube embed to start in 720p
Changing the iframe dimenstions to width="1280" heigh="720" in the html embed code and then using CSS to scale the iframe back down/up to the parent div. Described here: http://thenewcode.com/717/Force-Embedded-YouTube-Videos-To-Play-In-HD and here: How to force youtube to play HD videos
The only possible way would be using the Youtube JavaScript API, as described here:
http://biostall.com/the-100-guaranteed-method-to-get-youtube-iframe-embeds-playing-in-hd-by-default/
// 1. 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);
// 2. This function creates an <iframe> (and YouTube player) after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '1280',
width: '720',
videoId: 'E37YNMYlKvo',
events: {
'onReady': onPlayerReady
}
});
}
// 3. The API will call this function when the video player is ready.
function onPlayerReady(event) {
player.setPlaybackQuality('hd1080'); // Here we set the quality (yay!)
event.target.playVideo(); // Optional. Means video autoplays
}
<div id="player"></div>
But: I want to use a simple iframe embed since videos will be embeded through the wordpress oembed feature.
Is there any way to run the player.setPlaybackQuality('hd1080'); function for a simple iframe embed?
You can also set your playerVars
vq: 'hd1080',
144p: &vq=tiny
240p: &vq=small
360p: &vq=medium
480p: &vq=large
720p: &vq=hd720
1080p: &vq=hd1080
From what I understand, there seems to be a 'VQ' parameter that you can attach to the end of the embed iframe and set hd720 or hd1080 as the value. After some research it seems YouTube once offered the 'VQ' parameter, then took it away, and as of this writing is back again! In short, your embed should look something like this:
<iframe src="https://www.youtube.com/embed/VIDEO_ID_HERE?vq=hd1080" frameborder="0" allowfullscreen></iframe>
Here is an article related to this that I found during my research: Found Here
I've tested this briefly on a page and it seems to work (for now). Hope this helps!
What I want is to have a DIV divided in two, so that when clicking on the left DIV it expands to full height and starts playing the video, while closing it with a close button, the video pauses and the left DIV regains its normal height and width.
I found this code whitch is what im looking, but now I have to add the iframe and make it play and pause in while clicking the play and close button:
[1]: http://jsfiddle.net/davidThomas/CFNUJ/1/
Any ideas?
Thanks!
As explained in the full YouTube player API here, you will want to create an empty div with an id of player for this script to hook into. Once the onPlayerReady event fires, you can hook into the javascript player object that the script creates and use it to manipulate the video player with calls like player.playVideo(). The iframe that replaces your empty div can then be modified like any other DOM element to change the size of the video player.
Note: The script I'm providing is cut down from the original API example so that it doesn't stop after 6 seconds
<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();
}
function onPlayerStateChange(){
//Do Nothing for now
}
</script>
I want to load a YouTube video, then mute, play, pause, and unmute it immediately. In doing this, I hope to present the user with a video that doesn't have a big play button on it, and does have the controls on the bottom. In order to do this, I have the following code:
<script type="text/javascript">
function onYouTubePlayerReady(playerid)
{
mutePlayPauseUnmute(playerid);
}
function onYouTubePlayerAPIReady(playerid)
{
mutePlayPauseUnmute(playerid);
}
function onYouTubeIframeAPIReady(playerid)
{
mutePlayPauseUnmute(playerid)
}
function onPlayerReady(playerid)
{
mutePlayPauseUnmute(playerid)
}
function mutePlayPauseUnmute(playerid)
{
var player = document.getElementById(playerid);
player.mute();
player.playVideo();
player.pauseVideo();
player.unMute();
}
</script>
<iframe id="quotedVideo1" type="text/html" width="246" height="160" src="https://www.youtube.com/embed/NWHfY_lvKIQ?modestbranding=1&rel=0&showinfo=0&autohide=1&iv_load_policy=3&theme=light&enablejsapi=1&playerapiid=quotedVideo1" frameborder="0"> <!-- Magic Comment --> </iframe>
However, upon inspection, neither onYouTubePlayerReady, onYouTubePlayerAPIReady, onYouTubeIframeAPIReady, onPlayerReady, nor mutePlayPauseUnmute is ever called. What have I done wrong? According to https://developers.google.com/youtube/js_api_reference#onYouTubePlayerReady it looks like it should work, but it doesn't.
You're confusing two different player APIs here.
Do you want to use the iframe player? If so, you'll want to look at: https://developers.google.com/youtube/iframe_api_reference.
Instead of defining onYouTubePlayerReady, you'll want to define the following method: onYouTubeIframeAPIReady, create your player, and then assign an onPlayerReady callback.
Make sure you're including the JavaScript for the iframe player API, in order for onYouTubeIframeAPIReady to be called:
var tag = document.createElement('script');
tag.src = o.protocol + "://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
Worth noting from the doc, since you're writing the iframe instead of using JavaScript to do that for you:
If you do write the tag, then when you construct the
YT.Player object, you do not need to specify values for the width and
height, which are specified as attributes of the tag, or the
videoId and player parameters, which are are specified in the src URL.
Also, in your mutePlayPauseUnmute function..
playerid.mute();
playerid.playVideo();
playerid.pauseVideo();
playerid.unMute();
You'll want to trigger the actual the methods on the player as opposed to the playerid as described above.
I want to use the YT.Player code so that I can detect events. I have a CSV file with Youtube video ID's and a function that puts the ID's in an array and want to be able to dynamically change the ID when a user click an image. Essentially like this:
html
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
javascript
// 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.
// NOTE: videoId is taken out and instead is placed as the generated IFRAME src from the postSelection function
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '100%',
width: '100%',
videoId: '<<CALL TO FUNCTION OR VARIABLE HERE>>',
events: {
//'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
If you are familiar with this code then what happens is the #player DIV is replaced by an IFRAME. I can change the IFRAME source with this function:
function postSelection() {
$("#player").attr("src", _selected.attributes.url); //_selected.attributes.url comes from the CVS file
}
But this is very buggy and not cross browser friendly. If I use a standard IFRAME and not the YT Player API then everything works just fine. But I want to detect the end, and pause and so on so I have to use the API. My guess is that it is an issue with state and that persistence is lost some where in the creation of the IFRAME.
Regards.
This is very simple to do with the js api. When you want to load a new video just call player.loadVideoById(videoId); Details at https://developers.google.com/youtube/iframe_api_reference#loadVideoById
In case this is of help to anyone struggling as I did...
This player.loadVideoById(videoId) was only working for me when videoId was hardcoded e.g.
player.loadVideoById('sdfexxdfse')
When I tried to put that value into a variable directly or when storing in an array it wasn't working even though it contained the same information.
The video was coming up with incorrect parameter each time.
Adding it to a variable in this way
var x = new String(variabledatahere)
did the job.