You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过JavaScript获取SWF文件的内部标题并设置为网页标题

如何通过JavaScript获取SWF文件的内部标题并设置为网页标题

嘿,这个需求很合理!你要的是SWF文件内部存储的正式标题(不是文件名那种一串字符),这个信息其实藏在SWF的元数据标签里,咱们可以通过读取并解析SWF的二进制数据来获取它。下面是具体的实现步骤和代码修改:

实现思路

SWF文件的内部标题存放在**DefineInfo2标签(标签类型13)**中,我们需要:

  1. 读取用户上传的SWF文件的二进制数据
  2. 解析SWF文件结构,定位到这个元数据标签
  3. 提取标签里的标题内容
  4. 将提取到的标题设置为网页标题

具体代码修改

首先添加一个解析SWF标题的辅助函数:

async function getSWFTitle(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = function(e) {
      const buffer = new Uint8Array(e.target.result);
      let offset = 0;

      // 跳过SWF文件头:签名(3字节)+版本(1字节)+文件长度(4字节小端)
      offset += 3 + 1 + 4;

      // 遍历所有SWF标签
      while (offset < buffer.length) {
        // 读取标签头:高10位是标签类型,低6位是长度(长度>=63时需要读扩展长度)
        const tagHeader = (buffer[offset] << 8) | buffer[offset + 1];
        const tagType = tagHeader >> 6;
        let tagLength = tagHeader & 0x3F;
        offset += 2;

        if (tagLength === 0x3F) {
          // 处理扩展长度(4字节小端)
          tagLength = (buffer[offset] << 24) | (buffer[offset + 1] << 16) | (buffer[offset + 2] << 8) | buffer[offset + 3];
          offset += 4;
        }

        // 找到DefineInfo2标签(类型13),这里存储标题等元数据
        if (tagType === 13) {
          offset += 1; // 跳过保留字段
          // 读取以0结尾的UTF-8标题字符串
          let titleBytes = [];
          while (offset < buffer.length && buffer[offset] !== 0) {
            titleBytes.push(buffer[offset]);
            offset++;
          }
          const title = new TextDecoder('utf-8').decode(new Uint8Array(titleBytes));
          resolve(title || "未知SWF标题");
          return;
        } else {
          // 跳过当前标签的内容,继续找下一个
          offset += tagLength;
        }
      }

      // 如果没找到元数据标签,用文件名作为备选(去掉.swf后缀)
      resolve(file.name.replace(/\.swf$/i, ""));
    };
    reader.onerror = reject;
    reader.readAsArrayBuffer(file);
  });
}

然后修改你的runSWF函数,调用上面的函数获取标题并设置网页标题:

async function runSWF() {
  const fileInput = document.querySelector("#flash");
  if (fileInput && fileInput.files[0]) {
    const file = fileInput.files[0];
    // 先获取SWF内部标题
    const swfTitle = await getSWFTitle(file);
    // 设置网页标题为你想要的格式
    document.title = `emu - ${swfTitle}`;
    // 加载SWF文件
    swfobject.embedSWF(URL.createObjectURL(file), "gameWin", "640", "480", "9.0.0");
  } else {
    alert("You forgot to input your SWF!!");
  }
}

补充说明

  • 上面的代码默认处理未压缩的SWF(文件头以FWS开头),如果你的SWF是压缩格式(开头是CWS),需要先解压ZIP压缩的内容才能解析元数据,要是需要处理这种情况,可以告诉我,我再补充解压的逻辑。
  • 要是你更倾向于用Ruffle的API来获取,也可以尝试在Ruffle加载完成后,通过rufflePlayer.getMovie().metadata来访问元数据,但这个方法依赖Ruffle的版本,稳定性不如自己解析二进制。

备注:内容来源于stack exchange,提问作者X078

火山引擎 最新活动