简介:Telltale-Speech-Extractor 是一款面向游戏音频提取爱好者与逆向分析人员的开源工具,基于 Pascal 语言开发,版本 1.4.2,由 Bennyboy 维护。它能够从 Telltale Games 引擎制作的游戏中提取语音与音效资源,并兼容 Skunkape Games 的《Sam & Max Save the World》等第三方作品,新增对《行尸走肉:权威系列》的支持,同时修复了自《蝙蝠侠》第一季以来游戏的自动检测路径问题。资源包共 53 个文件,约 1.03MB,以 pas 与 dfm 源码单元、dpr 工程文件为主,辅以 dll 音频解码库、mp3 示例、pdf 文档与 html 说明,结构完整便于二次编译与功能扩展。用户只需指定游戏目录即可自动定位音频文件,支持试听、按需保存为 WAV 或 OGG 格式。目前已有 209 人学习下载,适合希望研究 Telltale 资源打包机制、批量导出游戏语音或进行音频素材整理的开发者参考使用。
1. 从游戏资源包里捞出音频:Telltale-Speech-Extractor 能解决什么
如果你拆过 Telltale 系游戏的安装目录,大概率见过那种一堆.ttarch后缀的资源包。想从里面单独把对白、音效拎出来,手动改后缀、拿十六进制编辑器翻,基本是自虐。Telltale-Speech-Extractor 就是冲着这个场景来的:它用 Pascal 写成,专门解析 Telltale 自家打包格式,把语音和 sfx 从资源包里提取成可播放的音频文件。适合两类人——做游戏音频逆向的从业者,以及想拿原版对白做二次剪辑、字幕对齐、语音分析的开发者。它不依赖游戏运行,直接对文件下手,所以离线也能跑。下面按“它怎么解析、怎么编译、怎么用、坑在哪”一路拆下去。
2. 拆开 .ttarch 之前:Telltale 资源包的格式逻辑与工具选型
2.1 为什么是 Pascal,而不是 Python 或 C#
Telltale 的资源打包格式并不复杂,但它的索引结构是分块存储的,每个块有自己的偏移表和压缩标记。用 Pascal 写这类二进制解析工具有个现实好处:Delphi/Free Pascal 对内存块和字节对齐的控制比脚本语言直接,读TFileStream时不用像 Python 那样反复struct.unpack拼字段。另一个原因是历史惯性——早期做 Telltale 工具链的那批人很多是从 Delphi 时代过来的,Pascal 代码在逆向圈子里有现成的二进制处理库可以复用。
从选型角度看,如果你只是临时提几个文件,Python 写个脚本确实更快;但如果你要批量处理几十个.ttarch,还要处理不同游戏版本的格式差异,Pascal 编译出来的单文件可执行程序在分发和运行环境上更省事。Telltale-Speech-Extractor 走的就是这条路:编译一次,拿到 exe 就能在 Windows 上直接跑,不需要装运行时。
2.2 .ttarch 里到底存了什么
Telltale 的游戏资源包通常包含几类东西:纹理、脚本、音频、字体。音频部分又分两种——预加载的短音效和流式加载的长对白。.ttarch文件本身是一个容器,头部有魔数标识,后面跟着块索引。每个块记录了自己的压缩方式(常见的是 zlib 或自定义的 LZ 变体)、未压缩大小和在文件中的偏移。
提取工具要做的第一件事就是读头部、验证魔数、定位索引表。索引表里每一项对应一个资源条目,条目里有资源名、类型标记、块偏移和大小。音频资源的类型标记和纹理不同,工具靠这个标记来筛选。这里有个容易翻车的地方:不同游戏版本的索引表项长度可能不一样,有的版本会在条目末尾多几个字节的填充。如果工具写死了条目长度,遇到新版本就会读串位,表现是提取出来的文件全是乱码或者直接崩溃。
2.3 提取流程的四个阶段
整个提取过程可以拆成四步:
- 读容器头:验证文件是不是合法的
.ttarch,拿到索引表的偏移和条目数。 - 遍历索引:逐条读资源条目,按类型标记过滤出音频资源。
- 解块:根据条目的压缩标记,把对应块解压到内存。如果是未压缩块,直接按偏移和大小读原始字节。
- 写文件:把解压后的音频数据写成独立文件,扩展名根据音频编码来定——Telltale 常用的是
.fsb(FMOD 样本库)或者裸的.wav头。
这四步里,第三步最容易出问题。有些块的压缩标记是“继承前一块”的意思,意思是它和上一个块用同一种压缩方式,但工具如果没维护状态,就会用错解压算法。常见做法是维护一个lastCompression变量,遇到继承标记就沿用上一次的值。
提示:如果你拿到的
.ttarch是加密的,这个工具处理不了。Telltale 后期有些游戏对索引表做了异或混淆,需要先解密再喂给提取器。
3. 把 Pascal 源码跑起来:编译环境、依赖与第一个提取命令
3.1 编译环境怎么搭
Telltale-Speech-Extractor 的源码是 Pascal,通常用 Free Pascal Compiler(FPC)或者 Delphi 编译。在 Windows 上,最省事的路径是装 Lazarus——它自带 FPC 和一套 IDE,不用单独配环境变量。如果你习惯命令行,也可以直接下 FPC 的 Windows 安装包,装完把fpc加到 PATH 里。
Linux 和 macOS 下用包管理器装 FPC 就行:
# Debian/Ubuntu 系 sudo apt update sudo apt install fpc # macOS 用 Homebrew brew install fpc装完之后验证一下版本:
fpc -iV输出应该是类似3.2.2的版本号。如果提示找不到命令,说明 PATH 没配好,手动把 FPC 的 bin 目录加进去。
3.2 从源码到可执行文件
假设你已经把源码包解压到了telltale-extractor/目录,里面有一个主程序文件(常见命名是extractor.pas或main.pas)和若干单元文件。编译命令:
# 进入源码目录 cd telltale-extractor # 用 FPC 编译主程序,-O2 开优化,-o 指定输出文件名 fpc -O2 -oextractor extractor.pas编译过程中如果报 “unit not found”,说明某个依赖单元不在搜索路径里。FPC 默认会在当前目录和标准库路径找单元,如果源码把单元放在子目录(比如units/),需要加-Fu参数:
fpc -O2 -Fusrc -Fuunits -oextractor extractor.pas编译成功后当前目录会出现extractor(Linux/macOS)或extractor.exe(Windows)。这个文件不依赖外部 DLL,可以直接拷到别的机器上用。
3.3 第一次提取:命令参数与输出结构
工具的基本用法是给它一个.ttarch文件和一个输出目录。不同版本的参数名可能略有差异,常见形式是:
# 基本用法:指定输入文件和输出目录 ./extractor -i "game_data.ttarch" -o ./output # 只看资源列表,不实际提取 ./extractor -i "game_data.ttarch" -l # 只提取音频类型,跳过纹理和脚本 ./extractor -i "game_data.ttarch" -o ./output -t audio参数说明:
-i:输入.ttarch文件路径,支持相对路径和绝对路径。-o:输出目录,不存在会自动创建。-l:列表模式,只打印资源名和类型,不写文件。用来确认包里有没有你要的音频。-t:类型过滤,audio只提音频,all提全部。不指定时默认提全部。
跑完之后,输出目录里会出现按资源名命名的文件。如果原始资源名是哈希值,工具可能会用序号代替。音频文件通常是.fsb格式,需要再用 FMOD 的fsbext或者vgmstream转成.wav才能直接播放。
注意:如果提取出来的
.fsb文件大小是 0 字节,大概率是索引表解析错了。先跑-l看列表能不能正常打印,如果列表就是乱的,说明这个.ttarch的版本和工具不匹配。
4. 避坑与排查:提取失败、文件损坏、版本不匹配的五个血泪经验
4.1 现象:工具直接崩溃,没有任何输出
原因:.ttarch文件头部的魔数不匹配。Telltale 在不同时期用过不同的魔数,有些是TTARCH,有些是TTA加版本号。工具如果只认一种,遇到另一种就会在读取阶段抛异常。
解决:用十六进制编辑器打开文件,看前 8 个字节是什么。如果是TTA开头,尝试找支持该版本的提取器分支,或者手动改工具源码里的魔数判断逻辑。改完之后重新编译。
4.2 现象:列表能打印,但提取出来的音频全是噪音
原因:解压算法用错了。Telltale 的块压缩有 zlib、LZ 变体和“无压缩”三种标记。如果工具把 LZ 块当成 zlib 解,出来的字节流虽然长度对,但内容完全是乱的,听起来就是白噪音。
解决:先确认块的压缩标记。在列表模式下加一个调试开关(如果工具支持),打印每个块的压缩类型。常见做法是手动改源码,在解压函数入口加一行日志,把compressionType打出来。对照已知的标记表:0通常是无压缩,1是 zlib,2是 LZ。如果标记是2但代码走的是 zlib 分支,改过来重新编译。
4.3 现象:提取到一半报“磁盘空间不足”,但硬盘明明有空间
原因:索引表里某个资源的大小字段被读成了负数或者超大值。这在 32 位程序里常见——文件偏移超过 2GB 时,有符号整数溢出,变成负数。工具如果没做无符号转换,就会试图写一个巨大的文件。
解决:把工具编译成 64 位版本。FPC 加-Px86_64参数:
fpc -Px86_64 -O2 -oextractor64 extractor.pas如果源码里用了 32 位专用的类型(比如LongInt存偏移),需要改成Int64。改的时候注意所有涉及文件偏移和大小的地方都要统一。
4.4 现象:提取出来的文件数量对,但文件名全是乱码
原因:资源名在索引表里是定长字符串,但不同版本的编码不一样。早期用 ASCII,后期用 UTF-8 或者带长度前缀的变长字符串。工具如果按固定长度读,遇到变长字符串就会把后面的二进制数据也当成名字的一部分。
解决:看索引表项的结构定义。如果名字字段前面有一个字节的长度标记,说明是变长字符串,要先读长度再读对应字节数。如果名字是哈希值(常见于后期游戏),那本来就没有可读名字,工具用序号命名是正常行为,不用修。
4.5 现象:在 Windows 上编译报“找不到 Windows 单元”
原因:FPC 在 Linux 上默认不包含 Windows 相关的单元(比如Windows、Messages)。如果源码里用了这些单元做文件对话框或者路径处理,跨平台编译就会失败。
解决:两个选择。一是装 FPC 的交叉编译包,在 Linux 上编译 Windows 目标:
# 装交叉编译工具链 sudo apt install fpc-source fpc-cross-win64 # 编译 Windows 64 位版本 fpc -Twin64 -Px86_64 -O2 -oextractor.exe extractor.pas二是把源码里平台相关的部分用条件编译隔开,{$IFDEF WINDOWS}包住 Windows 专用代码,{$ELSE}里写 Linux/macOS 的替代实现。后者改动量大,但一劳永逸。
5. 进阶:批量处理、格式转换与验证提取完整性的技巧
5.1 批量提取多个 .ttarch
游戏目录里通常有几十个.ttarch,一个个跑太慢。写个 shell 循环:
#!/bin/bash # 批量提取当前目录下所有 .ttarch 到各自子目录 for f in *.ttarch; do dir="${f%.ttarch}_output" mkdir -p "$dir" ./extractor -i "$f" -o "$dir" -t audio echo "done: $f -> $dir" done这个脚本的逻辑很简单:遍历当前目录的.ttarch文件,为每个文件建一个以原文件名命名的输出目录,然后调用提取器只提音频。${f%.ttarch}是 bash 的字符串截取,把后缀去掉。跑之前确认提取器在当前目录或者 PATH 里。
5.2 把 .fsb 转成可编辑的 .wav
提取出来的.fsb是 FMOD 的样本库格式,很多音频编辑器不认。用vgmstream或者fsbext转:
# 用 vgmstream-cli 转换单个文件 vgmstream-cli -o output.wav input.fsb # 批量转换 for f in *.fsb; do vgmstream-cli -o "${f%.fsb}.wav" "$f" donevgmstream-cli的-o指定输出文件名,不指定的话默认输出到标准输出。批量转换时注意文件名冲突——如果两个.fsb去掉后缀后同名,会互相覆盖。稳妥做法是保留原目录结构,或者用序号前缀。
5.3 验证提取完整性:对比文件数量和总大小
提取完之后怎么知道有没有漏?两个指标:文件数量和总字节数。在列表模式下,工具会打印资源总数和音频资源数。提取完之后统计输出目录:
# 统计输出目录的文件数和总大小 find ./output -type f | wc -l du -sh ./output把文件数和列表模式下的音频资源数对比。如果少了,说明有些块解压失败被跳过了。再看总大小——如果和列表模式打印的“音频总字节数”差太多,同样说明有问题。常见做法是在提取器的源码里加一个计数器,每成功写一个文件就累加,最后打印“成功/总数”。如果工具本身没这个功能,就靠外部脚本对比。
提示:有些音频资源在索引表里标记为“流式”,意思是它不在
.ttarch里完整存储,而是分片存在多个块中。这种资源提取出来可能只有第一片,需要工具支持流式重组。如果发现某个对白文件特别短,大概率就是这种情况。
5.4 一个容易被忽略的细节:输出目录的路径分隔符
在 Windows 上编译的提取器,如果源码里硬编码了\作为路径分隔符,拿到 Linux 上跑(或者反过来)就会出问题。FPC 提供了PathDelim常量,会自动适配当前平台。如果你要改源码,把所有硬编码的\和/换成PathDelim。这个改动很小,但能省掉很多“文件写到了奇怪的地方”的排查时间。
从那以后我每次拿到新的.ttarch,都先跑一遍-l确认列表正常,再小批量提几个文件试听,最后才全量跑。这个习惯帮我省掉了至少三次“提了 20GB 全是噪音”的后悔药。希望帮到你。
本文还有配套的精品资源,点击获取