JW Player + Brightcove Integration The following code gets video renditions from Brightcove using the media API. It then generates an ordered source list for the JW Player and selects the default rendition based on a pre-set bitrate.

function buildSourcesFromBrighcoveID(brightcoveID, onComplete) {
    var sources = [];
    var brightcoveAPI = 'http://api.brightcove.com/services/library';
    var parameters = {
      command: 'find_video_by_id',
      video_id: brightcoveID,
      video_fields: 'renditions',
      media_delivery: 'http',
      token: 'jskS1rEtQHy9exQKoc14IcMq8v5x2gCP6yaB7d0hraRtO__6HUuxMg..'                
    };

    // Get renditions
    $.ajax({
      dataType: "jsonp",
      url: brightcoveAPI,
      data: parameters
    }).done(function(data){

      var targetRate = 800000; // Bps
      var lowestDiff;
      var closestRate;

      // Sort them by encoding rate, higher rate first
      data.renditions.sort(function(a, b) {
        return parseFloat(b.encodingRate) - parseFloat(a.encodingRate);
      });

      // Get the closest encoding rate to target
      var currentRate = data.renditions[0].encodingRate;
      var lowestDiff = Math.abs(currentRate - targetRate);

      $.each (data.renditions, function(id, rendition){
        var diff = Math.abs(rendition.encodingRate - targetRate);
        if (lowestDiff &gt; diff) {
          lowestDiff = diff;
          closestRate = rendition.encodingRate;
        }
      });

      // Build sources for the player
      $.each (data.renditions, function(id, rendition){
        var newItem = {
          file: rendition.url,
          label: Math.round(rendition.encodingRate / 1000) + ' Kbps'
        }

        // Set default rendition
        if (rendition.encodingRate == closestRate) {
          newItem["default"] = true;
        }

        sources.push(newItem);

      });

      if (onComplete) onComplete(sources);
    });

    return sources;
  }

  function loadVideoPlayer(sources) {

    var playerInstance = jwplayer("player");
    playerInstance.setup({
      sources: sources,
      width: 727,
      height: 455,
      autostart: true
    }); 

  }

buildSourcesFromBrighcoveID('1520880903001', loadVideoPlayer);


Codepen

Questions


How can I be sure buildSourcesFromBrighcoveID completed before doing anything else? I currently run the function that builds the player from within the first function to be sure the Ajax completed, but I would like them to be independent.
Could I build the sources array in a more efficient way? I am currently iterating the renditions 3 times (to sort, to search for the best rendition and to build the sources array).
These two declarations are useless:


  var lowestDiff;
  var closestRate;



As you re-declare them later:


  var currentRate = data.renditions[0].encodingRate;
  var lowestDiff = Math.abs(currentRate - targetRate);



And, on that note, you shouldn't use the var keyword when you reference an already defined variable. However, in this case, the first block can be removed, making the second block the variable declaration.

The following block can be simplified:


  $.each (data.renditions, function(id, rendition){
    var newItem = {
      file: rendition.url,
      label: Math.round(rendition.encodingRate / 1000) + ' Kbps'
    }

    // Set default rendition
    if (rendition.encodingRate == closestRate) {
      newItem["default"] = true;
    }

    sources.push(newItem);

  });



into the following:

  $.each(data.renditions, function(id, rendition){
    sources.push({
      file: rendition.url,
      label: Math.round(rendition.encodingRate / 1000) + ' Kbps',
      default: (rendition.encodingRate == closestRate)
    });
  });





  How can I be sure buildSourcesFromBrighcoveID is completed before doing anything else? I currently run the function that builds the player from within the first function to be sure the Ajax completed, but I would like them to be independent.


You should make the function a promise and use a done callback to ensure the function has been completed successfully before continuing. Read this Stack Overflow question for more information.


  Could I build the sources array in a more efficient way? I am currently iterating the renditions 3 times (to sort, to search for the best rendition and to build the sources array).


Each loop does a different thing, so I'm not 100% sure whether they can be slimmed.