I have an embedded Vimeo video on the homepage my site, which is set to autoplay when the site loads. I am also using the api and froogaloop.js for some custom controls.
What I need to do is save the time the video has got to when a visitor navigates to another page, then resume playing from this point if and when they return to the homepage.
I know I can use playProgress to get the time elapsed, but am not sure how to store this and how to use it when the visitor returns to the homepage.
EDIT
I now have the following code, and am using js-cookie to store the progress cookie. How would I get the value of playProgress and set it as a cookie using beforeunload on window? I am not great at javascript so help would be great!
JAVASCRIPT (also including this library https://github.com/js-cookie/js-cookie)
$(function() {
var iframe = $('#player1')[0];
var player1 = $f(iframe);
var status1 = $('.status1');
// When the player is ready, add listener for playProgress
player1.addEvent('ready', function() {
status1.text('ready');
player1.addEvent('playProgress', onPlayProgress);
});
function onPlayProgress(data, id) {
status1.text(data.seconds + ' seconds played');
};
// SETTING A COOKIE
Cookies.set('timeElapsed','something');
});
HTML
<script src="https://f.vimeocdn.com/js/froogaloop2.min.js"></script>
<div class="videoholder">
<h3>Player 1</h3>
<iframe id="player1" src="https://player.vimeo.com/video/142216434?api=1&player_id=player1" width="500" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<div>
<p><span class="status1">…</span></p>
</div>
</div>
You can simply read the value of the cookie saved using
function onPlayProgress(data, id) {
Cookies.set('timeElapsed', data.seconds);
status1.text(Cookies.get('timeElapsed') + ' seconds played');
}
and then set the value of the video when it is being loaded by appending &t=0m0s at the end of the url.
$('#player1').attr('src','https://player.vimeo.com/video/142216434?api=1&player_id=player1&t='+timeElapsed)
I got this working with the following javascript:
$(function() {
var iframe = $('#player1')[0];
var player1 = $f(iframe);
// When the player is ready, add listener for playProgress
player1.addEvent('ready', function() {
player1.api('seekTo',(Cookies.get('timeElapsed')));
player1.api('pause');
player1.addEvent('playProgress', onPlayProgress);
});
function onPlayProgress(data, id) {
Cookies.set('timeElapsed', data.seconds);
};
});
My only issue now is that when you return to the (paused) video, you need to click twice to get it to resume as the Pause button is visible. Does anyone know why this would be? This is the last piece of my Vimeo puzzle!
Related
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>
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.
I have a webpage, and I made a video for it. With HTML5 formats (webm,ogg,mp4) works only the Chrome correctly. When the video is finishing, I can hide the video with JavaScript. I thought I can make with youtube player, (autoplay, hide controls etc) but i can't hide it, when it is finished. I found the "onStateChange function but I can't use it. Any ideas?
<iframe width="840" height="630" src="URLrel=0&showinfo=0;&autoplay=1;controls=0" frameborder="0" allowfullscreen></iframe>
You need to use the YouTube Iframe Player API to check (1) that the video has ended (YT.PlayerState.ENDED) when onPlayerStateChange is invoked, and (2) remove/hide the DOM element that contains the video, i.e. the iframe.
function onPlayerStateChange(event) {
// check if video ended and remove player
if (event.data == YT.PlayerState.ENDED) {
console.log($('#player').remove());
done = true;
}
}
You have a fully working solution in here: http://jsfiddle.net/jibietr/ua57A/1/
A quick and dirty solution would be to use innerHTML to overwrite the iframe when the user closes the video with an onclick event. If the iframe is wrapped inside a with id = "iframeDiv", you can call the following function onclick of the close video button:
function hideIframe() {
document.getElementById("iframeDiv").innerHTML = '';
}
The iframe would reappear when the user opens the video:
function showIframe() {
document.getElementById("iframeDiv").innerHTML = '<iframe width="840" height="630" src="URLrel=0&showinfo=0;&autoplay=1;controls=0" frameborder="0" allowfullscreen></iframe>';
}
I have a music blog that contains various embedded soundcloud and youtube players.
What I want to do is prevent any audio from playing simultaneously. In other words while I am playing a youtube video, if I click to play the soundcloud embed I want the youtube player to pause and vice versa.
I have developed code that pauses the streaming youtube player if I click to play another youtube player (soundcloud already does this inherently). I just need to make it cross compatible. Really would appreciate some help, thanks.
var playerCurrentlyPlaying = null;
var players = {}
YT_ready(function() {
$(".youtube_embed").each(function() {
var identifier = this.id;
var frameID = getFrameID(identifier);
if (frameID) {
players[frameID] = new YT.Player(frameID, {
events: {
"onStateChange": function(event){
if (event.data == YT.PlayerState.PLAYING)
{
if(playerCurrentlyPlaying != null &&
playerCurrentlyPlaying != frameID)
callPlayer( playerCurrentlyPlaying , 'pauseVideo' );
playerCurrentlyPlaying = frameID;
}
}
}
});
}
});
});
I have used functions from these sources:
Listening for Youtube Event in JavaScript or jQuery
YouTube iframe API: how do I control a iframe player that's already in the HTML?
YouTube API Target (multiple) existing iframe(s)
Rendered HTML using UniqueID():
<span class="soundcloud_embed" id="soundcloud_post_312">
<iframe id="ui-id-1" width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F103518792&show_artwork=true&secret_token=s-LnOTK"></iframe>
</span>
<span class="youtube_embed" id="youtube_post_309">
<iframe id="ui-id-2" width="528" height="190" src="//www.youtube.com/embed/Y3CYKXBEtf0" frameborder="0" allowfullscreen></iframe>
</span>
First of all, things will be greatly simplified if you are able to get an ID onto the iframes themselves, like this:
<span class="soundcloud_embed">
<iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F4997623" id="sound1"></iframe>
</span>
<span class="soundcloud_embed">
<iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F105153133" id="sound2"></iframe>
</span>
<span class="youtube_embed">
<iframe width="400" height="225" src="//www.youtube.com/embed/tv8WgLEIPBg" id="vid1" frameborder="0" allowfullscreen></iframe>
</span>
<span class="youtube_embed">
<iframe width="400" height="225" src="//www.youtube.com/embed/FmICU1gMAAw" id="vid2" frameborder="0" allowfullscreen></iframe>
</span>
If you'd prefer not to hack the auto_html gem that you mention in order to get IDs, you can either use jquery's .uniqueId() function to generate them on all iframes or use the getFrameID() helper method from the post you referred to (and seem to already be using).
To make it as easy as possible to get the two APIs (Youtube and Soundcloud) to be able to respond to each other's events, you can use a couple of control objects that keep track of which players are on your page and which of them is currently playing (this strategy is similar to that employed by the links you referred to, but are expanded to be able to keep track of which player belongs to which API). With it, define a generic pause function that serves as a simplistic wrapper for both APIs:
var playerCurrentlyPlaying = {"api":null,"frameID":null};
var players = {"yt":{},"sc":{}};
pauseCurrentPlayer=function() {
var api=playerCurrentlyPlaying["api"],
frameid=playerCurrentlyPlaying["frameID"];
switch(api) {
case "yt":
players[api][frameid].pauseVideo();
break;
case "sc":
players[api][frameid]["widget"].pause();
break;
}
};
Next, you'll want to define two separate functions; the first will be called whenever a YouTube play event is captured, and the second whenever a Soundcloud play event is captured. Currently the Soundcloud HTML5 Widget has a few bugs that force the necessity to include some pretty ugly hacks--namely, the Play event sometimes isn't fired when you play a Soundcloud sound for the first time. Luckily, the Play_Progress event is, so we can leverage that, but must also include a workaround so it doesn't create a race condition when pausing a sound and starting a video:
onYTPlay =function(frameid) {
if (playerCurrentlyPlaying["frameID"]!=frameid && playerCurrentlyPlaying["frameID"]!=null) {
pauseCurrentPlayer();
}
playerCurrentlyPlaying["api"]="yt";
playerCurrentlyPlaying["frameID"]=frameid;
};
onSCPlay=function(frameid,event) {
if (event==SC.Widget.Events.PLAY||players["sc"][frameid]["firstplay"]==true) {
if (playerCurrentlyPlaying["api"]=="yt") { // because any soundcloud player will be automatically paused by another soundcloud event, we only have to worry if the currently active player is Youtube
pauseCurrentPlayer();
}
playerCurrentlyPlaying["api"]="sc";
playerCurrentlyPlaying["frameID"]=frameid;
players["sc"][frameid]["firstplay"]=false;
}
};
Finally, you can then add your hooks to the Youtube embeds and the Soundcloud embeds, remembering the hack we have to put in for the Soundcloud Play event. Don't forget to embed the Soundcloud Widget API (<script src="w.soundcloud.com/player/api.js"; type="text/javascript"></script>), and then use this code to do your bindings:
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() {
$(".youtube_embed iframe").each(function() {
players["yt"][$(this).attr('id')] = new YT.Player($(this).attr('id'), {
events: { 'onStateChange': onYTPlayerStateChange }
});
});
}
onYTPlayerStateChange = function(event) {
if (event.data==YT.PlayerState.PLAYING) {
onYTPlay(event.target.a.id);
}
};
(function(){
$(".soundcloud_embed iframe").each(function() {
var frameid=$(this).attr('id');
players["sc"][frameid]={};
players["sc"][frameid]={"widget":SC.Widget(document.getElementById(frameid)),"firstplay":true};
players["sc"][frameid]["widget"].bind(SC.Widget.Events.READY, function() {
players["sc"][frameid]["widget"].bind(SC.Widget.Events.PLAY, function() {
onSCPlay(frameid,SC.Widget.Events.PLAY);
});
players["sc"][frameid]["widget"].bind(SC.Widget.Events.PLAY_PROGRESS, function() {
onSCPlay(frameid,SC.Widget.Events.PLAY_PROGRESS);
});
});
});
}());
This approach is set up to handle multiple players of both APIs, and should be decently extensible if you want to support other embeddable media widgets (provided they expose an event when they start to play and they have the ability to programmatically pause players).
it's possible. check widget api playground. you can watch all state events from soundcloud iframe widget. this can be done on flash embed too.
https://w.soundcloud.com/player/api_playground.html
watch for SC.Widget.Events.PLAY {"loadedProgress":0,"currentPosition":0,"relativePosition":0} event on start playing
I am new to the YouTube Iframe API and am trying to pause several embedded Iframe videos that are in a slideshow (jQuery flexslider plugin) when a user moves to a different slide. If the player isn't paused, the video continues to play and, since there will be multiple videos in the slide show, I need each one to pause when a new slide is revealed. The Iframes are not inserted via the API, but are already present in the html due to the CMS I am using.
I have read through the API reference and several answers I found on here, but am having trouble figuring out how to pause any/every Iframe video when a user transitions to a new slide.
In my latest attempt, as seen in the code below, I have tried to pause the Iframes whenever a link is clicked, since the only links on the page will be for navigating to the next and previous slides. I also have tried to pause all videos on a slide transition event provided via the flexslider API, but with no success.
var players = {}; //players storage object
function onYouTubeIframeAPIReady(){
$('iframe[id]').each(function(){
var identifier = this.id;
var frameID = getFrameID(identifier);
if (frameID) { // if iframe exists
players[frameID] = new YT.Player(frameID, {
events: {
"onStateChange" : createYTEvent(frameID, identifier)
}
});
}
});
}
//returns a function to enable multiple events
function createYTEvent(frameID, identifier){
return function (event){
var player = players[frameID]; //set player reference
var done = false;
$('a').click(function(){
player.pauseVideo();
return false;
});
}
}
Any help would be greatly appreciated
Sorry for my English, I'm French, but I got the same problem recently, and maybe I thought that I could help you or another person in the future.
The difference with you is that I only used 1 player loading a list of 4 videos, and not 4 players.
There is my HTML:
<div id='videos'>
<div id="player">
<!-- the iframe drectly write in the html, with a list of videos (4 in the example) -->
<iframe id="ytplayer" type="text/html" width="640" height="360" src="https://www.youtube.com/embed/youtubeVideoId1?playlist=youtubeVideoId2,youtubeVideoId3,youtubeVideoId4&version=3" frameborder="0" allowfullscreen></iframe>
</div>
<!-- below, the buttons for switching the 4 videos -->
<span id='pagination'>
<a onclick='video_slide(0);' id='puce1'></a>
<a onclick='video_slide(1);' id='puce2'></a>
<a onclick='video_slide(2);' id='puce3'></a>
<a onclick='video_slide(3);' id='puce4'></a>
</span>
</div>
</div>
and my Javascript:
<script type="text/javascript">
// call the youtube API
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// init the player
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ytplayer', {
events: {
// the function "onPlayerStateChange is call when the player load,
play, pause or stop a video
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerStateChange(event) {
// if a new video is buffering (the event.data is -1 when buffering,
1 when playing, 2 when paused ...)
if (event.data == -1) {
// it mean that the player pass at the next video,
so we call the bellow function to turn on the corresponding button
getTheRightPuce();
}
}
// I add a function to recognize the current video playing,
and turn on the right button automatically when at the end of a video,
the player pass on the next one
function getTheRightPuce(){
var vidIndex = player.getPlaylistIndex();
$("#pagination a").css('backgroundColor','#000000');
if (vidIndex==0){$("#puce1").css('backgroundColor','red');}
else if (vidIndex==1){$("#puce2").css('backgroundColor','red');}
else if (vidIndex==2){$("#puce3").css('backgroundColor','red');}
else if (vidIndex==3){$("#puce4").css('backgroundColor','red');}
}
// the function called by the buttons, change the current video
on the player and turn on the corresponding button,
the parameter is the index of the video in the play-list
(0 for the first, 1 for second...)
function video_slide(sld){
player.playVideoAt(sld);
$("#videos").css('display','none');
$("#pagination a").css('backgroundColor','#000000');
$("#videos").fadeIn(500);
if (sld==0){$("#puce1").css('backgroundColor','red');}
else if (sld==1){$("#puce2").css('backgroundColor','red');}
else if (sld==2){$("#puce3").css('backgroundColor','red');}
else if (sld==3){$("#puce4").css('backgroundColor','red');}
}
</script>
I tried to make it as clearer as possible.
I hope this will help you or someone else :)