Getting Current YouTube Video Time - javascript

I am writing a Browser Plugin and need to find a way to get the current time a YouTube Video playing on YouTube using JavaScript. I have been playing around in the Chrome JavaScript Console and haven't had any luck.
It appears that the chrome API only works with embedded video players not a video that is playing on on youtube.com. One option I looked into is in the share section of a video their is an input box for the "start at:" time that contains the current time of the video. I have tried using .value and .text on this input box and they both return undefined? Does anyone have any ideas?

ytplayer = document.getElementById("movie_player");
ytplayer.getCurrentTime();
See the api
Update: if it didn't work, also try player.playerInfo.currentTime (codepen live example)

Depends on what you want
player.getCurrentTime():Number
Returns the elapsed time in seconds since the video started playing.
player.getDuration():Number
Returns the duration in seconds of the currently playing video. Note
that getDuration() will return 0 until the video's metadata is loaded,
which normally happens just after the video starts playing.
http://code.google.com/apis/youtube/js_api_reference.html

Finally I found how to make it work on iOS (and Android too).
Actually, the whole youtube js api was broken for me if run on mobile browser.
Problem solved by creating player using new YT.Player as described in YouTube IFrame API.
Please note: only creating <iframe> from <div> placeholder works for mobile browsers at the time. If you try to use existing <iframe> in new YT.Player call, as mentioned in IFrame API, this will not work.
After player created, it's possible to use player.getCurrentTime() or player.getDuration() with player instance created.
Note: I had no luck calling this methods on player obtained with
player = document.getElementById(...) (from #JosephMarikle answer).
Only created player instance worked in mobile browsers.
Useful links:
YouTube IFrame API
YouTube JavaScript API
YouTube Player Demo

You can use Html5 Video API on youtube.com
var htmlVideoPlayer = document.getElementsByTagName('video')[0];
htmlVideoPlayer.currentTime
Note: It's not gonna work on Youtube Iframe API because Iframes are isolated. You cannot access the context of a Youtube IFrame .

In 2020, this works:
player.playerInfo.currentTime
full code:
see it live on codepen

Just FYI, There is a new iframe API for the YouTube player:
https://developers.google.com/youtube/iframe_api_reference

document.querySelector('video').currentTime

Stop at specific time youtube video and show notification box in GWD
<script>
var yid = document.getElementById("gwd-youtube_1");
var idBox = document.getElementById("box1");
pausing_function = function(event) {
var aa = setInterval(function() {
if (yid.getCurrentTime() > 8.0 && yid.getCurrentTime() < 8.1) {
yid.pause(yid);
idBox.style.opacity = 1;
console.log(yid.getCurrentTime() + "playing")
clearInterval(aa);
yid.removeEventListener("playing", pausing_function);
}
}, 100)
}
yid.addEventListener("playing", pausing_function);
var pausing_function_1 = function() {
if (yid.getCurrentTime() > 8.1) {
console.log(yid.getCurrentTime() + "pause")
// remove the event listener after you paused the playback
yid.removeEventListener("playing", pausing_function);
}
};
</script>
play video and hide notification
<script type="text/javascript" gwd-events="handlers">
window.gwd = window.gwd || {};
gwd.pauseVideo = function(event) {
var idBox = document.getElementById("box1");
idBox.style.opacity = 0;
};
</script>
<script type="text/javascript" gwd-events="registration">
// Support code for event handling in Google Web Designer
// This script block is auto-generated. Please do not edit!
gwd.actions.events.registerEventHandlers = function(event) {
gwd.actions.events.addHandler('gwd-youtube_1', 'playing', gwd.pauseVideo, false);
};
gwd.actions.events.deregisterEventHandlers = function(event) {
gwd.actions.events.removeHandler('gwd-youtube_1', 'playing', gwd.pauseVideo, false);
};
document.addEventListener("DOMContentLoaded", gwd.actions.events.registerEventHandlers);
document.addEventListener("unload", gwd.actions.events.deregisterEventHandlers);
</script>

Related

Automatically Pause Embedded iFrame Vimeo Video at Specific Time?

I'm using a Vimeo video-embed (iFrame embed code from their website) on my website, and I need the video to automatically stop at a specific timestamp (I'll use 6 seconds here) whenever users of my site play the video. The content after the timestamp is unnecessary.
But unlike YouTube, Vimeo doesn't seem to have an easy way to set end times for any video you embed from them. Unfortunately, I do not own the video so I can't edit the footage directly, so I believe a JavaScript solution is the best option.
Here's the aforementioned iFrame embed HTML from Vimeo that I use on my site:
<iframe id="vidz" src="https://player.vimeo.com/video/401649410?h=11d74aa27c&portrait=0" width="450" height="253" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen=""></iframe>
Upon trying to select elements within the iFrame (like the video itself), my JS selectors don't seem to be working at all, perhaps because the video is from a separate source not hosted on my site?
Here's code I've been working with, but it doesn't appear to be interacting with the iFrame, as I believe I would need to add this eventListener to a video, directly. But I can't select the embeded video via JS either, it seems. So I'm not quite sure how to handle this:
var vid = document.querySelector("#vidz");
vid.addEventListener("timeupdate", function(){
if(t >= 6000)
{
vid.pause();
}
});
I can also provide the HTML to any elements within the iFrame, but again, I'm not sure how I'd be able to interact with those elements.
Any ideas? Any and all help would be deeply appreciated. Cheers.
use Vimeo js file and below is a script you want video will pause after 6 minutes (specific time) (360 means 6 minutes)
<script src="https://player.vimeo.com/api/player.js"></script>
var iframe = document.querySelector('iframe');
var player = new Vimeo.Player(iframe);
function foo() {
player.getCurrentTime().then(function(time) {
console.log('time:', time);
if(time >= 360){
player.pause()
}
});
setTimeout(foo, 1000);
}
player.on('play', function() {
foo();
});
</script>

Mp4 from Dropbox used with HTML5 video player, is not repeating

I'm working on a Squarespace website, and they don't allow video upload, so I'm using Dropbox to host a video.
The video starts playing, but he is not repeating.
This is the code:
<video id="htmlVideo" loop="loop">
<source type="video/mp4" src="https://www.dropbox.com/s/videoID/videoplayback.mp4?dl=1">
</video>
What could be the problem?
This is how I create the video
/*
function repeatForDropbox() {
console.log("repeatForDropbox caled" + htmlVideo );
}
*/
function createVideo() {
var video = document.createElement("video");
video.id = "htmlVideo";
video.loop = "loop";
var vidSource = document.createElement("source");
vidSource.type = "video/mp4";
vidSource.src = "https://www.dropbox.com/s/videoID/videoplayback.mp4?dl=1";
video.appendChild( vidSource );
var vidLocation = document.querySelector('#location').parentNode;
vidLocation.appendChild( video );
htmlVideo = document.querySelector(" #htmlVideo ");
// on load, play the video/mp4
window.onload = function () {
setTimeout(function() {
htmlVideo.play();
// htmlVideo.addEventListener("ended", repeatForDropbox);
// I tried here to make the video repeat, using the "ended" event listener
// so when the video ended, the video
// should get another <source> element(same src)
// and delete the old one
// but the event didn't fire
// I also tried htmlVideo.onended = function() {} , but same result
}, 500);
}
}
Just a guess, but I suspect this relates to redirects. A Dropbox share link with ?dl=1 on it will redirect you to a one-time use URL to download the content. Perhaps when the video player tries to loop, it tries to access the target of the redirect again.
This might show up in the network traffic from the browser, so it's worth taking a look. (E.g. the network tab of Chrome inspector, if you're using Chrome.)
I would see if squarespace will let you save the binary of the video into a text file and then import it with AJAX and save it to indexedDB before converting it to video.
Here's some links:
Display a video from a Blob Javascript
https://simpl.info/video/offline/
Just in case anyone still needs the solution, I found a workaround using jQuery:
$('video').on('ended', function () {
this.load();
this.play();
});
However, there is a slight delay between repeats!

Debug Help for Simple Javascript/jQuery Vimeo Froogaloop

See this link: http://jitimanagementcoach.com/TC_test/tabbed4try.html
I've already got the videos to play and/or pause on one tab or another when a tab is clicked... but now I need the video on the Prelearn tab to "click" the Solution tab and play the video once the Prelearn video is finished. Here's the code:
<script>
var iframe1 = document.getElementById("prelearnvid");
var iframe2 = document.getElementById("solutionvid");
var player1 = $f(iframe1);
var player2 = $f(iframe2);
var prelearnBtn = document.getElementById("prelearnbtn");
prelearnBtn.addEventListener("click", function() {player1.api("play");player2.api("pause");});
var solutionBtn = document.getElementById("solutionbtn");
solutionBtn.addEventListener("click", function() {player2.api("play");player1.api("pause");});
player1.addEvent('ready', function() {player1.addEvent('finish', onFinish);});
function onFinish(id) {window.location.href = '#solution-tab';};
</script>
It all works fine until the very last two lines... where am I going wrong?
The ready event is not firing for your player. In order for the player's events to fire, you need to add a player_id parameter to your URL that includes the id of your <iframe>.
Change the src attribute of your <iframe> to this:
<iframe id="prelearnvid" src="http://player.vimeo.com/video/92349330?&player_id=prelearnvid"
From the Froogaloop documentation:
If you’re embedding and controlling multiple players on a page or
using our JS API library (Froogaloop), you should give each player a
player_id that matches the id of the iframe element.
This stackoverflow answer and this forum post helped uncover this solution.

Correct way to play <audio> + <video> from Javascript

I'm getting different results i Firefox and Chrome when using <audio> and <video> with preload="none" and then trying to play from Javascript.
Let's say i was using preload="auto" or preload="metadata" :
audio.src = "filename";
audio.play();
That seems to work fine in both Firefox and Chrome but i want to use preload="none" and then Chrome dossent play.
So i'm trying this code with preload="none" :
audio.src = url;
audio.load();
audio.addEventListener('canplay', function(e) {
audio.play(); // For some reason this dossent work in Firefox
}, false);
audio.play(); // Added this so Firefox would play
I don't know if that's the correct way to do it.
I'm using :
Firefox 20.0.1
Chrome 25.0.1364.172 m
I made a demo : http://netkoder.dk/test/test0217.html
Edit :
In the 2nd audio player (on the demo page) it seems that when using preload="none" you have to use load().
But is it correct to just use play() right after load() or is the correct way to use an event to wait for the file to load before playing it ?
In the 3rd audio player it seems Firefox 20.0.1 dossent support the canplay event correctly when used with addEventListener() because it dossent trigger after load(), it triggers after play() and also triggers when scrubbing though the sound which dossent seem to be the way the canplay should work.
Using .oncanplay does work.
So the following code seems to work :
function afspil2(url) {
afspiller2.src = url;
afspiller2.load(); // use load() when <audio> has preload="none"
afspiller2.play();
}
function afspil3(url) {
afspiller3.src = url;
afspiller3.load(); // use load() when <audio> has preload="none"
//afspiller3.addEventListener('canplay', function() { // For some reason this dossent work correctly in Firefox 20.0.1, its triggers after load() and when scrubbing
// afspiller3.play();
//}, false);
afspiller3.oncanplay = afspiller3.play(); // Works in Firefox 20.0.1
}
I updated the demo to include the changes : http://netkoder.dk/test/test0217.html
My way of adding addEventListener inside the afspil3() function dossent seem good because the first time the function is called the code inside addEventListener is called 1 time. The second time the function is called the code inside addEventListener is called 2 time and then 3 times and so on.
It's because your audio tags are missing the required src attribute, or <source> tags. When I added them in your demo, all 3 players immediately began working in both Chrome and FF.
Also, I recently discovered that src cannot be an empty string and subsequently changed with JS. If there's a reason you can't set the src in the HTML, your best alternative, IMO, is to create the audio elements with Javascript:
var audio = new Audio();
audio.src = url;
audio.controls = true;
audio.preload = false;
// and so on
Edit: Ok. It seems that in Chrome, when the HTML is preload="none" it is necessary to call load() before playing when the src is changed. Your second audio doesn't preload, so your function needs to be this:
function afspil2(url) {
afspiller2.src = url;
afspiller2.load(); // add load call
afspiller2.play();
}
Then, it seems that in Firefox, it is necessary to set preload="auto"; when attaching an event to the canplay event, like in the 3rd function.
function afspil3(url) {
afspiller3.src = url;
afspiller3.preload = "auto";
afspiller3.load();
afspiller3.addEventListener('canplay', function(e) {
this.play(); // For some reason this dossent work in Firefox
}, false);
}
That just seems very strange, but I tested it multiple times, and each time it would play if preload="auto" is called, but would not play if it isn't called. Note that it wasn't necessary for the 2nd player, which was also preload="none" in the HTML tag.
Finally, Chrome has some odd behaviors if there are multiple <audio> elements on the page. For all three players, reloading the page and clicking "the big electron" link would play correctly.
Reloading and then clicking "Yoda" on the 2nd or 3rd player won't do anything, but it WILL play for the first player. But, if the top player is played first by any means - play button or either link - then the other two "Yoda" links will suddenly work.
Also, if you click a 2nd or 3rd "Yoda" link first after reload, and then click the top player, the previously clicked "Yoda" (that didn't previously play) will begin to play on its own after the top player stops.
Suffice it to say they have some bugs to work out.
The correct way in my opinion would mean using an existing solution, like http://mediaelementjs.com/
If your really interested in the details on the best way to play audio and video with js then look at the source:
https://github.com/johndyer/mediaelement/tree/master/src/js
https://github.com/johndyer/mediaelement/blob/master/src/js/me-mediaelements.js

trying to add a multi source video player with more then one video?

Im trying to make a video player work in all browsers. There is
more then one video and every time you click on demo reel it plays the
video and if you click the video 1 the other video plays. How can i
make them both work in all browsers? Here is my html and javascript
html
<video id="myVideo" controls autoplay></video>
<div>
Demo Reel</div>
video 1</div>
</div>
javascript
function changeVid1() {
var changeStuff = document.getElementById("myVideo");
changeStuff.src = "video/demoreel.mp4"
}
function changeVid2() {
var changeStuff = document.getElementById("myVideo");
changeStuff.src = "video/video1.mp4";
}
After you switch the source of the video, you need to run .load() on it to force it to load the new file. Also, you need to provide multiple formats, because there is no video codec supported by all browsers.
First, set up your sources like this:
var sources = [
{
'mp4': 'http://video-js.zencoder.com/oceans-clip.mp4',
'webm':'http://video-js.zencoder.com/oceans-clip.webm',
'ogg':'http://video-js.zencoder.com/oceans-clip.ogv'
}
// as many as you need...
];
Then, your switch function should look like this:
function switchVideo(index) {
var s = sources[index], source, i;
video.innerHTML = '';
for (i in s) {
source = document.createElement('source');
source.src = s[i];
source.setAttribute('type', 'video/' + i);
video.appendChild(source);
}
video.load();
video.play(); //optional
}
See a working demo here.
This gives the browser a list of different formats to try. It will go through each URL until it finds one it likes. Setting the "type" attribute on each source element tells the browser in advance what type of video it is so it can skip the ones it doesn't support. Otherwise, it has to hit the server to retrieve the header and figure out what kind of file it is.
This should work in Firefox going back to 3.5 as long as you provide an ogg/theora file. And it will work in iPads, because you only have one video element on the page at a time. However, auto-play won't work until after the user clicks play manually at least once.
For extra credit, you can append a flash fallback to the video element, after the source tags, for older browsers that don't support html5 video. (i.e., IE < 9 - though you'll need to use jQuery or another shim to replace addEventListener.)

Categories

Resources