HiAPI
博客

教程

如何通过 HiAPI 调用 mirelo-sfx-2.0 API:curl、Python 与异步轮询

2026年11月3日
HiAPI 教程文章封面图:近黑底上薄荷绿半调点阵由疏至密铺展,深青点缀,构图克制均衡。

mirelo-sfx-2.0 的功能及适用场景

mirelo-sfx-2.0 是可通过 HiAPI 调用的文本转音效模型。你向它提供一段自然语言描述——例如“沉重的木门缓慢吱呀打开”或“硬币掉在大理石桌面上”——它就会生成一段与提示词匹配的短音频片段。

当你需要按需生成的音效设计、而非从采样库中授权获取时,这就是应当使用的端点:

  • 游戏与应用原型开发:为交互、UI 事件和环境循环生成占位或最终音效。
  • 视频与播客后期制作:无需预约录音棚,即可用拟音风格音频填补空白。
  • 生成式管线:从脚本、分镜或用户输入中获取提示词,并将生成的 WAV 附加到输出中。

当声音描述清晰且时长较短时,该模型表现最佳。如果你需要音乐、语音或长音频,那属于不同的模型系列——mirelo-sfx-2.0 专注于离散音效。

由于生成是异步的,请按基于任务的集成方式来规划,而不是阻塞式 HTTP 调用。本教程的其余部分将构建这一集成,从原始 curl 请求一直到轮询获取成品 WAV 的 Python 客户端。

前置条件与身份验证设置

在首次调用之前,请确保你已具备:

  • 一个 HiAPI 账号和 API 密钥。你可以在 HiAPI 控制台中创建和管理密钥。请像对待密码一样对待密钥:从环境变量或密钥管理器中加载,切勿将其提交到代码仓库。
  • 一个用于发送 HTTP 请求的工具。本演练使用 curl 即可;代码示例使用 Python 3.8+。
  • Python 中的 HTTP 客户端。示例为简洁起见使用 requests,但任何能发送 JSON 和请求头的客户端都可以。

HiAPI 对所有模型使用单一基础 URL 和单一身份验证方式,因此你在此学到的约定同样适用于其他端点:

export HIAPI_API_KEY="your-api-key-here"

每个请求都在 Authorization 请求头中发送密钥:

Authorization: Bearer $HIAPI_API_KEY
Content-Type: application/json

模型标识符在请求体中通过 "model": "mirelo-sfx-2.0" 传入。无需安装单独的 SDK——只要你的 HTTP 客户端能访问 HiAPI 基础 URL,就能调用该模型。

一条实用建议:将基础 URL 保存在配置变量中,而不是在各文件中硬编码。当你从本地脚本迁移到预发布或生产服务时,你会希望只在一个地方修改它。

curl 请求逐步解析

生成请求是向 HiAPI 任务创建端点发送的一次经过身份验证的 HTTP POST。以下是完整调用:

curl -sS -X POST "$HIAPI_BASE_URL/v1/tasks" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mirelo-sfx-2.0",
    "input": {
      "prompt": "heavy wooden door creaking open slowly, old house ambience"
    }
  }'

逐部分拆解:

  • -X POST——任务创建是写操作。对此路径使用 GET 不会启动任务。
  • URL——该端点接受新的生成任务。基础 URL 存放在 HIAPI_BASE_URL 中,因此同一命令可在任何环境中使用。
  • Authorization—— bearer 令牌标识你的账号,也是计费依据。请求头缺失或格式错误是 401 最常见的成因。
  • Content-Type: application/json——请求体是 JSON;没有此标头,服务器将拒绝或错误解析载荷。
  • model——选择 mirelo-sfx-2.0。由于 HiAPI 基于此字段进行路由,你可以在不更改 URL 的情况下切换模型。
  • input.prompt——声音的文本描述。具体、物理性的描述(材质、动作、环境)比抽象描述产生更好的结果。

成功提交不会返回音频。它会返回一个带有标识符(通常是 id 字段)的任务对象,你用它来检查状态。请从响应中捕获该 ID;它是你之后检索 WAV 的线索。

如果你想在接入代码之前确认请求结构,请先在终端运行这条确切命令。一旦成功,将其转换为 Python 就是机械性的工作。

Python 中的相同调用

Python 版本保持相同的 URL、请求头和请求体——只是将它们表示为字典和客户端调用:

import os
import requests

BASE_URL = os.environ["HIAPI_BASE_URL"]
API_KEY = os.environ["HIAPI_API_KEY"]

def create_sfx_task(prompt: str) -> str:
    response = requests.post(
        f"{BASE_URL}/v1/tasks",
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json",
        },
        json={
            "model": "mirelo-sfx-2.0",
            "input": {"prompt": prompt},
        },
        timeout=30,
    )
    response.raise_for_status()
    return response.json()["id"]

与 shell 版本的不同之处:

  • 环境访问——os.environ 取代 shell 展开,因此密钥永远不会出现在源代码中。
  • 用 json= 代替 -d——requests 会为你序列化字典并设置内容类型。你可以去掉手动请求头,不过保留也无妨。
  • raise_for_status()——将非 2xx 响应转为异常,错误处理应放在此处。
  • timeout——客户端超时可防止停滞的连接挂起你的工作进程。任务创建很快;长时间等待发生在轮询期间。

返回值是任务 ID。请存储它——它是你对该次生成的唯一句柄。至此 Python 路径和 curl 路径汇合:两者都需要轮询步骤,音频才会存在。

由于请求体只是数据,你可以参数化提示词,并遍历描述列表来批量生成音效,为每个提示词创建一个任务并收集 ID。

处理异步任务并轮询结果

声音生成需要时间——是秒级,而非毫秒级——因此 HiAPI 将其建模为任务。创建调用会立即返回一个 ID;第二个端点报告该任务仍在运行、已完成还是已失败。

典型循环是:

  1. 创建任务并捕获 ID。
  2. 用该 ID 轮询任务状态端点。
  3. 如果状态仍为处理中,短暂等待后再次轮询。
  4. 当状态报告成功时,从响应中读取输出。
  5. 如果状态报告失败,停止并抛出错误。

在 Python 中:

import time

def wait_for_task(task_id: str, timeout_s: int = 300) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        response = requests.get(
            f"{BASE_URL}/v1/tasks/{task_id}",
            headers={"Authorization": f"Bearer {API_KEY}"},
            timeout=30,
        )
        response.raise_for_status()
        task = response.json()

        status = task.get("status")
        if status == "succeeded":
            return task
        if status == "failed":
            raise RuntimeError(task.get("error", "task failed"))

        time.sleep(2)

    raise TimeoutError(f"task {task_id} did not finish in time")

有几点值得特别说明:

  • 轮询间隔。两秒是音效的合理默认值。紧凑循环轮询会浪费配额,还可能触发速率限制,却不会让结果来得更快。
  • 总体截止时间。始终为循环设定上限。卡住的任务应让你的作业失败,而不是永远挂起工作进程。
  • 状态值。将未知状态值视为“仍在处理”而非假设成功,并在成功和失败状态上显式分支。
  • Webhook(如果提供)。如果你的 HiAPI 账号支持完成回调,在服务器端生产代码中优先使用它们而非轮询;对于脚本和原型,轮询仍是最简单的选项。

请将任务 ID 与提示词一起保存在你自己的数据库中,以便之后重试、审计或重新获取输出,而无需重新生成。

读取返回的 WAV 响应

当任务报告成功时,响应包含生成的音频。取决于端点版本,输出可能以 WAV 文件 URL 或内联音频数据的形式出现;将两种情况都视为“可存储的字节”。

成功的任务对象在诸如 output 的字段下携带输出,通常还包含模型名称、原始提示词和时间信息等元数据。音频本身是标准的 WAV 容器,这意味着你可以将其交给任何音频库,无需自定义解码器。

要持久化基于 URL 的结果:

result = wait_for_task(task_id)
audio_url = result["output"]["audio_url"]

wav_bytes = requests.get(audio_url, timeout=60).content
with open(f"{task_id}.wav", "wb") as f:
    f.write(wav_bytes)

如果音频以解码数据形式到达,则在写入前进行 base64 解码:

import base64

wav_bytes = base64.b64decode(result["output"]["audio_base64"])
with open(f"{task_id}.wav", "wb") as f:
    f.write(wav_bytes)

拿到字节后:

  • 验证文件头。WAV 文件以 RIFF 魔数开头。检查前四个字节可在截断下载到达存储之前将其捕获。
  • 持久存储。写入对象存储,并将键与任务 ID 一起保存在数据库中。将生成的音频视为可缓存的产物,而非临时响应。
  • 播放或处理。标准工具——wave、soundfile 或任何音频播放器——可直接打开该文件。然后你可以裁剪静音、归一化响度或转换为其他格式用于交付。

由于文件是普通 WAV,将其接入 Web 端点或游戏引擎资产管线无需特殊处理。

常见故障点及修复方法

大多数集成问题可归入几个可预测的类别。

身份验证错误(401 / 403)

401 几乎总是意味着 Authorization 请求头缺失、格式错误或由空环境变量构建。请确认 HIAPI_API_KEY 在进程运行的 shell 中已导出——而不仅在编辑器中——并且请求头读作 Bearer <key>,中间只有一个空格。403 通常意味着密钥有效但无权访问该模型;请检查你账号的模型权限。

格式错误的载荷(400 / 422)

最常见的原因是请求体不是有效 JSON——curl 命令中引号不配对是典型例子。发送前用 JSON 检查器验证。第二常见原因是缺少 model 字段或提示词嵌套层级错误;模型期望 input.prompt,而非顶层 prompt。最后,检查提示词非空且长度在模型文档规定的限制内。

轮询过于频繁

没有休眠的紧凑 while 循环会产生大量状态请求,可能触发速率限制,并让你正在等待的任务变慢。使用一到两秒的固定间隔,并行运行多个作业时加入抖动,并始终强制执行最大等待时间。

将创建视为完成

创建响应看起来像成功并返回 200,但不包含音频。如果你的代码立即读取 output 字段,它将失败或写入空文件。在接触结果之前,始终通过状态端点。

静默超时与重试

任务创建时的网络超时重试是安全的,但在一次实际已成功的超时之后重试创建调用会产生重复作业。如果端点支持幂等键,请使用它们;否则在重试前列出最近任务进行核对。

磁盘与存储边缘情况

写入 WAV 字节时,以二进制模式("wb")打开文件。文本模式会损坏文件头。如果你按提示词名称存储输出,两个相同提示词的任务会互相覆盖——请按任务 ID 作为文件键。

有了这些防护措施,mirelo-sfx-2.0 集成就是一条短管线:创建、轮询、持久化。从 curl 调用开始,移植到 Python,并将任务 ID 作为你的真相来源。

立即开始构建持久 AI 产物

获取 API 密钥,通过一个基于任务(task)的 API 调用图像、视频和音频模型。

阅读 API 文档