news 2026/5/4 22:57:47

FSMN VAD输出结果导出:JSON转CSV批量处理脚本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FSMN VAD输出结果导出:JSON转CSV批量处理脚本

FSMN VAD输出结果导出:JSON转CSV批量处理脚本

1. 为什么需要这个脚本?

你刚用FSMN VAD WebUI跑完一批会议录音,页面上漂亮地显示着一串JSON结果:

[ {"start": 70, "end": 2340, "confidence": 1.0}, {"start": 2590, "end": 5180, "confidence": 1.0} ]

但问题来了——领导要你把所有音频的语音片段起止时间整理成Excel表格,方便导入到标注平台;同事想用Python做后续统计分析;而你手头有37个音频文件,每个都得手动复制粘贴、改格式、加文件名……光是点开37次网页就让人头皮发麻。

别折腾了。这篇脚本就是为你写的——一行命令,把几十个JSON结果自动合并成一个带文件名标记的CSV表格,字段清晰、时间可读、开箱即用。

它不依赖WebUI后台,不修改原系统,纯本地运行,5分钟就能部署好。你甚至不用懂Python,复制粘贴就能跑通。

2. 脚本能做什么?(小白一眼看懂)

这个脚本不是“又一个转换工具”,而是专为FSMN VAD工作流设计的轻量级生产力补丁。它解决的是真实场景里的三个卡点:

  • 自动识别文件归属:不用手动给每个JSON加文件名。脚本会根据JSON文件名(如meeting_01.json)自动提取音频名,并写入CSV第一列
  • 时间单位人性化转换:原始JSON里全是毫秒(start: 70),脚本自动转成秒(0.07)和标准时间格式(00:00:00.070),Excel里直接可排序、可计算时长
  • 一键批量合并:把分散在/results/目录下的37个JSON,合成一个vad_summary.csv,结构像这样:
audio_namestart_msend_msduration_msstart_secend_secduration_secstart_timeend_timeconfidence
meeting_0170234022700.072.342.2700:00:00.07000:00:02.3401.0
meeting_012590518025902.595.182.5900:00:02.59000:00:05.1801.0

注意:同一音频可能有多段语音,所以audio_name会重复出现——这正是你做分段统计需要的结构。

它不生成图片、不调用API、不连数据库,就是一个干净的.py文件,双击或命令行运行即可。连Python环境都不用额外装(只要你的WebUI能跑起来,说明环境已经齐了)。

3. 快速上手:三步完成部署

3.1 准备工作:确认你的文件结构

脚本默认从./vad_results/目录读取所有.json文件。请先确保你的FSMN VAD WebUI导出的JSON按如下方式存放:

your_project/ ├── vad_results/ │ ├── interview_01.json │ ├── interview_02.json │ └── call_center_20240512.json └── convert_json_to_csv.py ← 你将创建的脚本

小技巧:WebUI的“批量文件处理”功能还在开发中,但你可以用它的单文件模式,把每个音频单独处理,然后把结果JSON手动保存到vad_results/目录——这是目前最稳的落地方式。

3.2 创建转换脚本(复制即用)

新建一个文件,命名为convert_json_to_csv.py,粘贴以下内容(已实测兼容Python 3.8+,无需额外安装包):

#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ FSMN VAD JSON to CSV Batch Converter Author: 科哥 | 支持 FSMN VAD WebUI 输出格式 Input: ./vad_results/*.json (each contains list of {"start", "end", "confidence"}) Output: ./vad_summary.csv (with readable time columns) """ import os import json import csv from datetime import timedelta def ms_to_time_str(ms): """Convert milliseconds to HH:MM:SS.mmm format""" if ms < 0: return "00:00:00.000" td = timedelta(milliseconds=ms) hours, remainder = divmod(td.seconds, 3600) minutes, seconds = divmod(remainder, 60) return f"{hours:02d}:{minutes:02d}:{seconds:02d}.{ms%1000:03d}" def main(): input_dir = "./vad_results" output_file = "./vad_summary.csv" # Collect all JSON files json_files = [f for f in os.listdir(input_dir) if f.endswith(".json")] if not json_files: print(f"❌ 错误:未在 '{input_dir}' 目录下找到任何 .json 文件") print("请确认文件路径正确,且至少有一个 JSON 结果文件") return print(f" 发现 {len(json_files)} 个 JSON 文件,开始处理...") # Prepare CSV headers fieldnames = [ "audio_name", "start_ms", "end_ms", "duration_ms", "start_sec", "end_sec", "duration_sec", "start_time", "end_time", "confidence" ] with open(output_file, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() processed_count = 0 for json_file in json_files: try: # Extract audio name (remove .json extension) audio_name = os.path.splitext(json_file)[0] # Load JSON with open(os.path.join(input_dir, json_file), "r", encoding="utf-8") as jf: data = json.load(jf) # Process each segment for seg in data: start_ms = int(seg.get("start", 0)) end_ms = int(seg.get("end", 0)) conf = float(seg.get("confidence", 0.0)) duration_ms = end_ms - start_ms start_sec = round(start_ms / 1000, 3) end_sec = round(end_ms / 1000, 3) duration_sec = round(duration_ms / 1000, 3) start_time = ms_to_time_str(start_ms) end_time = ms_to_time_str(end_ms) writer.writerow({ "audio_name": audio_name, "start_ms": start_ms, "end_ms": end_ms, "duration_ms": duration_ms, "start_sec": start_sec, "end_sec": end_sec, "duration_sec": duration_sec, "start_time": start_time, "end_time": end_time, "confidence": conf }) processed_count += 1 print(f" ✔ 已处理 {json_file} ({len(data)} 段语音)") except Exception as e: print(f" ❌ 处理 {json_file} 失败:{str(e)}") continue print(f"\n 全部完成!共处理 {processed_count}/{len(json_files)} 个文件") print(f" 结果已保存至:{output_file}") print(" 提示:用 Excel 或 WPS 打开 CSV,'start_time' 列可直接排序查看语音顺序") if __name__ == "__main__": main()

3.3 运行脚本并验证结果

打开终端(Linux/macOS)或命令提示符(Windows),进入你的项目目录,执行:

python convert_json_to_csv.py

你会看到类似这样的输出:

发现 3 个 JSON 文件,开始处理... ✔ 已处理 meeting_a.json (2 段语音) ✔ 已处理 meeting_b.json (3 段语音) ✔ 已处理 call_2024.json (1 段语音) 全部完成!共处理 3/3 个文件 结果已保存至:./vad_summary.csv 提示:用 Excel 或 WPS 打开 CSV,'start_time' 列可直接排序查看语音顺序

打开生成的vad_summary.csv,你应该能看到整齐的表格,时间列已自动格式化,可以直接用于汇报、分析或导入其他工具。

常见问题直答:
Q:报错ModuleNotFoundError: No module named 'csv'
A:不可能。csv是Python标准库,只要能运行WebUI,这个脚本一定可以跑。检查是否输错了文件名,或路径里有中文空格。

Q:CSV里时间显示乱码?
A:用Excel打开时,选择“UTF-8编码”;WPS用户请右键→“以编码方式打开”→选UTF-8。

4. 进阶用法:按需定制你的输出

脚本设计为“开箱即用,按需可调”。如果你有特殊需求,只需改几行代码,无需重写逻辑。

4.1 修改输入/输出路径(两处)

找到脚本中的这两行:

input_dir = "./vad_results" output_file = "./vad_summary.csv"

改成你实际的路径,例如:

input_dir = "/home/user/fsnm_vad_outputs" output_file = "/home/user/reports/vad_all_2024.csv"

4.2 过滤低置信度片段(加一行判断)

如果你只关心置信度≥0.8的语音段,在for seg in data:循环内加入:

conf = float(seg.get("confidence", 0.0)) if conf < 0.8: # 跳过置信度低于0.8的片段 continue

4.3 添加音频时长字段(扩展分析维度)

想同时知道原始音频总时长?只需在writer.writerow({...})前加一行:

# 假设你有 audio_duration_ms 字段(需提前获取,例如从FFmpeg) # 这里演示如何添加:audio_duration_ms = 120000 # 2分钟 # 然后在 writer.writerow 中加入: # "audio_duration_ms": audio_duration_ms,

实用建议:真正需要音频总时长的场景,推荐用FFmpeg批量提取,再用pandas合并——但这已超出本脚本范围。本脚本专注做好一件事:把VAD结果变成可分析的表格

5. 为什么这个方案比其他方法更可靠?

市面上有各种JSON转CSV工具,但它们对FSMN VAD场景普遍存在三个硬伤:

对比项通用在线转换器Excel“从文本导入”本脚本
文件归属识别❌ 需手动为每个JSON加列❌ 同样需手动自动提取文件名,一目了然
毫秒转时间格式❌ 只做数值转换❌ 公式复杂易错内置ms_to_time_str(),精准到毫秒
多段语音展开❌ 把整个JSON当一整行❌ 无法自动拆分数组每段语音独立成行,结构规整
错误容忍度❌ JSON格式稍错就崩溃❌ 编码错误常导致乱码try/except包裹,单文件失败不影响全局
零依赖部署❌ 需联网、有隐私风险❌ Windows/Mac行为不一致纯本地,无网络,无第三方服务

更重要的是——它和你的工作流无缝咬合。你不需要改变现有操作习惯:照常在WebUI里点“开始处理”,照常把结果存成JSON,最后跑一次脚本。没有学习成本,没有流程切换,没有新工具要适应。

它不是炫技的工程,而是帮你每天省下15分钟的务实工具。

6. 总结:让VAD结果真正可用

FSMN VAD本身是个强大的模型,但再好的技术,如果结果不能被业务方快速理解、不能被下游工具直接消费,它的价值就会大打折扣。

这个脚本做的,就是打通从“模型输出”到“业务可用”的最后一公里:

  • 它把冷冰冰的毫秒数字,变成Excel里可排序、可筛选、可求和的时间戳;
  • 它把散落的37个JSON文件,聚合成一张清晰的总览表,让项目经理一眼看清每段语音归属;
  • 它用最朴素的Python标准库实现,不引入任何新依赖,确保在你现有的服务器、笔记本、甚至树莓派上都能稳定运行。

你不需要成为Python专家,也不需要理解FSMN的内部结构。你只需要记住:
下次导出一堆JSON时,cd进目录,敲python convert_json_to_csv.py,喝口茶,回来就有一张 ready-to-use 的CSV。

这才是AI工具该有的样子——不制造新麻烦,只默默解决老问题。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 0:44:06

颠覆式智能效率工具:3大核心功能让你的求职响应速度提升300%

颠覆式智能效率工具&#xff1a;3大核心功能让你的求职响应速度提升300% 【免费下载链接】boss-show-time 展示boss直聘岗位的发布时间 项目地址: https://gitcode.com/GitHub_Trending/bo/boss-show-time 在竞争激烈的求职市场中&#xff0c;每一分钟都可能决定你是否能…

作者头像 李华
网站建设 2026/4/17 16:58:53

3大突破让你的鼠标在Mac上重获新生

3大突破让你的鼠标在Mac上重获新生 【免费下载链接】mac-mouse-fix Mac Mouse Fix - A simple way to make your mouse better. 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix 痛点突破&#xff1a;第三方鼠标在Mac上的三大困境 设计师小林的滚动困…

作者头像 李华
网站建设 2026/4/26 23:08:42

Glyph OCR不是端到端?但这正是它的优势

Glyph OCR不是端到端&#xff1f;但这正是它的优势 在OCR技术快速演进的当下&#xff0c;一个看似“反潮流”的设计正引发专业用户的深度思考&#xff1a;Glyph-OCR没有选择端到端训练路径&#xff0c;而是构建了一条清晰可拆解、模块可替换、每一步都可验证的视觉推理流水线。…

作者头像 李华
网站建设 2026/5/1 6:18:01

无需配置环境!YOLOv12镜像让目标检测更高效

无需配置环境&#xff01;YOLOv12镜像让目标检测更高效 你是否经历过这样的场景&#xff1a;花两小时配好CUDA、PyTorch、Ultralytics&#xff0c;终于跑通YOLOv8&#xff0c;结果同事一问“你用的什么版本&#xff1f;”&#xff0c;发现对方环境里连model.predict()都报错&a…

作者头像 李华
网站建设 2026/5/2 14:16:16

老Mac焕新:用OpenCore Legacy Patcher实现系统升级的完整指南

老Mac焕新&#xff1a;用OpenCore Legacy Patcher实现系统升级的完整指南 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher OpenCore Legacy Patcher是一款专为老款Intel架构…

作者头像 李华
网站建设 2026/5/4 18:22:07

掌控游戏库管理:开源工具打造一站式游戏体验中心

掌控游戏库管理&#xff1a;开源工具打造一站式游戏体验中心 【免费下载链接】Playnite Video game library manager with support for wide range of 3rd party libraries and game emulation support, providing one unified interface for your games. 项目地址: https://…

作者头像 李华