SoundWise 用命令行批量转录的脚本写法

文章导读
SoundWise 的批量转录通常要解决两件事:一是确认 SoundWise 自带命令行接口还是只暴露 HTTP API,二是确定输入音频的目录结构和命名规则。如果 SoundWise 提供可执行命令,直接写循环调用即可;如果只有 API,就需要用 curl 或 Python 请求包装。下面给出两种通用脚本骨架,先在本机小范围试跑,再推广到全量目录。
📋 目录
  1. 准备输入文件和输出目录
  2. 方式一:SoundWise 提供命令行工具
  3. 方式二:SoundWise 只提供 HTTP API
  4. 验证结果和常见坑
  5. 常见问题
A A

SoundWise 的批量转录通常要解决两件事:一是确认 SoundWise 自带命令行接口还是只暴露 HTTP API,二是确定输入音频的目录结构和命名规则。如果 SoundWise 提供可执行命令,直接写循环调用即可;如果只有 API,就需要用 curl 或 Python 请求包装。下面给出两种通用脚本骨架,先在本机小范围试跑,再推广到全量目录。

批量转录脚本的核心是“文件清单 + 逐条调用 + 失败重试 + 输出落盘”。先确认 SoundWise 的调用方式(命令行或 API 端点),再把音频路径逐一传给转录命令,结果写入对应文本文件。脚本要保留日志和重试机制,因为长音频或高并发下服务端可能超时。适用场景是本地已有成批音频文件、需要一次性生成文字记录;操作前先准备一个包含 3~5 个文件的测试集,跑通后再放开。

准备输入文件和输出目录

建议先把音频集中到一个目录,统一格式,例如只保留 .wav、.mp3、.m4a。如果原始文件分散在多个子目录,可以先用 find 生成清单,避免脚本进入深层目录时路径拼接出错。输出目录建议单独建,比如 transcripts,每个文件命名与源文件一致,但扩展名改为 .txt。

mkdir -p audio_files transcripts
# 把要处理的音频放到 audio_files 下

方式一:SoundWise 提供命令行工具

如果 SoundWise 的 CLI 可以单文件调用,比如 soundwise transcribe input.mp3 -o output.txt,那么用 bash 循环即可。要注意命令名和参数需要根据实际安装的版本调整,下例中的 soundwise 只是一个占位。

#!/bin/bash
INPUT_DIR="audio_files"
OUTPUT_DIR="transcripts"
LOG="transcribe.log"

for f in "$INPUT_DIR"/*.{wav,mp3,m4a}; do
    [ -e "$f" ] || continue
    base=$(basename "$f")
    name="${base%.*}"
    out="$OUTPUT_DIR/$name.txt"

    # 已存在的输出文件可跳过,便于断点续跑
    if [ -f "$out" ]; then
        echo "skip $f -> $out" | tee -a "$LOG"
        continue
    fi

    echo "transcribing $f" | tee -a "$LOG"
    soundwise transcribe "$f" -o "$out" 2>>"$LOG"
    if [ $? -ne 0 ]; then
        echo "FAILED $f" | tee -a "$LOG"
    else
        echo "OK $f" | tee -a "$LOG"
    fi
done

脚本会跳过已生成的文本文件,避免重复处理。如果某个文件失败,日志里有 FAILED 记录,可以单独重跑。

SoundWise 用命令行批量转录的脚本写法

方式二:SoundWise 只提供 HTTP API

如果 SoundWise 只有 API,通常需要先上传音频再获取转录结果。这种场景下用 Python 脚本处理更灵活,因为要处理 HTTP 状态码和轮询。下面是一个通用骨架,你需要替换成实际服务的端点、密钥和请求字段。

import os
import time
import requests
import glob

INPUT_DIR = "audio_files"
OUTPUT_DIR = "transcripts"
API_URL = "https://api.example.com/transcribe"  # 替换成 SoundWise 实际地址
API_KEY = "your-key"  # 替换成你的密钥

os.makedirs(OUTPUT_DIR, exist_ok=True)

def transcribe(audio_path):
    with open(audio_path, "rb") as f:
        resp = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"audio": f},
            timeout=300,
        )
    if resp.status_code != 200:
        raise RuntimeError(f"HTTP {resp.status_code}: {resp.text}")

    task_id = resp.json().get("task_id")
    # 轮询获取结果,每 10 秒查一次,最多等 10 分钟
    for _ in range(60):
        result = requests.get(
            f"{API_URL}/{task_id}",
            headers={"Authorization": f"Bearer {API_KEY}"},
        )
        if result.status_code == 200 and result.json().get("status") == "done":
            return result.json()["text"]
        time.sleep(10)
    raise TimeoutError("polling timeout")

for audio_path in glob.glob(os.path.join(INPUT_DIR, "*.mp3")):
    base = os.path.basename(audio_path)
    out_path = os.path.join(OUTPUT_DIR, ".".join(base.split(".")[:-1]) + ".txt")
    if os.path.exists(out_path):
        continue
    try:
        text = transcribe(audio_path)
        with open(out_path, "w", encoding="utf-8") as f:
            f.write(text)
        print(f"OK {audio_path}")
    except Exception as e:
        print(f"FAILED {audio_path}: {e}")

这个骨架假设 API 返回 JSON,且包含 task_idstatus 字段。如果 SoundWise 是同步返回文本,可以去掉轮询部分,直接读取响应内容。

SoundWise 用命令行批量转录的脚本写法

验证结果和常见坑

跑完脚本后,先检查输出文件数量是否和输入一致:

ls transcripts/*.txt | wc -l
ls audio_files/*.mp3 | wc -l

数量一致不代表内容正确,建议随机挑两个音频,打开对应文本文件,听一段核对。如果音频很长,而转录文本明显短于音频时长,可能是 API 只处理了前几分钟,需要看 SoundWise 是否对单个音频有时长限制。另外,脚本里的 glob.glob("*.mp3") 只匹配该格式,如果目录里有 mp4 或 wav,要扩展扩展名列表,或者直接用 glob.glob(os.path.join(INPUT_DIR, "*")) 再用后缀过滤。

批量转录通常比较耗时间。如果文件数量大,先小批次跑,确认没有超时和配额问题。对于需要稳定产出的场景,建议给脚本加上断点续跑,也就是已经生成输出的文件跳过,这样中途失败后重跑不会从头再来。

SoundWise 用命令行批量转录的脚本写法

常见问题

转录中途失败,如何断点续跑?

脚本里已经用“检查输出文件是否存在”作为跳过条件。如果失败发生在写入之前,再次运行脚本会重新处理该文件;如果文件写了但内容不完整,需要手动删除该输出文件,或者改进脚本,写入成功后才生成输出。

音频文件很多,能否并行处理?

可以,但要控制并发量。参考 bash 方式,可以用 xargs -P 4 限制 4 个进程并行;Python 方式可以用 concurrent.futures 的 ThreadPoolExecutor 或 ProcessPoolExecutor。并发数不宜过高,避免触发服务端限流。建议先从 2 并发开始测试。