Google Analytics Event Tracking for Flowplayer: Setting Up Playlist Video Clip Event Tracking

Image of Flowplayer Standard VersionWhen it comes to improving and enhancing any website, understanding the user experience is key.  For existing websites, there's almost no better way to determine how users interact with your site than Event Tracking.  Google Analytics provides the ability to track all kinds of events; and nowhere is this as pertinent as with audio and video streams.  

When embedding a/v on a website, site owners often want to know just how many people watched a video in its entirety or listened to an audio podcast completely.  With event tracking, one can monitor:

  • How many times the play action/control was clicked on a multimedia clip
  • The instant (time index) within a clip where it may have been stopped or paused
  • How many times the clip or segment was played through to its finish

Recently, I had to configure GA Event Tracking with an instance of a Flowplayer playlist (thus being able to track multiple video clips that are configured to play continually in series with one another.  In addition, the playlist was configured as two parallel sets of videos (one formatted and optimized for iOS devices, and one for other platforms.)  

Flowplayer does offer a google analytics plugin, but it is limited in capabilities.  As such, I thought it'd help to document my custom implementation of GA Event Tracking for a Flowplayer playlist with the ipad plugin for future reference.  

In the code blocks below, site-specific implementation variables are denoted in BOLD RED CAPS.  Coding comments are in italicized blue.
 
In your HTML, you should be calling the google analytics script and initializing your individual event tracking variable before the function call to flowplayer.  This could occur either in the <HEAD> section of your HTML or between the closing </BODY> and </HTML> tags similar to:
  <script type="text/javascript">
    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
  </script>
  <script type="text/javascript">
    // the try statement below is used for tracking visits to the page
    try {  
      var pageTracker = _gat._getTracker("UA-#######-#");
      pageTracker._trackPageview();
    } catch(err) {};  

    // the variable below is used for individual event tracking  
    var _tracker = _gat._getTracker("UA-#######-#");  
  </script>

 
Your flowplayer javascript call should resemble the code below.    
/*
 * function flowplayer(player_container_id, {flash_wrapper, embed settings}, commercial key, clip {}, 
 *                                                  playlist[], plugins{} ).ipad().playlist(playlist_container_id,variables)
 *   function initializes an instance of flowplayer
 *     note: this should be called after initializing google analytics tracking
 */
 
flowplayer(PLAYER_CONTAINER_ID, {src: "flowplayer_js/flowplayer.commercial-3.2.7.swf"},
  {
  key: 'COMMERCIAL_LICENSE_KEY_AS_STRING',
  clip : {
    autoBuffering: true,
    duration: CUMULATIVE_TIME_OF_CLIPS_WHEN_PLAYED_BACK_TO_BACK,

    //Google Analytics Event Tracking, default settings for entire playlist
    // track start event for this clip
    onStart: function(clip) {
      _tracker._trackEvent("Event Category", "Play", clip.url);
    },
    // track pause event for this clip. time index (in seconds) is also tracked
    onPause: function(clip) {
      _tracker._trackEvent("Event Category", "Pause", clip.url, parseInt(this.getTime()));
    },
    // track stop event for this clip. time index (in seconds) is also tracked
    onStop: function(clip) {
      _tracker._trackEvent("Event Category", "Stop", clip.url, parseInt(this.getTime()));
    },
    // track finish event for this clip
    onFinish: function(clip) {
      _tracker._trackEvent("Event Category", "Finish", clip.url);
    }
    //note last item in clip array does not have a trailing comma
  }, //end clip array
  playlist: [  //each segment or video clip is an element in the playlist array
    {
      url: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_1_FILENAME.flv",
      ipadUrl: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_1_FILENAME.mp4",
      duration: vid_duration = DURATION_OF_1st_VIDEO_SEGMENT_AS_INTEGER,
      position: prevEnd = calcTimeIndex(vid_duration,0),
      autoPlay: false // disable automatic playing on page load/launch of player
    }, //end 1st clip
    {
      url: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_2_FILENAME.flv",
      ipadUrl: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_2_FILENAME.mp4",
      duration: vid_duration = DURATION_OF_2nd_VIDEO_SEGMENT_AS_INTEGER,
      position: prevEnd = calcTimeIndex(vid_duration,prevEnd),
      autoPlay: true  // enable automatic play of this video segment upon load
    }, //end 2nd clip
    {
      url: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_N_FILENAME.flv",
      ipadUrl: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_N_FILENAME.mp4",
      duration: vid_duration = DURATION_OF_2nd_VIDEO_SEGMENT_AS_INTEGER,
      position: prevEnd = calcTimeIndex(vid_duration,prevEnd),
      autoPlay: true  // enable automatic play of this video segment upon load
    }, //end nth clip
    {
      url: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_LAST_FILENAME.flv",
      ipadUrl: "RELATIVE_OR_ABSOLUTE_FILE_PATH/SEGMENT_LAST_FILENAME.mp4",
      duration: vid_duration = DURATION_OF_LAST_VIDEO_SEGMENT_AS_INTEGER,
      position: prevEnd = calcTimeIndex(vid_duration,prevEnd),
      autoPlay: true  // enable automatic play of this video segment upon load
    } // end clip NOTE- last item in playlist array does not have a trailing comma
  ], //end playlist array
  plugins: {
    controls: {
      playlist: true,  //enable the controls plugin to show playlist buttons
      stop: true
    }
  }
  }).ipad().playlist(PLAYLIST_CONTAINER_DIV_ID_AS_STRING, {loop:true} );

In the implementation above, I was able to track the same four events for each of the clips within the playlist.  In each of the event tracking calls,

  1. "Event Category" can be your own description to identify and group the events.  For example, you may want to use the name of the video series/playlist.
  2. The second argument is the Event Action.  You could change the text to read anything you want, but most would want to track it by the control/button type.
  3. The third argument, clip.url, represents the url of the video or audio segment in the series.  Replace clip.url with clip.ipadUrl to track for iPads.  This is passed as the Event Label.
  4. The fourth argument, a javascript call to parseInt(this.getTime()) tracks the time index (in seconds, within that particular clip) at which a button was pressed.  That time is passed as an Event Value.  Note, when looking at your Analytics report, Event Value is a cumulative total.  Refer to Average Value to understand when your video might be paused or stopped.  

If you wanted to track different events for each clip, then you would move the event tracking calls into the playlist event section themselves, rather than place it in the general clips section.  As of the date of this post, real-time event tracking on Google Analytics is not available, however most events are reflected on the site after approximately one hour.

An example of the above code in action can be found at SaintClares.org/saintclares247, launched December 23, 2011.  For more details about how to implement a Flowplayer playlist compatible with iOS devices, be sure to read my post Flowplayer: Configuring a Cumulative Sequence of Video Clips with Playlist & Ipad Plugins.