I am working on a small project that envolves geting the time to wich a user skips to when playing a video.
I am using the javascript part of the API to play the video, pause and so on, but I cannot seem to understand how to get the time that the user skips to. I know I can seekTo on my own... But there seems to be no corresponding event for when the user does this
I am trying to find the event that fires when the user skips to a certain time...
From YT API I see they do not have such an event (in javascript... I wouldn't like to create my own custom player based on HTML5 and/or AS3).
It seems that there isn't a real way to do it, but probably you can "intercept" it and understand it, it won't take long:
In this page you can see all the featurea available for the api. You can do it in 2 way:
checking and confronting the time of the video with a counter continuously (probably a bad idea).
Intercepting the player state:
There are 5 state for the player, when the player cursor is moved:
-if the player was playing, the state go from 1 to 2 and then from 2 to 1.
-if the players was paused, nothing happens to his state.
Considering that you can intercept the player state you can easily get the current time when the player is paused and then, confront it with the current time when the user restart play. In each of the 2 case, you should be able to know if the user moved or not the cursor. I don't know well this api so I don't know if some other state of the player can mean something important for your question. I think this way, if isn't complete, it's a good start from where begin developing your idea.
UPDATE
HERE IS THE CODE EXAMPLE TESTED + JSFIDDLE
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
var doing = -1;
var timenow=0;
var timeold=0;
var flag=0;
// 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(flag==1){
flag=0;
timenow=timeold;
}else{
if((doing==-1)&&(event['data']==1)){//start play
doing=1;
}
if((doing==1)&&(event['data']==2)){//from play to pause
timeold=player.getCurrentTime();
timeold=timeold;
doing=2;
console.log('go pause at:'+timeold);
}
if((doing==2)&&(event['data']==1)){//from pause to play
timenow=player.getCurrentTime();
console.log('go play at:'+timenow);
if(timenow>timeold){
alert('are you kidding me?! You switched from '+timeold+' to '+timenow+'!');
player.seekTo(timeold);
flag=1;
}else{
timeold=timenow;
}
}
if(event['data']==5 || event['data']<1){//stopped or ended
doing=-1;
timeold=0;
timenew=0;
}
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
Related
When I load a youtube video into my web page, I want it to default to playing from the beginning. I'm using javascript code to control it and I need it to start there initially. Every time I reload the page, though, the video plays where it left off and I can't test my script.
Following the API's documentation this should work:
<div id="player"></div>
<script>
// The IFrame Player API code should be added here
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
videoId: 'UG8DX3LxDb8',
playerVars: {
'start': 0
},
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
</script>
This code generates an iframe showing the video with id 'UG8DX3LxDb8' and the playerVar start tells the API to start at 0 seconds.
I have been trying to change the video playback quality/resolution of an iframe embedded video from YouTube using YouTube IFrame API by simply calling player.setPlaybackQuality("hd720") in the middle of playback.
According to YouTube: https://developers.google.com/youtube/iframe_api_reference#setPlaybackQuality
"The function causes the video to reload at its current position in the new quality."
BUT, the quality of the video is changing only when the current playback time reaches the end point of the buffered old quality stream. So, how can I force the player to buffer the video at the new resolution at that very moment and start showing it from exactly that 'current duration' of the video just as it happens inside YouTube?
By the way, I'm using pre-defined iframe tag in the html with all the parameters in the embed URL, like so:
<iframe id="genesis" src="https://www.youtube.com/embed/EZgTo1kKSsg?enablejsapi=1&controls=0&showinfo=0&iv_load_policy=3&modestbranding=1&rel=0&fs=1" frameborder="0"></iframe>
And creating the player, like so:
$.getScript("https://www.youtube.com/player_api");
function onYouTubeIframeAPIReady() {
player = new YT.Player('genesis', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
'onPlaybackQualityChange': onQualityChange
}
});
}
function onQualityChange(){
console.log('Now playing at ' + player.getPlaybackQuality());
// Though it returns "hd720" within a few moments after hitting
// setPlaybackQuality("hd720"), actual playback quality remains the older one.
}
$(document).on('click', '.play', function(){
player.playVideo();
});
$(document).on('click', '#res_change_while_playing', function(){
player.setPlaybackQuality($(this).data("id")); // data-id="hd720"
});
Please help!
Thanks.
You can use seek function to re-buffer the video after you call setPlaybackQuality function
function onQualityChange(){
player.setPlaybackQuality("small")
player.seekTo(60) // or set to CurrentTime using player.getCurrentTime()
}
if this code doesnt work, you must stop the video first, then set the video quality, then seek to your time
I have a website where user logon and has to watch a video. After that user has to answer 5 questions after the video has finished loading. I have been able to allow the user to play the video. The next part is adding a link to the page that appears as a button. It works fine when running on Google Chrome and Safari, but not on iOS simulator
Here are the possible problems.
Is there any way i can run, or view those html, css, & js files on my iPhone 6?
Is there something wrong with my code or is there anything i can add to allow the video to run on mobile device?
My video is not showing up either.
Following is my code.
// youtube video
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
videoId: '0Bmhjf0rKe8',
events: {
'onStateChange': onPlayerStateChange
}
});
}
// add link
function onPlayerStateChange(event) {
if (event.data === 0) {
addLink();
}
}
// when video ends
function addLink() {
var link = document.createElement("A");
var text = document.createTextNode("Continue");
link.appendChild(text);
document.getElementById("housing").appendChild(link);
link.id = "link"
}
Here is a fiddle.
I'm creating this webpage on wordpress which have videos from youtube in some of it's posts, for tagging purposes I need to capture everytime a person clicks play on each of the videos. I've looked through the web, but all I could find is that, since this videos are on iframes from outside the main domain, it's impossible to catch something from the inside of it, like clicks.
Is there any way that I can catch this clicks on the play button without changing anything on the site? Just from JS.
Regards and thanks in advance.
You could capture some events within the iframe using youtube's js API
This is what you have to do:
1). Load the Player API in your page
<script src="http://www.youtube.com/player_api"></script>
2). Enable jsapi in your iframe as a trailing parameter (enablejsapi) like
<iframe id="myIframe" src="http://www.youtube.com/embed/opj24KnzrWo?enablejsapi=1&autoplay=0" width="420" height="280" frameborder="0"></iframe>
... also notice we added an ID to the iframe.
3). Create 3 functions :
a). onPlayerReady :
Here is where you can detect when the video has loaded and is ready to play. Here you can actually start the video, etc.
function onPlayerReady(event) {
// video is ready, do something
event.target.playVideo();
}
b). onPlayerStateChange :
Here is where you can detect what events are triggered:
function onPlayerStateChange(event) {
console.log(event.data); // event triggered
// e.g. end of video
if (event.data === 0) {
// end of video: do something here
}
}
When you click play or pause, an event is triggered. Then you can decide what action you want do, including pushing a tracking event, etc.
This is a list of the returned values of each event :
-1 – unstarted
0 – ended
1 – playing
2 – paused
3 – buffering
5 – video cued
Refer to the documentation to learn more about those events
c). onYouTubePlayerAPIReady :
This is where you actually initialize the API and bind the events to the other functions :
function onYouTubePlayerAPIReady() {
var id = document.getElementById("myIframe").getAttribute("id");
var player = new YT.Player(id, {
events: {
onReady: onPlayerReady,
onStateChange: onPlayerStateChange
}
});
} // youtube API ready
See JSFIDDLE
I was having trouble isolating a bug in my JavaScript code for controlling Youtube videos via the iframe/HTML5 API.
I went back to the demo code on the main documentation page:
https://developers.google.com/youtube/iframe_api_reference
...and to my surprise, I see the same inconsistent behavior even when I use the demo code from there and don't change anything.
The behavior is that some of the time, when I load this page, the player autoplays (which is the intent of the code), and other times it doesn't. It always does succeed in loading. Also, the player never seems to stop after 6 seconds, in contrary to what the comments say.
Breakpoints verify that part of the issue at least is that onPlayerReady() is not always being called. When I set a breakpoint in onPlayerReady(), it usually is not reached, and is only reached the times that the player goes on to succeed in autoplaying.
Of course, this behavior may be dependent on the speed and reliability of my internet connection, which is wired and otherwise seems decently fast. I just tested it -- 24 Mbps, and it seems pretty consistent.
If I make superficial changes to the html, that seems to sometimes prompt the page on loading to autoplay, but not always. Sometimes I will reload every few seconds 5 times in a row with no autoplay or onPlayerReady breakpoint being hit, then do it a 6th time and that time it will autoplay fine.
I'm using Chrome v30.0.1599.101 on Mac OS 10.8.4.
I know that code is in beta and in flux, and isn't supposed to be production level yet, but I was hoping there was something i can try.
Here is the code I'm using, FYI, in case the code posted on the api reference page above changes. Again, I'm not altering a single character.
<!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 was opening the page locally, which makes for different behavior in all sorts of little ways from how it works when delivered from a server. The browser client itself handles things like cacheing differently when content is local. When I put the same page on a server, it started to work every time.
In addition, FYI, for my bigger issue that led me down this rabbithole, I found that I needed to follow this advice: https://stackoverflow.com/a/14952334/2308190 ...in order to get my YouTube callback functions to be called with jQuery loaded.
I had a situation where my first YouTube iframe would load correctly, and subsequent ones would not.
The issue was caused by creating a new YT.Player before its <div> had been added to the DOM. This issue didn't occur the first time I created a YT.Player, because the YouTube API had to be loaded first. This caused a microsecond delay which allowed the rest of my code to execute, so the <div> was added to the DOM before the YouTube API finished loading.