MOOCK LECTURES  back to
FLASH FORWARD CONFERENCE, NYC  

 

deploying and detecting flash
~colin moock, 07.25.2000, flash forward 2000, nyc
~this information is also available in easy-to-chew slide format
flash can turn the web into a medium capable of expressing rich visual and audio messages, and highly interactive content--but only if the right version of the player is installed. at some point in every flash project, flash content producers are faced with the task of avoiding the dreaded puzzle piece. choosing amongst the various player versions--and then detecting the one you need--is one of the trickiest aspects of flash content publishing. colin moock has been dealing with the seemingly endless list of caveats and gotchas involved in flash detection since the days of flash 2. in this session colin offers to help navigate the minefield of effective flash publication with a survey of key issues and a technical exposition of his new detection script, the moock fpi.

when to choose flash
flash is an amazing medium, but it's certainly not the only one we have to convey a message. when choosing flash for our content we must be sure the features of the flash medium suit our communication needs. for instance, flash is not a good medium to choose if our content is simply a long text document such as the one you're currently reading--flash's features are not suited to communicating that kind of content.

marketing types often think of flash as being a suitable medium for publishing what they vaguely call "high-impact" web sites. while that term may look good on a press release, it doesn't really explain in any practical terms what flash does well. in order to determine whether or not our content suits the flash medium, we need to plainly list flash's communication assets.

specifically, flash is a good medium to choose when these factors are important to us:

as you discover more features in flash which are important to your content delivery, add them to the list. having a feature-by-feature breakdown of the strengths of flash as a medium will help you rationalize the decision to use flash (both to yourself and to your client, if you're a web content supplier).

when to choose standard html
flash is not always the best medium for a body of information. There's still a highly significant place for html-based content on the web. true to its roots, html tends to provide a better medium for the representation and maintenance of text-based information. choose html when these factors are important:

why wouldn't you use flash?
as flash developers, we must still face the reality that flash is not installed in all browsers. according to macromedia's whitepaper on flash penetration, flash is now a part of about 90% of the world's browsers. that may seem like a very high percentage, but population percentages tend to obscure individual people. for instance, if you get a million visitors a month to your all-flash site, you turn away 100 000 of them. and depending on which version of flash your site requires, the amount of people you exclude can be even greater: in june 2000, the flash 4 player was listed as available in 71% to 76% of browsers. again, that translates to roughly 300 000 people turned away from a site that gets a million hits a month. don't forget that percentages translate to real viewers.

whether you use flash or not is simply a question of reaching your target audience with your intended message. you need to determine two things: 1) the group of people to which you want to communicate your message and, 2) the medium which best communicates your message to that group. if you're deploying a site and you think flash is the best medium for your message, you have to ask yourself a question: "does my message depend so heavily on the features of the flash medium that i'm willing to reach a smaller audience for the sake of effectively communicating my message?"

sometimes the answer will be easy to determine: in the case of a full-motion cartoon, for instance, the content can't be communicated without animation, so flash is clearly required. no flash, no cartoon. but for more text-heavy informational sites, the decision is not as obvious. flash is not the only medium that can render text, so you're forced to decide whether or not flash will render your content most effectively. even if you decide it will, the question "how many people am i willing to exclude from my content in order to improve its appeal?" frequently translates directly into cash-figures: a 10% drop in a site's audience means a 10% drop in the site's potential revenue. on the other hand, if your flash content is extremely compelling, you may gain a broader audience through good press and word of mouth.

in order to get the best of both worlds, you can optionally create two bodies of content: one in flash, and one not in flash. but creating two versions of a site is obviously more work, so you end up asking yourself another question: "is it worth creating a whole secondary version of my site just to cater to non-flash users?" how you judge "worth it" depends on the type of site you're producing. for revenue-generating sites, you can try to determine whether or not the non-flash site would make enough $$$ to be self-sustaining. in creative or entertainment-based sites, a non-flash version may not be appropriate if too much of the content is lost in the translation from flash to non-flash.

since every case is unique, it's impossible to invent a single set of rules that govern when to use flash and when not to. but in making your decision, never forget your audience: without them, your message sounds like one hand clapping. and never forget the goal of your communication; focusing on that goal will help you decide how to treat your audience.

i'm going to use flash: which version is right for me?
once you've reached the point where you know you want to use flash, you have to decide which version of the player you're going to require your visitors to have. the older the version you require, the greater the percentage of visitors that will be able to see your content. below is a breakdown of flash features and player penetration for flash 2, 3, and 4 (as of mid-2000, flash 2 is pretty much the oldest player you'll see in any real circulation).

flash 4 penetration: 71-76% (march 2000)
key features offered only by flash 4:

flash 3 penetration: 82-91% (march 2000)
key features offered only by flash 3:

flash 2 penetration: 90-94% (march 2000)

how much flash do i need?
after you've picked which version of the player your site requires, you need to decide how much of your site's content will be delivered in flash. obviously, the more content you put in flash, the less accessible your site will be to non-flash users.

if your main content is flash-based (a collection of animated shorts, for example), you may well want to produce your entire site in flash. flash-only sites may also be appropriate where the audience is known to be technically savvy, or where the experience conveyed by the site demands immersive movement and sound.

for commercial, information-heavy sites that require the broadest possible accessibility, flash is best used as an accent device, that is, a way to enhance non-flash content. accenting content with flash is an effective way to give a site a dynamic feel without losing visitors. however, when you use flash to accent content, a good detection script is definitely in order: detection ensures that non-flash users will always be delivered a viewable alternative to the flash accents. we'll get to flash detection options a little later.

some common uses of flash as an accenting device:

choosing a publication model
once you've decided a) that you need flash, b) which version of flash your site will require, and c) how much flash you're going to use on your site, you need to consider a publication model. the publication model you use will determine your users' experience. we'll consider several publication models in terms of their effect on three kinds of users: those who have the flash player, those who do not have the flash player, and those who have an old version of the flash player.

publication model #1: flash on entry page
the most obvious publication model is also the easiest to implement: simply place your flash content on your site's entry page. users that have flash will see your content. but what about users who can't see the content? they have one of these experiences:

not ideal.

placing flash on an entry page is a poor publication model because it causes potential confusion for two of our three site audiences. we want to be sure to offer each of our three audiences a very controlled experience on our site. we don't want to let the browser control their experience because 1) the browser is not branded with our brand, and 2) most browsers have a user interface for installing plug-ins which is confusing to average users. i, therefore, don't recommend ever placing flash directly on the entry-page of a site without any kind of detection.

publication model #2: user-directed site-entry
the most foolproof publishing model puts the control in the hands of the user: create an entry page that tells the user they need a certain version of flash to view the site, and ask them to choose whether to view the flash content or the non-flash content, or, alternately, to download and install flash. while this approach is an extremely reasonable approach, asking users to choose their own entry-path to a site is potentially undesirable for two reasons:

  1. the choice requires users to know what flash is and what version of flash they have. many average web users don't know either of those things (particularly the version of flash they have).
  2. the choice is disruptive to the user experience. we want them to see our content, not to waste time thinking about whether or not they can see our content.

publication model #3: auto-entry through detection
a detection system can be useful as a means of removing the mandatory-choice component of the "user-directed site-entry" model. in a detection-based publication model, we examine the user's browser with javascript or vb script to see if flash is installed. if a new enough version of flash is found, the script automatically issues the flash content. if not, the script presents the non-flash content to the user.

there's only one hurdle in implementing the detection publication model: writing an effective detection script is not a trivial task. even though the programming used in a detection script is not particularly high-level, the seemingly endless combinations of flash players and browser-scripting support are quite challenging to keep up with and test. luckily, several detection scripts have been created by macromedia and third-party flash developers. these are freely available for use and study:

publishing flash content with the moock fpi
we'll explore the detection-based publication model using the moock fpi, which is available from moock.org. in this publication example, we'll assume the content developer is attempting only to use the script, not to customize it or to write a new detection script from scratch. we'll also assume that the detection is being performed on the entry page to a site (though a detection routine could be placed on any page of a site that contains a flash movie or is the access point to a flash movie).

to publish a flash movie using the moock fpi, follow these instructions:

  1. download the latest version of the detection system as a .zip archive. you'll find it posted here:
    http://www.moock.org/webdesign/flash/detection/moockfpi/

  2. extract the file called moockfpi-???.html from the .zip archive (??? is the version of the script).

  3. name that file appropriately as the entry page of your site--probably index.html.

  4. open the newly named page in a text editor.

  5. near the top of the file, locate the following block of code. (note that code blocks which require publisher modification in the fpi are demarcated by rows of number signs.)
    // #############################################
    // these are the user defined globals
    // modify the following variables to customize the inspection behaviour
    
    var requiredVersion = 4;    // version the user needs to view site (max is 5, min is 2)
    var useRedirect = true;     // "true" loads new flash or non-flash page into browser
                                // "false" embeds movie or alternate html code into current page
    
    // set next three vars if useRedirect is true...
    var flashPage = "movie.html"        // the location of the flash movie page
    var noFlashPage = "noflash.html"    // send user here if they don't have the plugin or we can't detect it
    var upgradePage = "upgrade.html"    // send user here if we detect an old plugin
    // #############################################
    
  6. on the line that reads:
    var requiredVersion = 4;
    change the number 4 to the version of flash you require on your site (must be a number between 2 and 5).

  7. decide how you want to deliver your content. there are two options:

    1. page redirection
      page redirection is a good delivery method to use when an entirely separate non-flash site is available for users without the flash player.

      when you deliver your content with page redirection, different pages are loaded into the browser depending on the results of the fpi's plug-in detection. if the correct version of flash is found in the browser, the script loads the flash-movie page. if an old version of flash is found in the browser, the script loads an upgrade-notice page. if no flash player is found in the browser, the script loads the non-flash page.

      note: sometimes you may not want to send users with an old plug-in to an upgrade notice--you may just want them to see the non-flash content. that's easy enough to do: specify the non-flash page as the value of the upgradePage variable. see step 7.

    2. dynamic page generation
      dynamic page generation is particularly useful for sites which use flash to accent non-flash content. an advertising banner, for instance, can be placed on a page as either a flash movie or an animated .gif depending on whether or not the required flash player is detected.

      when you deliver your content with dynamic page generation, the flash or non-flash content is automatically inserted into the entry page, itself. separate flash/non-flash/upgrade pages are not required. dynamic page generation does not support the notion of an upgrade notice. if the required version of flash is found, flash content is delivered. if an old version of flash is found, or if no flash is found, non-flash content is delivered.

    once you've decided which delivery method you want to use, you need to specify that method in the script. on the line that reads:
    var useRedirect = true;
    use the word true if you want to deliver your content with page redirection. use the word false if you want to deliver your content using dynamic page generation.

  8. if you're using page redirection as your delivery method, you need to specify the location of your flash, non-flash, and upgrade-notice pages. otherwise you can skip this step. on the following lines, change the filenames movie.html, noflash.html, and upgrade.html to the appropriate file locations for your content pages.
    var flashPage = "movie.html"
    var noFlashPage = "noflash.html"
    var upgradePage = "upgrade.html"


  9. if you're using dynamic page generation as your delivery method, you need to add the code for your flash and non-flash content. you do so in the body of the page that contains the fpi script. provide the html for your flash movie by modifying the lines of code that read:
    var oeTags = '<OBJECT CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'
    + 'WIDTH="550" HEIGHT="400"'
    + 'CODEBASE="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">'
    + '<PARAM NAME="MOVIE" VALUE="movie.swf">'
    + '<PARAM NAME="PLAY" VALUE="true">'
    + '<PARAM NAME="LOOP" VALUE="false">'
    + '<PARAM NAME="QUALITY" VALUE="high">'
    + '<PARAM NAME="MENU" VALUE="false">'
    + '<EMBED SRC="movie.swf"'
    + 'WIDTH="550" HEIGHT="400"'
    + 'PLAY="true"'
    + 'LOOP="false"'
    + 'QUALITY="high"'
    + 'MENU="false"'
    + 'TYPE="application/x-shockwave-flash"'
    + 'PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">'
    + '</EMBED>'
    + '</OBJECT>';
    
    those lines assign the html tags of your movie to the variable oeTags. change the movie tags as desired. the most important things to change are shown in bold--the location of the flash movie, and the height and width of the movie.

    after you've adjusted your movie tags as desired, specify the html to be displayed if the flash player is not found or is too old. as with the movie tags, the non-flash content is a block of html code assigned to a variable:
    var alternateContent = '<IMG SRC="altimage.gif" HEIGHT="400" WIDTH="550">'
    + '<BR>any desired alternate html code goes here';
    
    there's no limit on the kind or amount of html you can use as your non-flash content: as long as you assign the html to the alternateContent variable, the content will be displayed. add additional lines of html code in single quotes, using the + operator to concatenate each line. note that if you're using images in your non-flash content, you must be sure to include the height and width attributes of the image tags, otherwise internet explorer 4.5 on mac may truncate the images.

further detection-based publishing issues

when is detection impossible?
detection scripts can determine which version of flash is present in most browsers, but there are circumstances under which the player is not detectable. the following browsers do not support detection of the flash player:

in all four of these situations, the moock fpi deploys the non-flash content. you should, therefore, always have a link to the flash content somewhere on the non-flash content for users who know they have flash but are using browsers that do not support detection.

know your codebase
codebase is an attribute of the object tag which is used to place a flash movie on a page in internet explorer. for example:

<OBJECT
CLASSID="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
WIDTH="400"
HEIGHT="300"
CODEBASE="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=4,0,28,0">

the codebase attribute specifies the location of the flash player. the browser uses that location to retrieve the player if it is not installed. take a close look at the #version=4,0,28,0 portion of the codebase value. that information specifies the precise version of the flash player required by the movie being placed on the page. if the version specified in the codebase is higher than the version actually installed in the browser, the browser will go download the newer version (even if the two versions are only different minor releases).

since we've already done our own detection, we already know whether or not the user will be able to see our content. we, therefore, shouldn't inadvertently force the user to download a newer player by specifying a codebase version that's higher than our required version. we can prevent unnecessary downloads by simply removing the version information altogether, like this: CODEBASE="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"

here's some more background reading on the codebase attribute by erica norton at macromedia.

minor version detection
you may have noticed that the fpi detects only major versions of flash (2, 3, 4, etc). to use some features of flash (eg., printing) it may be necessary to detect a minor version. minor versions are the releases of the flash player that come between releases of the flash authoring tool; you'll see them referred to in this style: 4.0r7 and 4.0r12, which translates to version 4, release 7; and version 4, release 12, respectively.

since player release 4.0r11, flash has supported an internal version variable called $version that stores information about the flash player. this variable should be used to handle minor version detection. see macromedia's instructions on how to use $version for minor version detection, by matt wobensmith.

you may wonder why we don't just detect the minor version while we're doing the major version anyway. theoretically we could. here are a couple of reasons why i dont:

  1. normally when we want to use a feature supported by a specific minor version, that feature is only a small part of our flash content. we don't want to prevent users from seeing our entire body of flash content just because they can't use that small part. we should, rather, warn them about the issue inside our flash movie.
  2. when we detect the minor version inside flash, we can make the detection system part of our interface, and provide well-presented options to the user ("upgrade", or "skip this section") without leaving the context of our movie.

other internal version detection
for the same reasons we detect minor versions inside flash, it is occasionally desirable to detect flash 2, 3, and 4 from within flash. before version 4.0r11, however, the flash player had no $version property to consult. still, we can pull a few tricks to make internal version detection possible with those older players. we start with an implementation of the fpi set to detect flash 2. then, if version 2 is detected, we perform our internal detection using the techniques described at moock.org's article on non-scripted detection.

testing your detection system
once you've published a movie using a detection system, you need to check that the system works as you expect and want it to. to do so, you'll need lots of machines, and two pieces of information:

1// how do i uninstall the flash player?
this is a vexing task if you don't know how to do it, but easy if you do. this macromedia tech note explains how to rid your ie (windows only) of the flash activex control. (thanks to erica norton for writing it and matt wobensmith for making sure it was updated to include the step about deleting the .ocx file). in netscape and other browsers that use the flash plug-in (for instance, ie on mac), you can kill flash by deleting the plug-in from the browser's plugins directory. on windows the plug-in is called npswf32.dll and on mac it's one of: Shockwave-Flash-NP-PPC or Shockwave-Flash-NP-68. in both browsers you should restart after uninstalling before doing any tests.
2// where do i get old flash players?
as of march 2000 we have been able to obtain historical versions of the flash player from macromedia's flash support site which has an archive of old flash players. unfortunately, minor versions (like r7, r20, etc) still haven't been posted. the old players were made available after some kicking and screaming by flash developers on flasher-l listserv.

dissecting the moock fpi
for the sake of developers who may want to create a detection script of their own or who wish to extend the moock fpi, here is the core detection methodology used in its code.

javascript detection
in most browser varieties, we can use some form of javascript to detect the flash plug-in. as of version 1.1, javascript has supported an array of plugin objects as a property of the top-level navigator object. each plugin object provides a collection of information about an individual plug-in which is installed in the browser. we use the flash plugin object in the navigator.plugins array to do our detection with javascript. since every plugin object is stored as a named property of the plugins array, we can access the flash plugin object like this:

navigator.plugins["Shockwave Flash"]

in order to check whether or not the flash plug-in exists, we can simply see if the flash plugin object exists:

if (navigator.plugins["Shockwave Flash"])

if the plugin object does not exist, the expression navigator.plugins["Shockwave Flash"] resolves to undefined, from which we infer that the plug-in is not installed. if the plugin object does exist, the expression navigator.plugins["Shockwave Flash"] evaluates to the string "[object Plugin]", from which we infer that the plug-in is installed. there's only one minor wrinkle: version 2 of the flash player is called "Shockwave Flash 2.0" and all other versions are called "Shockwave Flash". our code, hence, checks for both plugin objects when attempting to establish whether or not some version of the plug-in is installed:

if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"])

after we know that the flash plug-in is installed, we have to determine its version. the version information is kept in a property of the plugin object called description. unfortunately, the version number is embedded in a long description string that looks something like this:

Shockwave Flash 4.0 r5

not too big a deal. with a little string manipulation, we can extract the version number. we first check whether we're dealing with Flash 2 or not, then we store the description property in the variable flashDescription for easy access in our string manipulation:

var isVersion2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
var flashDescription = navigator.plugins["Shockwave Flash" + isVersion2].description;
var flashVersion = parseInt(flashDescription.charAt(flashDescription.indexOf(".") - 1));


that takes care of our detection work for browsers that have a navigator.plugins array. (the code in the actual fpi also includes some logic that is used later with the redirection and page-generation systems, but our work with navigator.plugins is done). note that we don't do our detection using the more aptly named clientInformation object because it's not supported in netscape.

vb script detection
the flash player on windows versions of internet explorer comes not as a plug-in but as an activex control. our detection of flash in internet explorer on windows is, hence, achieved through activex detection. to do activex detection we use vb script. since vb script can cause errors on non-vb script-capable browsers, we make sure to only include it when we're dealing with internet explorer on windows. a bit of javascript dynamically generates the vb script content.

the vb script itself is quite simple: it attempts to create a flash object and then checks if that attempt was successful. if it was, we know the player is installed. if it wasn't, we know the player isn't installed. we store that knowledge in a variable for later reference:

flash4Installed = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.4")))

we perform this test once for each version of flash we want to detect. at the end of our tests, we have a series of boolean variables which we use later in the javascript redirection and dynamic page-writing routines.

web tv webtv supports flash 2, and will support flash 3 in the summer of 2000. but jellyscript (webtv's implementation of ecma-262) doesn't have a navigator.plugins array, so we make a special point of sniffing for web tv using the navigator.userAgent property. i don't like to cater specifically to individual browsers because chasing down the information about which browser comes with what version of flash can be an endless and losing battle (especially because users can alter the default distribution of the browser). however, since web tv is attached to hardware, it is stable for long periods of time and cannot be altered by users, so it's easy to keep track of. i therefore make an exception and sniff for web tv explicitly. (plus i think flash looks neat on tv.)

special development notes
a couple of details in the fpi that are not directly related to detection bear mentioning:

  1. the meta tags in the fpi prevent the script page from caching in netscape. some versions of netscape on windows choke on code that is re-executed from the cache. if the meta tags are omitted, netscape users who repeatedly visit the detection script page occasionally get stuck on that page.
  2. if possible, we use the window.location.replace() method to perform page redirection because that method does not adversely affect the functioning of the browser's back button. if we were to use the more common window.location property for redirection the back button would not take the user to the previous page--it would cause the redirection script to re-execute, effectively trapping users on the post-detection page.

revision history
july 23, 2000: posted.
sept 24, 2001: fixed some css causing netscape display problems