Articles Archive
Articles Search
Director Wiki
 

Detecting QuickTime

December 5, 2000
by Zac Belado

So you're nearing the end of your most recent CD project, and it strikes you that some users might not be able to view some of the great content you've included because they don't have the requisite QuickTime files installed. You could certainly add an entry to the product's system requirements, but that isn't a fail-safe method. What you need to do is write some Lingo code to check for the presence of QuickTime and then react accordingly if the user doesn't have it installed.

This article will present the steps needed to create a movie that will:

  1. Check to see if QuickTime is present
  2. Check to see if the correct version of QuickTime is present
  3. Display a screen that offers to install QuickTime or quit the movie

Is there anybody out there?

The first thing you need to do is determine whether or not the user has QuickTime installed. A secondary, but equally important, requirement is to ensure that the user has the correct version of QuickTime. It isn't going to do you any good if the user has QuickTime 3 installed and the movie you want them to play needs QuickTime 4. So, determining if the user can play your QuickTime content is actually a two-part process. This can be done using the quickTimeVersion() function.

The Lingo Dictionary defines quickTimeVersion() as follows:

returns a floating-point value that identifies the current installed version of QuickTime and replaces the current QuickTimePresent function.

The function will return the current version of QuickTime, or zero if QuickTime isn't installed.

Armed with this knowledge, you can create a function that will test the user's machine.

global gQTState

on checkForQT versionNumber

  if voidP(versionNumber) then exit

  currentVersion = quickTimeVersion()

  if currentVersion <> 0 then
    
    -- check to see if we have the right version
    if currentVersion >= versionNumber then
      gQTState = #QTPresent
    else
      gQTState = #wrongVersion
    end if
    
  else
    -- it isn't present
    gQTState = #notPresent
  end if

end

To use it, you call it and supply the version of QuickTime that you want to search for. For example,

checkForQT(4)

would check for the existence of QuickTime version 4 on the user's machine. The function uses a global variable gQTState to store the results of its test. In the sample movie, gQTState is initially set to #unknown:

on startMovie

  gQTState = #unknown
  checkForQT(4)

end

Once checkForQT() has been called, the variable will be one of three values:

  1. #notPresent
    QuickTime was not found on the user's machine
  2. #wrongVersion
    QuickTime was found, but the wrong version was installed on the user's machine
  3. #QTPresent
    QuickTime was found and it is the correct version.

Acting accordingly

Now that you know the state of the user's machine (in terms of its QuickTime version), you can redirect the user if need be. This can be accomplished by adding a case statement to the startMovie handler to test the value of gQTState.

on startMovie

  gQTState = #unknown
  checkForQT(4)

  case (gQTState) of
      
    #QTPresent:
      -- just go about our business
      nothing
      
    #wrongversion:
      go frame "wrongversion"
      
    #notPresent:
      go frame "noQT"
      
  end case

  initMovie()

end

If the user has the correct version of QuickTIme installed, the movie continues to play. If they don't have the correct version, then the movie jumps to the wrongVersion marker. If no version of QuickTime is present, execution jumps to the noQT marker.

Options

The reason for jumping to a new marker is that it allows you to make the user aware of a problem, and to present them with options. As you can see in the sample movie, each option jumps to a frame that has a title, a small explanation of the problem, and three buttons.

At this point, the user has to make a decision about how she wants to proceed.

Quit

Quit the movie. This is included because the user shouldn't arbitrarily be forced to install something on their machine that they don't want to. You might think that they need QuickTime installed, but the ultimate choice should be left to the user; so this button would have a script on it that simply quits the projector.

on mouseUp me
  quit
end

Install

The user could also choose to install the newer version of QuickTIme, if you've included the installer. Apple has two versions available: a stub installer that downloads the files from their web site; or a full installer that contains all the required files in a separate cache file. The full installer can be found at http://www.apple.com/quicktime/download/support/.

If this an option you want to provide, then you need to do two things. First, determine the path to the installer and then run it. In order to determine the path to the installer (and which version to run), you first need to determine the platform the user is running and what path delimiter you need to use when building a file path to the installer. This is actually something you should determine as soon as the movie starts. The sample movie does this in the startMovie handler and then stores the result in a global variable.

global gQTState, gPathDelimiter

on startMovie

  gPathDelimiter = determineDelimiter()
  gQTState = #unknown

You can then write a function to return the platform's path delimiter. On the Mac it is a colon ":" and under Windows it is a backslash "\". So, the function would look something like this.

on determineDelimiter

  thisMachine = the platform

  if thisMachine contains "Windows" then
    return "\"
  else if thisMachine contains "Macintosh" then
    return ":"
  else
    -- wishing for a world with UNIX playback
    return "/"
  end if

end

Once the path delimiter has been determined, you can generate the path to the installer. A typical place to store the QuickTime installer is in a subdirectory called "QT". But before you can build the path, you need to again identify the user's OS, because the Mac and Windows versions of the installer will have different names. Since you already did this when you ascertained the path delimiter, you can use the delimiter to determine the name of the correct installer.

global gPathDelimiter

on mouseUp me

  -- build a path to the installer
  pathToInstaller = the moviePath & "QT" & gPathDelimiter

  case (gPathDelimiter) of
      
    "\":
      pathToInstaller = pathToInstaller & "quickTime Installer.exe"
      
    ":":
      pathToInstaller = pathToInstaller & "quickTime Installer"
      
  end case

  -- open it
  open pathToInstaller

  -- quit
  quit

end

Once you have created the path to the file, you can use the open command to run the installer, and then quit the projector.

Disable

The final option would be to allow the user to disable the QuickTime elements and continue playing the movie. This is a middle-ground solution between requiring the user to install QuickTime and not playing the movie at all. This is probably only a useful option if there isn't a large number of QuickTime movies, or if the movie doesn't have sound assets that require the QT3Mix sound mixer.

In order to facilitate this you need to include another global variable, called gDisableQT, that will track whether the QuickTime assets are to be displayed or not. Initially, this should be set to TRUE. You can then set this variable to FALSE if the user chooses to exercise this option.

global gDisableQT

on mouseUp me

  -- turn off the QT sprites
  gDisableQT = TRUE

  -- init the movie variables etc
  initMovie()

  -- go to the start frame
  go frame "intro"

end

You may have noticed earlier on in the article that the startMovie() handler includes a call to a handler called initMovie(). This handler is where you would place all the code you need to execute in order to initialize your movie. This is set aside in a separate handler for many reasons, but the one most salient to this discussion is that it allows you to jump back and initialize your movie variables in case the user does want to disable the QuickTime elements. If you keep all that initialization code in your startMovie handler, you won't be able to activate any of those variables or execute any code you need before your movie starts.

The final ingredient needed to allow you to disable the QuickTime assets in the movie is a small behavior that will check the value of gDisableQT and set the QuickTime sprite's visible property to FALSE if the QT assets have been disabled.

global gDisableQT

on beginSprite me
  -- turn off the sprite if we need to disable the QT sprites
  if gDisableQT then sprite(me.spriteNum).visible = FALSE
end
 
on endSprite me
  -- re-enable the sprite once it is finished playing
  if gDisableQT then sprite(me.spriteNum).visible = TRUE
end

Remembering, of course, to set it back to TRUE once the sprite has finished playing so you don't accidentally "turn off" a sprite that you'll need in another section of the movie.

Wrapping it all up

Now you should be able to test for the presence of QuickTime in your movies, and allow the user to have several options in response to the state of their current QuickTime version. You don't necessarily have to provide all these options in each movie. Typically, your client will have some say in this process, and may remove options based on their knowledge of the end user or their own preferences.

Complications

The following discussion is really of use to developers who need to support older Windows machines. Under Windows, if there are multiple versions of QuickTime installed, the quickTimeVersion() function may return something other than the most recent version. The possible return values for quickTimeVersion() are:

  1. the version of QuickTime installed, or zero if QuickTime is not present
  2. if there is more than one version installed, then the latest version of QuickTime is returned
  3. if there is a version prior to 3 installed, it will return version 2.1.2 instead

This still isn't totally reliable, either. It appears that under Windows NT the quickTimeVersion() function will still return the most recent version despite the presence of any QuickTime 2 controls or DLLs. The reason for this odd behavior is a result of some changes Apple made to QuickTime version 3 under Windows. This allowed older versions of the Xtra to remain on the machine and still function.

This isn't much of an issue unless you are working with older Windows systems that are still running the 16 bit version of QuickTime, or where QuickTime 2 may be installed.

The quickest way around this problem is to use the Buddy API Xtra and the baVersion() command to test the version number of any QuickTime 2 components and the version of any more recent QuickTime controls. The baVersion() function is supplied a string indicating for which component you want the version number. To get the QuickTIme 2 version number you supply it with the string "qt":

baVersion("qt")

and to get the most recent QuickTime versions you pass it the string "qt3":

baVersion("qt3")

If you need to check for both versions, you could write a small function that would use the baVersion() function to test for each "type" if QuickTime and then return the results.

Untested code warning! This code is based on some functions posted to DIRECT-L by Fumio Nonaka and has been modified to fit my own peculiar coding style. All the machines here at DOUG North's Arctic testing facilities have QuickTime, and none of them have ever had QuickTime 2 installed, so we have been unable to adequately test the code. Any errors or bugs in the code are this author's responsibility, not Fumio's.

on os_QTVersions

  QT = stringToFloat(baVersion("qt"))
  QT3 = stringToFloat(baVersion("qt3"))

  theReturn = []

  if QT <> QT3 then
    
    if QT <> 0 then append theReturn, QT
    append theReturn, QT3
    
  else
    theReturn = max(QT, QT3)
  end if

  return theReturn

end

What the function will do is return a single float value if there is only one version of QuickTime, or a list with both versions if QuickTime 2 is present. The stringToFloat() function (included in the sample movie) is used to convert the data returned by baVersion() from a string to a number.

Testing the function on my Mac returns:

put os_QTVersions()
-- 4.1000

Notice that the baVersion() function appears to return a slightly different number than quickTimeVersion(). On my Mac, quickTimeVersion() returns:

put quickTimeVersion()
-- 4.1600

but the baVersion() function returns

put baVersion("qt3")
-- "4.1.0"

This is a minor point, but something to watch out for.

A sample Director 7 movie is available for download in Mac or Windows format.

Zac Belado is a programmer, web developer and rehabilitated ex-designer based in Vancouver, British Columbia. He currently works as an Application Developer for a Vancouver software company. His primary focus is web applications built using ColdFusion. He has been involved in multimedia and web-based development, producing work for clients such as Levi Straus, Motorola and Adobe Systems. As well, he has written for the Macromedia Users Journal and been a featured speaker at the Macromedia Users Convention.

Copyright 1997-2024, Director Online. Article content copyright by respective authors.