11

I'd like to write a little class that adds a Day/Month box showing the date a SWF was published from Flash.

The company I work for regularly produces many, many SWFs and many versions of each, iterating over the course of months. A version-tracking system we've been using to communicate with our clients is a Day/Month date-box that gives the date the SWF was published. Up until now, we've been filling in the publish date by hand. If there's any way I can do this programatically with ActionScript that'd be fantastic.

Any insight? Basically, all I need is the call that gives me the publish date, or even.. anything about the circumstances under which a SWF was published that I could use to roll into some form of.. automated version identification, unique to this SWF.

So, can ActionScript tell when a SWF was published?

ivanreese
  • 2,718
  • 3
  • 30
  • 36

5 Answers5

24

George is correct. Adobe sneaks an undocumented ProductInfo tag that contains the compilation date in to every compiled swf. The DisplayObject.loaderInfo.bytes contains the the complete uncompressed swf that loaded the Display Object.

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObject.html#loaderInfo

So the quickest way to get the swf's compilation date without external libraries (from a Display Object):

import flash.utils.Endian;
import flash.display.LoaderInfo;
import flash.utils.ByteArray;
...

private function getCompilationDate():Date{
  if(!stage) throw new Error("No stage");

  var swf:ByteArray = stage.loaderInfo.bytes;
  swf.endian = Endian.LITTLE_ENDIAN;
  // Signature + Version + FileLength + FrameSize + FrameRate + FrameCount
  swf.position = 3 + 1 + 4 + (Math.ceil(((swf[8] >> 3) * 4 - 3) / 8) + 1) + 2 + 2;
  while(swf.position != swf.length){
    var tagHeader:uint = swf.readUnsignedShort();
    if(tagHeader >> 6 == 41){
      // ProductID + Edition + MajorVersion + MinorVersion + BuildLow + BuildHigh
      swf.position += 4 + 4 + 1 + 1 + 4 + 4;
      var milli:Number = swf.readUnsignedInt();
      var date:Date = new Date();
      date.setTime(milli + swf.readUnsignedInt() * 4294967296);
      return date; // Sun Oct 31 02:56:28 GMT+0100 2010
    }else
      swf.position += (tagHeader & 63) != 63 ? (tagHeader & 63) : swf.readUnsignedInt() + 4;
  }
  throw new Error("No ProductInfo tag exists");
}

The SWF Specification: http://www.adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf_file_format_spec_v10.pdf

SketchBookGames
  • 464
  • 8
  • 14
Joony
  • 4,498
  • 2
  • 30
  • 39
  • 2
    +1. Absolutely cool. I wasn't aware that this info was available in the swf out of the box (well, at least when compiled with MXMLC). I'll keep this in mind in case I need to get the compilation date. I like the fact that you can have this data without any kind of extra build-time trickery and without having to use a full blown parser, which seems overkill if all you want is that piece of info. By the way, I wouldn't mind if @spiralganglion accepted this answer instead of the currently accepted one, as it's clearly better than mine ;) – Juan Pablo Califano Nov 12 '10 at 04:13
2

Also you can read the date from the SWF bytecode with the awesome as3swf library. Check this out.

George Profenza
  • 50,687
  • 19
  • 144
  • 218
  • This looks promising. I will try it out and change the answer when I verify that it works. Thank you very much for this. – ivanreese Oct 09 '10 at 07:23
1

In case you're using FlashDevelop (which is very nice lightweight, free AS3 IDE) you can do this:

public static function GetBuildDate() : String
{
    return CONFIG::timeStamp;
}

It returns date in format YYYY-MM-DD

More info: http://www.flashdevelop.org/wikidocs/index.php?title=AS3_Conditional_Compilation

Koshmaar
  • 166
  • 13
1

I'm afraid you can't do it in Actionscript. Depending on how you build the swfs, there might be a couple of options. For instance, if you use the Flash IDE, you could use a JSFL script to publish the swf. This jsfl could replace a placeholder variable where you will store the publication date, and the publish the swf (haven't write a JSFL script in a long time but it shouldn't be too hard to get this working).

So, let's say you have a Version class:

public class Version {

    public var publicationDate:Date = new Date();

}

Your script should read the file where this class lives, find that line and replace it with the current date:

Something like this:

var curDate = new Date();
var dateLine = "public var publication:Date = new Date(" + curDate.getFullYear() + "," + curDate.getMonth() + "," + curDate.getDate() +");";
Juan Pablo Califano
  • 12,213
  • 5
  • 29
  • 42
  • That's certainly not a bad idea. I had thought that I might have to turn to JSFL to accomplish this. Unfortunately, I can't do that for the time being, but it's good to know it can be accomplished in that way. – ivanreese Apr 19 '10 at 20:45
0

Not sure if this would work, but could you use an 'include' statement which calls in an externally generated .as file at compile time which has the (then) current date hard-coded into it? You'd need to have a script of some kind running on your server to update this file once a day to keep it current.

Richard Inglis
  • 5,888
  • 2
  • 33
  • 37
  • I suppose this could work, but it would be a little bit difficult for us to set up, as we're not running any servers. These SWFs are published by individual developers. I suppose I could hack together some sort of batch or something, but that'd be tricky. Thanks for the idea. – ivanreese Apr 19 '10 at 20:40