May 28

Make Captivate HTML5 Work in Firefox

screen shot of error dialogWith the slow but steady demise of Flash, SWF-based elearning software makers, like Adobe, have been “cramming” (a word from disruptive innovation) HTML5 into their products, like Captivate (I’m using v6.1), to keep up. Because the HTML5 spec itself is still growing in inconsistent and at times uncertain directions there are bound to be holes and gaps in the implementations. For Captivate 6.1 the first one I encountered was the “This browser does not support some of the content…” error I got when I attempted to view my HTML5 output in my browser of choice—Firefox. It was version 20, and I know Firefox has supported HTML5 audio and video tags since version 3.5 so it had to be something silly. In the proprietary software world that may mean license issues, and so it does with Firefox (Free, Open, Libre software) and the MP3 (not so much). Captivate exports only MP3s, Firefox (and Opera) play only OGGs. So until Adobe offers a checkbox on the Publishing page you can do the following, or hope your visitors use only IE, Safari or Chrome—as the majority probably do… but we’re big on inclusion around here so let’s not leave anyone out!

I quickly ascertained it’s the MP3-only audio export preventing Firefox from doing Captivate sound. As you probably know, some browsers do MP3, others do OGG. You may even remember why. Fortunately that’s the only reason Firefox won’t play Captivate HTML5. All you have to do are

  1. create OGG versions of each MP3 and
  2. edit two JavaScript files to
    1. detect Firefox
    2. provide the appropriate file extension and
    3. suppress the error message.

Simple enough you say, but I figured I may as well google it and see what others have done. I did, and found all the hints I needed in hermit9911’s answer to this post (scroll down a few). hermit just needs OGG. I want both to work depending on browser, so I had to improvise on hermit9911’s theme. Here are the steps I ended up following.

1. Create OGG versions of each MP3

There are many programs that convert audio formats. I used Audacity’s “Chains” feature (macros). Since I’ve met many more people who know of Audacity than know of its Chains feature, I’ve done a separate screencast of that process:

Made using Camstudio (screen video), iPhone (narration),
Audacity (mix/process audio) & Sony Vegas (mix/render video)
Can you suggest a good open source video editor? Please use the comments with my thanks!

2. Edit two JavaScript files

detect Firefox

Project.js is found in the root export folder. It’s “minified,” which means line breaks and extra spaces are removed and it’s pretty hard to read, but we can add our tiny bit of code right at the beginning. I don’t see any need for feature detection in this case, so I settled for user agent:

var is_firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; 
// converts the string to lowercase then creates Boolean, 
// true if it finds 'firefox' anywhere in the name. Otherwise : false 

provide the appropriate file extension

Once you have a question that can be answered yes or no the best syntax is usually as follows:

myExtension = is_firefox ? '.ogg' : 'mp3'; <br>// Yes? Send '.ogg' No : send '.mp3

Then just search & replace existing .mp3' with '+myExtension Everything between ”s is literal, myExtension is variable depending on the answer to is_firefox?yes:no;

UPDATED: If you have Administrator rights and access to the Adobe Captivate install folder you can add these changes to the template Captivate creates the file from. Otherwise both files are overwritten every time you publish, and you have to repeat all these steps. If you can access and edit
[InstallFolder]\HTML\assets\js\CPHTML5Warnings.js
use that file instead (path to install folder will differ depending on operating system and installation) otherwise follow the instructions as written:
Next, open [PublishFolder]/assets/CPHTML5Warnings.js and make the two additions suggested by hermit9911. (I looked up the earliest version of Firefox that supported the audio tag and replaced hermit9911’s xx with 3.5).

this.BrowserEnum.FIREFOX_MIN_SUPPORTED_VERSION = 3.5; // sets minimum version, used in code below

suppress the error message

Finally at the very bottom of the file you will find a series of IF and IF ELSE statements… add the following after the closing semicolon of the last one:

else if((this.browser == this.BrowserEnum.FIREFOX) <br>  &amp;&amp;<br> (this.browserVersion &gt;= this.BrowserEnum.FIREFOX_MIN_SUPPORTED_VERSION )) <br> lSupported = true;

Browse to index.html in Firefox, press Play and watch your movie. With a bit of practice this will add all of about 5-10 minutes to your publishing routine. Alas, you’ll have to redo Project.js—and convert all your audio files— every time you publish.

As an extension activity, make this work for Opera (yes, you can use find/replace but watch case-sensitivity. Do each separately… firefox/opera and FIREFOX/OPERA). Use flow control instead? (Hint: yes) Look back at the code above and explain why you need to do that. Would you change the variable name? To what?

My entire solution instructions and code snippets
(including my answers to the extension questions)

/* ADD TO TOP OF Project.js */
var wantsOggsOverEasy = ((navigator.userAgent.toLowerCase().indexOf('firefox') > -1) || (navigator.userAgent.toLowerCase().indexOf('opera') > -1)), myEXT=wantsOggsOverEasy?'.ogg':'.mp3'; 
/* nb comma/semi-colon usage - I declared 2 local vars in 1 dec */

/* This is the text to search for
   .mp3' and change it to '+myEXT
  EXAMPLE
  FROM: src:'ar/Mouse.mp3',du:182
       TO: src:'ar/Mouse'+myEXT,du:182

IF you have Admin privileges find the Captivate install folder and edit the warnings file found in
[InstallFolder]\HTML\assets\js\CPHTML5Warnings.js. Otherwise you can save these changes in a safe place and you'll need to replace [PublishFolder]/ar/CPHTML5Warnings.js in the published location every time you publish. (Project.js is generated programmatically by the publishing engine, so to the best of my knowledge it must be fixed after each publish, also protect your OGG files.)  */

/* In CPHTML5Warnings.js 
(somewhere between lines 19 and 20) non-destructively ADD:  */

        this.BrowserEnum.FIREFOX_MIN_SUPPORTED_VERSION = 3.5;
        this.BrowserEnum.OPERA_MIN_SUPPORTED_VERSION = 10;

(approximately line 112) AFTER final 
          lSupported = true; AND BEFORE

          return lSupported; non-destructively ADD 

		else if((this.browser == this.BrowserEnum.FIREFOX) && (this.browserVersion >= this.BrowserEnum.FIREFOX_MIN_SUPPORTED_VERSION))

            lSupported = true;	
		else if((this.browser == this.BrowserEnum.OPERA) && (this.browserVersion >= this.BrowserEnum.OPERA_MIN_SUPPORTED_VERSION))
            lSupported = true;

§

N.B. Post was edited for clarity since first publishing.