代码分析 长音频分割为短音频

import os

import json

import argparse

from pathlib import Path

#简单易用的音频处理库 pydub 支持加载、切片、格式转换、音量调整,底层依赖ffmpeg

#关键功能就是 audiosegment.from_wav("file.wav") 加载wav文件,audio[start_ms:end_ms]按毫秒切片 clip.export("out.wav",format="wav")导出音频

from pydub import AudioSegment

#这个函数,里面的三个参数是jsonl路径,音频路径,输出路径

def split_audio_by_jsonl(jsonl_path, audio_dir, output_dir):

audio_dir = Path(audio_dir)#为啥要这样?将传入的字符转换为一个pathlib.path对象,因为path可以拼接路径audio_dir / "file.wav",而不是 os.path.join(audio_dir, "file.wav")

#还可以直接调用方法.exists() .is_file()等

output_dir = Path(output_dir)#指向命令行参数,意义同上

#parents=true 如果目录路径中包含多级不存在的父目录,自动递归创建所有上级目录

output_dir.mkdir(parents=True, exist_ok=True)#如果没有便创建

#打开jsonl文件,逐行读取

with open(jsonl_path, 'r', encoding='utf-8') as f:

for line_num, line in enumerate(f, 1):

line = line.strip()

if not line:

continue

#json.loads(line)将字符串line 解析为Python字典item

#.get("key") 获取字段key

try:

item = json.loads(line)

key = item.get("key")

#.get("utterances",[])获得utterances字段,若缺失则默认为空列表

utterances = item.get("utterances", [])

if not key or not utterances:

print(f"⚠️ 跳过第 {line_num} 行:缺少 key 或 utterances")

continue

#看一下这段代码,首先是直接audio_dir/key作为路径,没有的话 加上wav后缀,要是还没有就是没有

查找原始音频文件(支持 .wav)

audio_path = audio_dir / key

if not audio_path.exists():

尝试带 .wav 后缀(如果 key 本身不含���

audio_path = audio_dir / (key + ".wav")

if not audio_path.exists():

print(f"❌ 第 {line_num} 行:未找到音频文件 {key}(或 {key}.wav)")

continue

print(f"🔊 正在处理: {key}")

#然后这个是找到了,用pydub库加载一个.wav格式的音频文件,将其转化为一个可编程操作的音频对象

  • pydub 会调用底层音频引擎(通常是 ffmpeg)读取文件;
  • 将音频数据加载到内存中,转换为 AudioSegment 对象;
  • 对象内部包含:
    • 音频采样率(如 16000 Hz)
    • 通道数(单声道/立体声)
    • 采样位深(如 16-bit)
    • 原始音频数据(以 bytesarray 存储)

audio = AudioSegment.from_wav(audio_path)

#对于utternaces 这里面很多条的 得到开始和结束的 得到text部分,我这个jsonl文件懒得粘贴条目,应该就是里面有 开始 结束 和text这三部分

for utt in utterances:

start_ms = utt.get("start_time")

end_ms = utt.get("end_time")

text = utt.get("text", "").strip()

if start_ms is None or end_ms is None:

continue

确保时间不越界

start_ms = max(0, start_ms)

end_ms = min(len(audio), end_ms)

#很健壮

if end_ms <= start_ms:

continue

切片

clip = audio[start_ms:end_ms]

生成文件名:key_start_end.wav

safe_key = key.replace(".wav", "") # 避免重复 .wav

#这是对于文件的命名,就是以文件名命名,但是不要.wav 然后加上开始和结束时间 作为命名

filename = f"{safe_key}{start_ms}{end_ms}.wav"

#构建路径

output_path = output_dir / filename

clip.export(output_path, format="wav")

print(f" ✅ 保存: {filename}")

except Exception as e:

print(f"❌ 第 {line_num} 行处理出错: {e}")

print(f"\n✅ 所有音频切分完成!输出目录: {output_dir}")

def main():

#命令行参数

parser = argparse.ArgumentParser(

description="根据 JSONL 中的 utterances 时间戳切分音频"

)

parser.add_argument("jsonl_file", help="输入的 .jsonl 文件路径")

parser.add_argument("audio_dir", help="原始音频所在文件夹")

parser.add_argument("output_dir", help="切分后音频的输出文件夹")

args = parser.parse_args()

split_audio_by_jsonl(args.jsonl_file, args.audio_dir, args.output_dir)

简单代码分析

相关推荐
WangYaolove13145 分钟前
基于python的在线水果销售系统(源码+文档)
python·mysql·django·毕业设计·源码
AALoveTouch12 分钟前
大麦网协议分析
javascript·python
●VON21 分钟前
React Native for OpenHarmony:2048 小游戏的开发与跨平台适配实践
javascript·学习·react native·react.js·von
ZH154558913130 分钟前
Flutter for OpenHarmony Python学习助手实战:自动化脚本开发的实现
python·学习·flutter
xcLeigh1 小时前
Python入门:Python3 requests模块全面学习教程
开发语言·python·学习·模块·python3·requests
xcLeigh1 小时前
Python入门:Python3 statistics模块全面学习教程
开发语言·python·学习·模块·python3·statistics
YongCheng_Liang1 小时前
从零开始学 Python:自动化 / 运维开发实战(核心库 + 3 大实战场景)
python·自动化·运维开发
sweetone1 小时前
LINN莲CLASSIK桌面音响微修
经验分享·音视频
鸽芷咕1 小时前
为什么越来越多开发者转向 CANN 仓库中的 Python 自动化方案?
python·microsoft·自动化·cann
秋邱1 小时前
用 Python 写出 C++ 的性能?用CANN中PyPTO 算子开发硬核上手指南
开发语言·c++·python