Using Flashy to Play Video inside Lightbox2

Nov 6 2009

By default, the Drupal Lightbox2 module supports the flvPlayer flash movie player, which is not Open Source. However, Drupal has a 100% Open Source video player called Flashy. Here's a quick method of overriding Lightbox's setup to use Flashy instead of flvPlayer. Update: Fixed for Internet Explorer.

Assumptions: This article assumes that you already have Lightbox2 configured, and you already have fields configured to use Lightbox2's video support. All we are doing here is swapping Flashy in for flvPlayer.

There are two steps to making this work: Configuring and coding.

Configuring Lightbox2

The first is to configure Lightbox2 to use Flashy's SWF file. To do this, go to Administer>Lightbox2>General (The general lightbox settings page) and enable video support, pointing the software to Flashy's SWF:

From there, all you need to do is add a simple function re-declaration using JavaScript.

Scripting Lightbox2

You will need to have the SWFEmbed module or jQuery plugin installed. But once that is done, you can easily do the rest in your theme's script file, or in a custom module:

$(document).ready(function () {
  function splitQString(queryString) {
    var pairs = queryString.split('&');
    var map = {};
    for (i = 0; i < pairs.length; ++i) {
      var two = pairs[i].split('=');
      map[two[0]] = two[1];
    }
    return map;
  }

  // We are going to override showData, but we want to keep
  // the old version around.
  Lightbox.oldShowData = Lightbox.showData;

  // Override Lightbox.showData
  Lightbox.showData = function () {
    // If this is a video, do our own processing.
    if (Lightbox.isVideo) {
      // Hide the throbber
      $('#loading').hide();
      // Paint controls
      Lightbox.updateDetails();
      // Embed the video
      $("#modalContainer")
        .swfEmbed(Lightbox.flvPlayer, Lightvideo.settings)
        .click(function(){return false;})
        .css('zIndex', '10500')
        .show();
    }
    // If this is not a video, use the old logic.
    else {
      return Lightbox.oldShowData();
    }
  }

  // Override Lightvideo.createEmbed
  Lightvideo.createEmbed = function (href, id, color, variables) {
    // Create settings.
    Lightvideo.settings = {flashvars:{}, height: 342, width: 608};
    Lightvideo.settings.flashvars = splitQString(variables);
    Lightvideo.settings.flashvars.video = Lightbox.videoId;

    // We don't want anything in the HTML.
    Lightbox.modalHTML =  '';
  }
});

In the code above, all we are doing is re-defining the lightbox Lightvideo.createEmbed and Lightbox.showData functions. The showData function is re-written to allow the object to be written directly into the DOM. This is necessary because of the way IE treats object and param tags. The swfEmbed jQuery plugin is used to write the actual tags. This function abstracts away all of the details of browser-specific embedding.

In order to make sure that all of the other Lightbox2 behavior works as expected, we copy an old copy of showData into oldShowData. When some other Lightbox2 feature is used, our new showData function simply hands control off to oldShowData

The createEmbed function is rewritten to simply handle settings instead of generating a deprecated embed tag.

That's all there is to it.

The old SWFObject library could also be used to do this sort of embedding. There may be examples in the Flashy module which would illustrate this.

Where to Go from Here

At some point, I will figure out how to make this approach generic enough that it can accomodate either Flashy or flvVideo. I'm sure the maintainers of Lightbox2 would welcome any such patch. My change above, however, will allow ONLY use of Flashy.