Flash Player bug with streaming content and innerHTML in IE

A few weeks back some Schematic developers were working on a video player for NBC Universal*. They found a very odd bug: when watching a video, if they hit F5 to reload the page, or closed the popup window, if they were using IE, the audio would keep playing until the video ended or until they closed all their open Internet Explorer windows.

After spending a few hours investigating, Danny noticed that when they weren’t using SWFObject to embed the swf, they didn’t have the problem. So they called me late on a Sunday night to help figure out what the problem was. To make a long story short, the issue was this:

When you embed a swf using innerHTML in IE 6, and stream content to the Flash Player, when the user leaves the page (either by reloading it, hitting the back button, or closing the browser window with another browser window open), the audio will keep playing until the video ends or until the user closes all of their open IE windows.

Working with another developer, we found a very odd resolution at first – if we removed the Id attribute from the object tag, it would fix the problem – no more ghosted audio. The downside to this was that it also broke ExternalInterface calls going into the swf. I tried many other ways to reference the swf, but it seemed that without that Id attribute there, Flash Player wasn’t able to add the Javascript hooks to the page when the plugin was loaded.

After that I started playing with all kinds of different methods including using document.write instead of innerHTML, (which fixed the issue) but the drawback of using this was so great I kept looking for another way to fix it. Without innerHTML, I would have to change the way SWFObject works, move the placement of the Javascript code on the page, and then add more code to clear the alternate content before writing the swf to the page. All of this made that option unacceptable. I also tried using DOM methods to embed the swf file, but that ended up being such a headache I quickly gave up on that as well. Using the DOM to embed plugins is the fastest way to a headache: you think CSS is bad cross browser? Try getting plugins to work…

At this point I gave up, and e-mailed a couple of Adobe contacts. Luckily I’ve had a lot of contact with them lately because of the Devnet article and the whole FlashObject name change thing, so I figured they owed me anyway ;).

I put together a test case (HUGE thanks to Gene Dymarskiy at IBCTV for setting me up with a stream from one of their servers to test against – Gene sent an e-mail to the SWFObject mailing list the day after we found this bug, so was also eager to find an answer to it) and sent the details over to Adobe and waited for them to check it out. A while later, I got some Javascript code back from a Flash Player engineer that with a little tweaking, fixed the problem. Here’s the code that I’ve added to SWFObject:

/* fix for video streaming bug */
deconcept.SWFObjectUtil.cleanupSWFs = function() {
  var objects = document.getElementsByTagName("OBJECT");
  for (var i=0; i < objects.length; i++) {
    for (var x in objects[i]) {
      if (typeof objects[i][x] == 'function') {
        objects[i][x] = null;
      }
    }
  }
}
if (typeof window.onunload == 'function') {
  var oldunload = window.onunload;
  window.onunload = function() {
    deconcept.SWFObjectUtil.cleanupSWFs();
    oldunload();
  }
} else {
  window.onunload = deconcept.SWFObjectUtil.cleanupSWFs;
}

As you can see, it simply checks the page for object tags when the page unloads and loops through their properties looking for functions, and if it finds one, it sets it to null. I’m assuming this is cleaning up some leftovers Flash Player inserts because of the new ExternalInterface stuff, but I haven’t looked too deep into the cause of it.

I’ve just updated SWFObject to v1.4.1 to include this code. If you are using streaming content, this update is a must – if not, you can hold off as this was the only change to the code.

UPDATE: I realized this morning that the title of this post is slightly misleading – this is not a Flash Player bug, but a bug in Internet Explorer 5 and 6 in the way the browser handles the Flash Player. The issue doesn’t exist in IE 7.

UPDATE 2: It seems that there is still one issue remaining with this that can’t be solved. I haven’t tested it extensively, but it appears that when you leave a page using a link from within a Flash movie, the audio will continue, but if you leave the page using the back button or using an HTML link, the audio will be stopped. The bug was introduced when Microsoft introduced the Eolas changes, so it may be fixable in a future update. I’ll post more info here as I get it.

UPDATE: The latest SWFObject (v1.4.2) fixes all of the known isues with this, so if you are still seeing the problem, go update and you should be fine.

* If you want to check out the player, which has TONS of great content loaded into it, you can try these urls:

The player was built so it can be re-skinned on the fly for all the different networks or shows. Dig around a bit, there’s so much great content in there – especially some of the Conan and SNL stuff.

55 thoughts on “Flash Player bug with streaming content and innerHTML in IE

  1. I have recently been using the SWF Object on a lot of my current projects, it a great method. But on one site imparticular i have been having some bizar issues with images loading in IE. The page itself has x4 different flash movies embedded into the page with the SWFObject. Each .swf is completely stand-alone requesting .xml file for their data. But as the flash is loading into the page along with it’s .xml it seems to stop imgaes in the body of the page from loading / displaying. It’s only happens on lower bandwidth connections (56k) and only in IE. I have been trying for 2 week now to find a resolution to the problem but with no joy. If I only embed one .swf in the page it seem to be fine. Have you ever come accross anyhting like this?

  2. I have stumbled upon a bug with swfobject, but it only happens in your latest version. Whenever I try to do a getUrl to a hiddenframe (i’m implementing a swf safe back button) IE will say: “Out of memory at line: 114”

    I changed back to an older version of swfobject after trying all sorts of things (I was having some other problems with my code before upgrading swfobject so i didn’t know what caused this error) and now I don’t get the errormessage anymore…

    If you need more specific information you can mail me.

    Hope this helps,

    Laurent

  3. The video streaming patch has been really important to our project – but I just wanted to let you know that although you said you had updated the swfobject.js file, it doesn’t include the new changes. Just thought you might like to know. Thanks for a fantastic script.

  4. If they already have an onunload set, this script will leave theirs intact and add the extra code on to that.

  5. I just installed swfobject and am receiving an error in IE that reads “Out of memory At line 114” every time i refresh the page. This only seems to happen if i have two flash objects on the one page, as with one object it is fine. I have ensured the div=id’s and so.write’s are unique but am stuck now…please help!

  6. Heres the code i am using, what am i doing wrong?

  7. The latest version of SWFObject does not fix the audio bug when you hit the back button … Any insight would very appreciated!!

  8. To reinforce Brian Wells comment: MP3 sound played using loadSound do not stop when hitting “back” on IE. Other than that, great job!

  9. Regarding the microsoft audio bug that keep playing the audio after leaving the page.
    Where can I get more info about it ?

  10. I just got finished with installing your code and file. It seems to work very well.
    It would be nice if Microsoft would not make this sort of thing necessary.
    Thank you very much.

  11. Has anyone found a solution to the problem that Richie reported? I also seem to be getting an “Out of memory at line …” error with IE when I include two flash objects on one page (with or without SWFObject). Perhaps this isn’t the best forum to address the issue, but a search for ‘externalinterface’ and ‘out of memory at line’ only turns up Richie’s question.

  12. Sorry this is a bit off topic again, but regarding Richie’s original question and my own reiteration if it, it seems the broken part of ExternalInterface is (below), where placing two ExternalInterface-activated flash objects on a page at the same time (in IE) causes an infinite recursion with __flash_unloadHandler:

    function __flash_unloadHandler() {
    myflash_object.style.display = ‘none’;
    for (var prop in myflash_object) {
    if (typeof(myflash_object[prop]) == “function”) {
    myflash_object[prop]=null;
    }
    }
    if (__flash_savedUnloadHandler != null) {
    __flash_savedUnloadHandler();
    }
    }
    function __flash_setupUnloadHandler() {
    if (window.onunload != __flash_unloadHandler) {
    __flash_savedUnloadHandler = window.onunload;
    window.onunload = __flash_unloadHandler;
    }
    }


    I guess it would be cool if SWFObject included a work-around for this bug, but since almost nobody seems to use two or more ExternalInterface-active objects at the same time, the increased code size might outweight the (massive) advantage for those of us who do.

  13. Geoff, I’m a bit confused about the plug-in /player detection. I know ExpressInstall detects the VERSION of flash player but in order to just detect whether the player is present or not does the basic version work? I would like to avoid having to add anything to the actual Flash file. Thanks again :)

  14. I’ve found a bit of a work-around for the multiple ExternalInterface problem with __flash_unloadHandler that we’ve come across in IE. The solution has worked for me in player 9, but I believe it should work for 8, too, as the scheme shouldn’t have changed much. The fix is simple and tricky at the same time. I’ve put mine below, but please just don’t copy and paste as the tricky parts can get you if you don’t customize it to your code.

    First, the simple part. You need to set __flash_unloadHandler = function() to create a replacement function. This needs to be called at some point after the flash ExternalInterface mechanism has set its own __flash_unloadHandler function. In my code, I call it every time I get a certain call from the player just to make sure my version is there when you unload the page. In this function place a global variable that you’ve set to false at load time (i.e. var externalProbSet = false). Then place this code in the function:


    if (externalProbSet) return;
    externalProbSet = true;

    This will make sure the code doesn’t go into that infinite loop.

    Now, the tricky part. The main part of the code appears to be some sort of cleanup so that no functions are left behind in the browser when the page unloads. I’m not really certain how useful this is since I tried commenting that code out and the page still closed just fine. Still, I’m assuming it has some value so I’ll leave it in. The only problem is that the flash player over-writes its own old versions of __flash_unloadHandler, and since the function directly references one and only one flash object, the other objects won’t be “cleaned up”. To be nice and tidy, we’ve got to figure out a way to “clean up” all of the flash objects. One interesting thing is that the ExternalInterface player seems to create a variable that contains a direct reference to each player instance that is the same as the id of the instance. Thus if you id a player “flash1”, then there is a “flash1” reference variable in your global space (don’t overwrite it!). In my code, I have an object (fspobj) that contains references to all the flash players on the page. My code does a “for in” loop on this object and gets all the id references which then can act as the objects themselves after you eval them. You’ll have to come up with your own methods for iterating through your flash players.


    __flash_unloadHandler = function()
    {
    if (externalProbSet) return;
    externalProbSet = true;
    for (var obj in fspobjs)
    {
    var theObj = eval(obj);
    theObj.style.display = "none";
    for (var prop in theObj)
    {
    if (typeof(theObj[prop]) == "function")
    {
    theObj[prop]=null
    }
    }
    }
    if (__flash_savedUnloadHandler != null)
    {
    __flash_savedUnloadHandler();
    }
    }
    if (window.onunload != __flash_unloadHandler)
    {
    __flash_savedUnloadHandler = window.onunload;
    window.onunload = __flash_unloadHandler;
    }

    I make sure this code is only called in IE on the PC when there are multiple instances of my player. Notice that I’m repeating the __flash_setupUnloadHandler code there just for good measure. It looks like if you don’t do that then the new function you just created is ignored.

    Anyway, hope this is helpful. I’m sure it could be refined some.

    Daniel Niland
    Software Engineer
    Walt Disney Internet Group

  15. Thank you Daniel, that was very helpful!

    Now the tricky part is to determine when exactly do the flash objects replace the onUnload function in order to replace it afterwards with our own code (although your workaround to do it once in a while works).

    Good job.

  16. Yeah, I couldn’t quite nail that down. It seems to be after flash player onload, but other than that I gave up, since for me occasionally re-writing the function seems to take virtually no overhead and it wasn’t worth the headache of hunting down that exact moment.

  17. Re: where to replace __flash_unloadHandler — I haven’t had any problems doing it in window.onbeforeunload, though I guess that breaks with much older browswers (but given that ExternalInterface already requires Flash 8, does that matter?).

  18. I’m getting the same problem (out of memory line 56) using the externalInterface with multiple flash movies in IE7 (Beta 2). Of course that could just be my coding! The problem does not exist in Mozilla or netscape.

  19. We’ve determined that the Out of memory atl line 56 error is a Flash Player 9 error. I’ve adjusted SWFObject so that it removes the javascript that fp9 inserts into the page and then uses my own custom cleanup code instead of the bad code that fp9 inserts.

    I’ll be releasing the new version later today, or if you don’t want to wait, you can pull the latest version (1.4.3) out of SVN at svn.deconcept.com/swfobject/.

  20. First, much thanks for this imba fix!
    I changed Daniel Niland’s script a very bit to work more dynamic. ( fspobjs to getElementsByTagName(‘OBJECT’) )

    Just paste it somewere on your page an it should work:

    function cleanup() {
    __flash_unloadHandler = function(){
    if (externalProbSet) {return};
    externalProbSet = true;
    for (var obj in getElementsByTagName(‘OBJECT’)){
    var theObj = eval(obj);
    theObj.style.display = “none”;
    for (var prop in theObj){
    if (typeof(theObj[prop]) == “function”){
    theObj[prop]=null
    }
    }
    }
    if (__flash_savedUnloadHandler != null){
    __flash_savedUnloadHandler();
    }
    }
    if (window.onunload != __flash_unloadHandler){
    __flash_savedUnloadHandler = window.onunload;
    window.onunload = __flash_unloadHandler;
    }
    }
    window.onbeforeunload=cleanup;

    THX again MS

  21. I’m having a problem with swfObject. When I call a javascript function (even a simple alert function), from a page with flash content, the flash content immediately unloads. Has anybody seen this before?

  22. There’s a new issue whith using onbeforeunload: If you have a link that has an href=”javascrpt:…” in it, it will trigger the onbeforeunload in IE.

    I’m trying to think of a different way to fix this, but the only way that I can think of that would be 100% is to add an interval that constantly checks the onunload and overwrites it whenever a new Flash movie is written to the page. Not a very clean way to do things.

  23. thanks for the insight into this memory bug you guys, I implemented a very similar fix in my surebert.com javascript toolkit. In your swfobject fix you can save a bunch of lines by using attachEvent instead of checking to see if the handlers exists and then copying them.


    //////////You can replace this/////////////////////
    // fixes bug in fp9 see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
    deconcept.SWFObjectUtil.prepUnload = function() {
    __flash_unloadHandler = function(){};
    __flash_savedUnloadHandler = function(){};
    window.attachEvent(
    if (typeof window.onunload == 'function') {
    var oldUnload = window.onunload;
    window.onunload = function() {
    deconcept.SWFObjectUtil.cleanupSWFs();
    oldUnload();
    }
    } else {
    window.onunload = deconcept.SWFObjectUtil.cleanupSWFs;
    }
    }
    if (typeof window.onbeforeunload == 'function') {
    var oldBeforeUnload = window.onbeforeunload;
    window.onbeforeunload = function() {
    deconcept.SWFObjectUtil.prepUnload();
    oldBeforeUnload();
    }
    } else {
    window.onbeforeunload = deconcept.SWFObjectUtil.prepUnload;
    }


    ////////////////// With this/////////////////////

    deconcept.SWFObjectUtil.prepUnload = function() {
    __flash_unloadHandler = function(){};
    __flash_savedUnloadHandler = function(){};
    window.attachEvent( "onunload", deconcept.SWFObjectUtil.cleanupSWFs );
    }
    window.attachEvent( "onbeforeunload", deconcept.SWFObjectUtil.prepUnload);

  24. Thanks, Bobby actually just e-mailed a very similar update that used attachEvent.

    While it would be attracticve to switch to something like this, I need to take into account other issues, like only adding the event if the user is running IE, and you have to pay attention to other things that can break that, like Atlas adding in an attachEvent method if a user isn’t in IE. So for the next release I’ll probably look into optimizing this a bit more. Thanks!

  25. I just wanted to say thanks to you guys for this fix. I was going crazy trying to solve this problem… Thanks!

  26. IE, Multiple Flash movies using ExternalInterface, OUT OF MEMORY LINE 56, ERROR:

    This may help someone… if you simply delete the offending function (defined by flash player 9) that IE loops: “__flash_savedUnloadHandler” using the “onbeforeunload” handler, and you’re not using an onunload handler in your script, it corrects the problem.
    [tested in ie6,SP2(standalone) & ie7]

    function nullFlashLoopFunction() { __flash_savedUnloadHandler = null; }
    window.onbeforeunload = nullFlashLoopFunction;

    Hope that helps someone.

    .tim.

  27. This fix is already included in the latest SWFObject version (1.4.4) – it removes the bad unload handlers and replaces them with one that doesn’t cause the out of memory error.

    The unload handlers are important because they fix an issue in IE where streaming media doesn’t quit playing when you leave the page.

  28. I’ve got multiple SWFs on a page. In IE6 and IE7 I an getting “Out of memory at line: 126” when linking out of the page. Any suggestions?

  29. Hi,

    I was receiving still getting ‘out of memory’ errors using IE 6 & 7 with version 1.4.4 of SWFObject.js however using the firebug (http://www.getfirebug.com) firefox extension I noticed a complaint from firefox about the amount of recursion in one of the swfobject.js functions. At line 208 in the released version (line 130 in the trunk svn) I commented out the recursive call //oldBeforeUnload(); Now a page we are working on with 3 SWF’s embedded works fines with fp9 + IE6 & 7.

    Geoff, could it be in some cases Firefox handles recursion and memory access it doesnt like rather better than IE which simply craps out?

  30. Graham: We came across this exact problem at Yahoo! today. It was caused my multiple versions of SWFObject being loaded into the same page. Might be worth checking to make sure you’re not including SWFObject in your page twice.

  31. Thanks Graham and Steve. Saved me lots of trouble, I’m glad I read to the end of the comments. //oldBeforeUnload() did the trick. (the most cred. goes to Geoff though)

  32. For the out of memory errors:

    One of the reasons this occurs is due to the fact that you have more than one requests to include the swfobject.js file.
    Just make sure a page doesn’t have 2 or more requests to load that external script.

  33. have been using swfobject for some time and has worked great. but i have a client that has 3 flash obect and is getting out of memory line 126. swfobject1.4.4 did not fix, sany suggestions?

  34. Dean (re: Dean Evans — May 18, 2006)
    We’ve found a similar issue – a SWF that loads some XML is breaking images. Although worse – when the SWF was near the beginning of the HTML, the actual HTML itself was getting cutoff! Its a timing thing – if the page hasn’t finished loading by the time the XML has finished, problems occur. It looks like (guessing) that when the XML is finished loading, the connection is closed (by Flash player?) .. .this actually closes off the connection within IE – and that connection IE also uses to fetch other page content! We moved the SWF to the end of the HTML, and now rather than cutting off the HTML, it’s ‘only’ cutting off the last few images from the page. Am giving up and hard-coding my data inside the SWF :-(

  35. why do you have to include only swfobject.js file once in each page. Does it not go to browsers cache?
    I’m making some changes in my blog
    so every comment is needed. Feel free to write anything.
    Mario

  36. um, hello guys..
    i got a problem on coding about innerHTML in flash coding though i am not actually a web developer master… anyway, my point is, to understand what is the main code for the innerHTML for flash, a flash object that not reload on every page when you have change…

    hope some of you can advise me and help me about this…

    PS.
    give me a mail when you have a full coding of this problem… thanks

  37. If you are using one of these versions of Windows then Internet Explorer 6 was not installed by default when you installed the operating system but rather from an upgrade. Since you upgraded to IE6 you have the advantage of having a repair toolthat came with the installation.

Comments are closed.