tvgemert
tvgemert

Reputation: 1486

Vimeo API (froogaloop). Trying to preload a video using play / pause

I have an issue with the vimeo player API. I embed a Vimeo video in my page using an iframe, I position an image over this iframe. The image has a play button, click on this image fades out the image and then I use the following command to play the video:

froogaloop.api('play');

This works great, except for the fact that playback is a bit cranky because the video loads while playing. I would like the video to start loading on page load so that the video is (fully or partially) loaded when user clicks the image with the play button. I tried doing this by calling:

froogaloop.api('play');
froogaloop.api('pause');

sequentially on page load (see beneath). Calling play first and then pause should force the video to load while paused. The point is that the pause command directly following the play command is somehow ignored. So the video is just playing on page load.

Does someone have experience with this, is there a way to get the video to preload?

    //INIT Vimeo API
var vimeoPlayers = document.querySelectorAll('iframe'),
    player;

for (var i = 0, length = vimeoPlayers.length; i < length; i++) {
    player = vimeoPlayers[i];
    $f(player).addEvent('ready', ready);
}

function addEvent(element, eventName, callback) {
    if (element.addEventListener) {
        element.addEventListener(eventName, callback, false);
    } else {
        element.attachEvent(eventName, callback, false);
    }
}

function ready(player_id) {
    // Keep a reference to Froogaloop for this player
    var container = document.getElementById(player_id).parentNode.parentNode, 
        froogaloop = $f(player_id);

    //Call Play and pause to activate loading of whole video
    //Vimeo won't let you preload the video by default (because of bandwidth issues etc.)
    froogaloop.api('play');
    froogaloop.api('pause');

    $('#media-home a').click(function(){

        $(this).fadeOut('12000');
        froogaloop.api('play');

        return false;   

    });                

}

Upvotes: 4

Views: 7959

Answers (3)

Brendan Nee
Brendan Nee

Reputation: 5353

You preload Vimeo videos without using froogaloop by calling the Vimeo API manually. The following code waits until the player is ready then triggers play and then immediately pauses the video:

var player = $('iframe');
var playerOrigin = '*';
var preloaded = false;

// Listen for messages from the player
if (window.addEventListener){
  window.addEventListener('message', onMessageReceived, false);
} else {
  window.attachEvent('onmessage', onMessageReceived, false);
}

function onMessageReceived(e) {
  // Handle messages from the vimeo player only
  if (!(/^https?:\/\/player.vimeo.com/).test(event.origin)) {
    return false;
  }

  var data = JSON.parse(e.data);

  switch (data.event) {
    case 'ready':
      onReady();
      break;
    case 'playProgress':
      // if video is not yet preloaded, pause it right away
      if(!preloaded) {
        var preloaded = true;
        post('pause');
      }
      break;
  }
}

// Helper function for sending a message to the player
function post(action, value) {
  var data = {
    method: action
  };

  if (value) {
    data.value = value;
  }

  var message = JSON.stringify(data);
  player[0].contentWindow.postMessage(data, playerOrigin);
}

function onReady() {
  post('addEventListener', 'playProgress');

  //preload video by triggering `play` as soon as the player is ready
  post('play');
}

The above is based on sample code provided by Vimeo. Note that this will only work in new-ish browsers: Internet Explorer 8+, Firefox 3+, Safari 4+, Chrome, and Opera 9+.

Upvotes: 2

J nui
J nui

Reputation: 190

This did not work for me.
It seemed that play and pause cancelled each other out, and nothing was done. I could play, but not pause.

I ended up using a click trigger to simulate the pause.

$(document).ready(function(){

    playerID = $('iframe.talkingHead').attr('id');
    setTimeout(function(){
                    $('.hiddenplay').trigger('click');

                    //Froogaloop(playerID).api('play');
                    setTimeout(function(){
                                    Froogaloop(playerID).api('pause');
                    },800);
    },1000);


    $('#imageID').on('click', function(){
                    $(this).css('display', 'none');
                    Froogaloop($(this).data('vidref')).api('play');
    });
    $('.hiddenplay').on('click', function(){

                    Froogaloop(playerID).api('play');
    });
 }); // end document ready

I had to use a pause with setTimout because it seemed to fire too early and caused errors on froogaloop, perhaps because the video was not ready.

The html included an element with class="hiddenplay" & also in this case i had an image covering the video, that when clicked played the video and in this case since the video is all ready paused there is no black flash before the video starts.

Upvotes: 0

Miloš Rašić
Miloš Rašić

Reputation: 2279

If you call play and pause sequentially, they will overlap on most platforms and cause pause to be ignored. To get it to work reliably, you should bind an event handler to play event and call pause in it, like this:

    Froogaloop(playerID).addEvent('play', function(playerID) {
        Froogaloop(playerID).api('pause');
        Froogaloop(playerID).removeEvent('play');
    });
    Froogaloop(playerID).api('play');

Note that the event handler should unbind itself so that it is not executed when the user actually clicks play.

Upvotes: 2

Related Questions