Search code examples
javascriptjqueryvimeovimeo-apivimeo-player

Controlling when Vimeo thumbnail turns off and video begins


I'm looking into the vimeo embed api. I want the video to autoplay on load which I have working but currently what happens is like this:

  • player loads then autoplays [event "ready"]
  • thumbnail removed and shows black for about a second
  • video begins playing [event "playProgess"]

The problem is the second step. I'm trying to eliminate that black screen between when the thumbnail hides (when play is initiated) to when the video actually appears and starts playing.

The way I figure it can be solved is to keep the thumbnail around and trigger the thumbnail hide on the first "playProgress" but I can't seem to find anyway to control when the thumbnail turns on or off.

Is this possible to control? I'm aware that I can pull the thumbnail and overlay it over the iframe but I'm hoping for a cleaner fix (keep it all contained to the iframe).

Here's a pen with api running: http://codepen.io/mattcoady/pen/KMzZMZ

$(function() {
    var player = $('iframe');
    var playerOrigin = '*';
    var status = $('.status');

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

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

        if (playerOrigin === '*') {
            playerOrigin = event.origin;
        }

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

        console.log(data.event);

        switch (data.event) {
            case 'ready':
                onReady();
                break;

            case 'playProgress':
                onPlayProgress(data.data);
                break;

            case 'pause':
                onPause();
                break;

            case 'finish':
                onFinish();
                break;
            case 'play':
              onPlay();
              break;
        }
    }

    // Call the API when a button is pressed
    $('button').on('click', function() {
        post($(this).text().toLowerCase());
    });

    // 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(message, playerOrigin);
    }

    function onReady() {
        status.text('ready');

        post('play');

        post('addEventListener', 'pause');
        post('addEventListener', 'finish');
        post('addEventListener', 'playProgress');
    }

    function onPause() {
        status.text('paused');
    }

    function onFinish() {
        status.text('finished');
    }

    function onPlay(){
      alert('play')
    }

    function onPlayProgress(data) {
        status.text(data.seconds + 's played');
    }
});

Solution

  • What I ended up going with my hacky fix. It's pulls the thumbnail and lays it over the video. When my script detects the 'playProgress' event that means the video is actually playing. I use jQuery to fade away the thumbnail cover.

    http://codepen.io/mattcoady/pen/YWqaWJ

    $(function() {
      var player = $('iframe');
      var playerOrigin = '*';
      var videoId = 76979871;
    
      player.attr('src', 'https://player.vimeo.com/video/' + videoId + '?api=1&player_id=player1&background=1&autoplay=1&loop=1');
    
      // Listen for messages from the player
      if (window.addEventListener) {
        window.addEventListener('message', onMessageReceived, false);
      } else {
        window.attachEvent('onmessage', onMessageReceived, false);
      }
    
      $.getJSON('http://vimeo.com/api/v2/video/' + videoId + '.json', {jsonp: 'callback',dataType: 'jsonp'}, function(data) {
        var thumbnail = document.createElement('img');
        thumbnail.src = data[0].thumbnail_large;
        thumbnail.style.width = document.querySelector('#player1').offsetWidth  + 'px';
        thumbnail.style.height = document.querySelector('#player1').offsetHeight + 'px';
        document.querySelector('#vimeo-thumb-container').appendChild(thumbnail);
      })
    
      // Handle messages received from the player
      function onMessageReceived(event) {
        // Handle messages from the vimeo player only
        if (!(/^https?:\/\/player.vimeo.com/).test(event.origin)) {return false;}
        if (playerOrigin === '*') { playerOrigin = event.origin; }
    
        var data = JSON.parse(event.data);
    
        switch (data.event) {
          case 'ready':
            onReady();
            break;
    
          case 'playProgress':
            onPlayProgress(data.data);
            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(message, playerOrigin);
      }
    
      function onReady() {
        post('play');
        post('addEventListener', 'playProgress');
      }
    
      function onPlayProgress(data) {
        $('#vimeo-thumb-container').fadeOut(250);
      }
    
    });