录音元数据提取与映射:让历史录音可检索
迁移里最常见的失败不是音频转不出来,而是转出来了没人能定位到具体某一通。检索刚需的字段在平台数据库里,不在音频文件里。本文讲清哪些字段必须一起导出、对应关系怎么固化、时区与时间戳的坑,以及导出成什么结构才算真的可检索。
更新于
真正卡住迁移的,往往不是音频
录音迁移做到一半卡住的时候,问题很少出在音频本身。专有容器能解、编码能识别、WAV 也批量转出来了,几十万个文件整整齐齐躺在新归档里。然后合规部门来一句「把某年某月某日、某个坐席跟某个号码的那通调出来」,没人做得到。因为决定「能不能找到某一通」的字段,几乎都不在音频文件里,而在原平台的数据库里:通话开始时间、坐席工号、主叫号码、被叫号码、呼叫方向(呼入还是呼出)、通话时长,以及把这通电话与业务系统串起来的业务流水号。少了这些,导出的结果只是可播放,不是可检索。而可播放本身价值接近于零——没有人会去逐个试听三十万个文件。
对应关系的两种断法:接不上,和接错了
音频与元数据的对应,通常靠源数据库里那一列指向存储位置的信息建立:每条通话记录带着录音文件的路径、文件名或内部 ID。它的脆弱之处在于,这是一条外部约定,而不是文件自身的属性。导出过程中把文件重命名、按日期重新分目录、或者把多批数据合并进同一个扁平目录而撞了重名,对应关系就断了。断了之后想补,只能靠音频侧仅存的几个物理特征去猜:时长、文件大小、修改时间。几十万条里同一秒开始、时长又相同的通话大量存在,这种猜测的结果没有人敢拿去应付一次监管调阅。所以对应关系必须在导出的第一步就固化,而不是留到最后再拼。另一种断法更安静:对应关系没断,但时间字段本身是错的。平台数据库里存的到底是什么时间,需要逐个部署去确认——有的存服务器本地时间且不带任何时区标记,有的存 UTC,有的在不同表里两者混用。只要不带偏移量,这一列就是有歧义的:跨时区调阅会整体错位数小时,夏令时切换的那两天还会出现重复或凭空缺失的一小时。稳妥的做法是导出时同时保留三样东西:转换后的 UTC 时间戳、原始字段的原样值、以及这个原始值所属的时区与偏移。三者齐全,日后任何一方对不上都还能回溯;只留一个转换结果,错了就永远查不出错在哪。
可检索的导出该长什么样
- 把元数据当主索引而不是附件:源库的一条通话记录对应一行,每行都带上指向具体音频文件的相对路径,并且这一列在全量范围内唯一。
- 时间拆成三列:UTC 时间戳、原始时间的原样值、所属时区或偏移。只留一列叫「时间」是不够的。
- 字段名与取值做一次显式映射并写成文档:呼叫方向在一套系统里可能是 1 和 2,在另一套里是 I 和 O;坐席工号可能在两张表里各有一套编号。这些映射要落在文档上,不能只活在脚本里。
- 选一种能被直接导入的结构化格式(CSV、JSONL、Parquet 之类),而不是人工维护的表格文件。几十万行既超出表格软件的行数上限,也没法施加主键约束。
- 导出后立刻做双向校验:每一行元数据都能解析到一个文件,每一个文件也都能解析回一行,两侧差集都必须为空,并且都要留档。
- 把源库记录总数、实导条数、缺失条数以及缺失的时间分布写进核验报告。这份报告才是「可检索」这件事的证明。
上海万椿的做法
我们长期从事呼叫中心历史录音的解析与迁移,元数据从来不是音频之外的附加项,而是与音频同等的交付物:从源平台数据库提取检索所需的完整字段,与解析出的音频逐条建立并固化对应关系,时间字段按上面的三列口径导出,最终产出可以直接导入检索系统的结构化清单,并附一份与源库逐条对账的核验报告。目标始终是同一个——让历史录音脱离任何单一厂商,永久在线、随取随用、可被检索也可被分析。