如何通过JavaScript获取SWF文件的内部标题并设置为网页标题
如何通过JavaScript获取SWF文件的内部标题并设置为网页标题
嘿,这个需求很合理!你要的是SWF文件内部存储的正式标题(不是文件名那种一串字符),这个信息其实藏在SWF的元数据标签里,咱们可以通过读取并解析SWF的二进制数据来获取它。下面是具体的实现步骤和代码修改:
实现思路
SWF文件的内部标题存放在**DefineInfo2标签(标签类型13)**中,我们需要:
- 读取用户上传的SWF文件的二进制数据
- 解析SWF文件结构,定位到这个元数据标签
- 提取标签里的标题内容
- 将提取到的标题设置为网页标题
具体代码修改
首先添加一个解析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




