news 2026/5/6 14:37:24

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 15:47:52

老款Mac升级实战指南:macOS兼容性破解与性能解锁全攻略

老款Mac升级实战指南&#xff1a;macOS兼容性破解与性能解锁全攻略 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 老旧Mac设备面临系统升级困境&#xff1f;苹果官方支持…

作者头像 李华
网站建设 2026/5/2 19:32:37

3步解锁老设备潜力:面向复古科技爱好者的系统升级指南

3步解锁老设备潜力&#xff1a;面向复古科技爱好者的系统升级指南 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 老旧设备重生并非遥不可及的梦想。本文将深入探讨如何通…

作者头像 李华
网站建设 2026/5/1 11:47:55

Z-Image-Turbo镜像内置哪些黑科技?一文说清楚

Z-Image-Turbo镜像内置哪些黑科技&#xff1f;一文说清楚 Z-Image-Turbo不是又一个“跑分好看但用不起来”的模型。它是一套经过工程锤炼的完整图像生成系统——从模型本身到服务架构&#xff0c;从交互界面到部署逻辑&#xff0c;每一层都藏着让开发者真正省心、让用户真正顺…

作者头像 李华
网站建设 2026/5/1 9:12:05

一张图拆多层?Qwen-Image-Layered真实案例分享

一张图拆多层&#xff1f;Qwen-Image-Layered真实案例分享 你有没有遇到过这样的修图困境&#xff1a;想把商品图里的背景换成纯白&#xff0c;结果边缘毛边糊成一片&#xff1b;想给海报中的人物换件衣服&#xff0c;却连带把头发和阴影一起扭曲变形&#xff1b;想批量调整几…

作者头像 李华
网站建设 2026/5/1 10:15:20

解锁Mac鼠标潜能:掌控专业级指针体验的技术侦探指南

解锁Mac鼠标潜能&#xff1a;掌控专业级指针体验的技术侦探指南 【免费下载链接】mac-mouse-fix Mac Mouse Fix - A simple way to make your mouse better. 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix Mac Mouse Fix是一款能够重新定义鼠标体验的…

作者头像 李华
网站建设 2026/5/1 11:06:41

HsMod炉石传说插件全攻略:55+增强功能让游戏体验升级

HsMod炉石传说插件全攻略&#xff1a;55增强功能让游戏体验升级 【免费下载链接】HsMod Hearthstone Modify Based on BepInEx 项目地址: https://gitcode.com/GitHub_Trending/hs/HsMod 核心价值&#xff1a;为什么选择HsMod&#xff1f; 当你在炉石传说中遇到这些场景…

作者头像 李华