ActionScript 能否判断 SWF 何时发布?

Posted

技术标签:

【中文标题】ActionScript 能否判断 SWF 何时发布?【英文标题】:Can ActionScript tell when a SWF was published? 【发布时间】:2011-02-09 01:17:06 【问题描述】:

我想编写一个小类,添加一个显示从 Flash 发布 SWF 的日期的日/月框。

我工作的公司会定期制作很多很多 SWF 以及每个版本的多个版本,并在几个月内不断迭代。我们一直用来与客户沟通的版本跟踪系统是一个日/月日期框,它给出了 SWF 的发布日期。到目前为止,我们一直在手动填写发布日期。如果有任何方法我可以使用 ActionScript 以编程方式执行此操作,那就太棒了。

有什么见解吗?基本上,我所需要的只是给我发布日期的调用,甚至……任何关于发布 SWF 的环境的信息,我可以使用它来滚动到某种形式的……自动版本识别,这是该 SWF 独有的。

那么,

【问题讨论】:

【参考方案1】:

乔治是正确的。 Adobe 会在每个已编译的 swf 中偷偷包含一个未记录的 ProductInfo 标签,其中包含编译日期。 DisplayObject.loaderInfo.bytes 包含加载显示对象的完整未压缩 swf。

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

因此,无需外部库(从显示对象)获取 swf 编译日期的最快方法:

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");

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

【讨论】:

+1。绝对酷。我不知道这些信息在开箱即用的 swf 中可用(嗯,至少在使用 MXMLC 编译时)。我会记住这一点,以防我需要获取编译日期。我喜欢这样一个事实,即您可以在没有任何额外的构建时间技巧的情况下获得这些数据,并且不必使用完整的解析器,如果您想要的只是那条信息,这似乎有点过头了。顺便说一句,如果@spiralganglion 接受了这个答案而不是当前接受的答案,我不介意,因为它显然比我的好;)【参考方案2】:

您还可以使用出色的 as3swf 库从 SWF 字节码中读取日期。 签出this。

【讨论】:

这看起来很有希望。当我验证它是否有效时,我会尝试并更改答案。非常感谢您。【参考方案3】:

恐怕你不能在 Actionscript 中做到这一点。根据您构建 swfs 的方式,可能有几个选项。例如,如果您使用 Flash IDE,您可以使用JSFL script 来发布 swf。这个 jsfl 可以替换一个占位符变量,您将在其中存储发布日期,并发布 swf(很长时间没有编写 JSFL 脚本,但应该不会太难让它工作)。

所以,假设你有一个 Version 类:

public class Version 

    public var publicationDate:Date = new Date();


您的脚本应该读取该类所在的文件,找到该行并将其替换为当前日期:

类似这样的:

var curDate = new Date();
var dateLine = "public var publication:Date = new Date(" + curDate.getFullYear() + "," + curDate.getMonth() + "," + curDate.getDate() +");";

【讨论】:

这当然不是一个坏主意。我曾认为我可能不得不求助于 JSFL 来完成此任务。不幸的是,我暂时不能这样做,但很高兴知道它可以通过这种方式完成。【参考方案4】:

如果您使用的是 FlashDevelop(它是一款非常不错的轻量级免费 AS3 IDE),您可以这样做:

public static function GetBuildDate() : String

    return CONFIG::timeStamp;

它以 YYYY-MM-DD 格式返回日期

更多信息:http://www.flashdevelop.org/wikidocs/index.php?title=AS3_Conditional_Compilation

【讨论】:

【参考方案5】:

不确定这是否可行,但您能否使用“include”语句在编译时调用外部生成的 .as 文件,该文件将(当时)当前日期硬编码到其中?您需要在您的服务器上运行某种脚本来每天更新一次此文件以使其保持最新状态。

【讨论】:

我想这可以工作,但设置起来会有点困难,因为我们没有运行任何服务器。这些 SWF 由各个开发人员发布。我想我可以将某种批次或其他东西拼凑在一起,但这会很棘手。谢谢你的想法。

以上是关于ActionScript 能否判断 SWF 何时发布?的主要内容,如果未能解决你的问题,请参考以下文章

隐藏和显示 swf 时如何判断 ExternalInterface 何时可用

将 ActionScript 2 SWF 转换为 ActionScript 3 SWF 文件(可以剥离代码)

无需不断重建 swf 即可修补 actionscript

Actionscript 3 从另一个/根 SWF 调用函数

Actionscript 3 - 在我的 swf 中加载另一个 swf 时出现列表错误

关于 swf 中的 actionscript 标签的按位数学