跳至主要內容

開發者

Hushscript SDK 與命令列工具

支援 TypeScript、Python、Go 與 PHP 的官方程式庫,以及一個命令列工具,一次呼叫就能把錄音檔變成逐字稿。

官方 SDK 為伺服器程式碼與腳本封裝了 REST API。一次呼叫即可轉錄一個檔案:它會上傳錄音、等待工作完成,並交回逐字稿。過程中,SDK 會在暫扣任何分鐘數之前先檢查檔案,重試可以安全重試的請求,讓長時間的上傳保持連線,並在每次上傳與購買時附上冪等金鑰,因此重試絕不會重複扣款。命令列工具建立在 TypeScript SDK 之上,可在終端機中做同樣的事。

套件

語言 套件 套件庫 原始碼
TypeScript @hushscript/sdk npm: www.npmjs.com/package/@hushscript/sdk github.com/Hushscript/hushscript-sdk-typescript
Python hushscript PyPI: pypi.org/project/hushscript github.com/Hushscript/hushscript-sdk-python
Go github.com/Hushscript/hushscript-sdk-go pkg.go.dev: pkg.go.dev/github.com/Hushscript/hushscript-sdk-go github.com/Hushscript/hushscript-sdk-go
PHP hushscript/sdk Packagist: packagist.org/packages/hushscript/sdk github.com/Hushscript/hushscript-sdk-php
CLI @hushscript/cli npm: www.npmjs.com/package/@hushscript/cli github.com/Hushscript/hushscript-cli

執行環境最低版本:

這些 SDK 供伺服器與腳本使用。API 不接受瀏覽器來源,而放進瀏覽器套件的權杖就等於外洩的權杖,因此 TypeScript SDK 在存在 window 與 document 的環境中會拒絕啟動。

取得權杖

每個 SDK 與命令列工具都以個人存取權杖驗證身分。請在帳戶中的 MCP 頁面的 建立新的權杖 區段建立權杖,選擇程式碼所需的權限範圍,並決定它是否可以購買分鐘數。權杖只會顯示一次,格式為 hsr1:<region>:pat.<id>.<secret>。權限範圍與權杖的運作方式請見 API 頁面。

未傳入權杖時,SDK 會從 HUSHSCRIPT_TOKEN 讀取:

export HUSHSCRIPT_TOKEN=hsr1:...

代理程式也可以自行開設帳戶、在託管的結帳頁面完成付款,並以程式碼領取第一個權杖:TypeScript 使用 Hushscript.agent.signup() 與 Hushscript.agent.claim(),Python 使用 Hushscript.agent_signup() 與 Hushscript.agent_claim(),Go 使用 AgentSignup 與 AgentClaim,PHP 使用 Client::agentSignup() 與 Client::agentClaim()。流程與規則請見自動化使用。

TypeScript

npm install @hushscript/sdk
import { writeFile } from "node:fs/promises";
import { Hushscript } from "@hushscript/sdk";

const hs = new Hushscript(); // reads HUSHSCRIPT_TOKEN
const transcript = await hs.transcribe("meeting.mp3");
console.log(transcript.text);
await writeFile("meeting.srt", transcript.toSRT());

transcribe() 接受路徑、Blob、Uint8Array 或 ReadableStream<Uint8Array>。串流必須提供確切的 size 與 durationSeconds。hs.balance() 回傳您可使用的分鐘數,hs.transcripts.list() 分頁列出已完成的逐字稿,hs.buy("300min", { acknowledgeNoRefund: true }) 則購買一個套餐。每個 /v1 操作也都可透過 hs.api 使用,並具備相同的重試、逾時與遮蔽處理。

Python

pip install hushscript
from pathlib import Path

from hushscript import Hushscript

with Hushscript() as hs:  # reads HUSHSCRIPT_TOKEN
    transcript = hs.transcribe("meeting.mp3")
    print(transcript.text)
    Path("meeting.srt").write_text(transcript.to_srt(), encoding="utf-8")

每個呼叫在 AsyncHushscript 上都有同名的 asyncio 版本。transcribe() 接受路徑、bytes 或二進位檔案物件;無法 seek 的檔案物件需要提供 size 與 duration_seconds。hs.balance()、hs.transcripts.list() 與 hs.buy("300min", acknowledge_no_refund=True) 分別負責查詢餘額、列出逐字稿與購買套餐。

Go

go get github.com/Hushscript/hushscript-sdk-go
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	hushscript "github.com/Hushscript/hushscript-sdk-go"
)

func main() {
	client, err := hushscript.New() // reads HUSHSCRIPT_TOKEN
	if err != nil {
		log.Fatal(err)
	}
	transcript, err := client.Transcribe(context.Background(), "meeting.mp3", nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(transcript.Text(nil))
	if err := os.WriteFile("meeting.srt", []byte(transcript.SRT(nil)), 0o600); err != nil {
		log.Fatal(err)
	}
}

Transcribe 接受路徑,TranscribeReader 接受 io.ReaderAt 及其確切大小,TranscribeStream 則接受只能向前讀取的 reader,並搭配其大小與 DurationSeconds。client.Balance、client.Transcripts.List 與 client.Buy 分別負責查詢餘額、列出逐字稿與購買套餐。可以是關閉、開啟或未設定的選項為 *bool,以 hushscript.Bool 建立。

PHP

composer require hushscript/sdk
<?php

require __DIR__ . '/vendor/autoload.php';

use Hushscript\Client;

$hs = new Client(); // reads HUSHSCRIPT_TOKEN

$transcript = $hs->transcribe('meeting.mp3');
echo $transcript->text();
file_put_contents('meeting.srt', $transcript->toSrt());

transcribe() 接受路徑或已開啟的串流;無法 seek 的串流需要 size 與 duration_seconds 選項。選項使用 snake_case 陣列鍵,結果則使用 camelCase 屬性。$hs->balance()、$hs->transcripts()->list() 與 $hs->buy('300min', true) 分別負責查詢餘額、列出逐字稿與購買套餐。在 Laravel 中,請在 service provider 裡綁定一個 Client,並在佇列工作中執行轉錄,同時設定固定的 idempotency_key 選項。

CLI

npm install --global @hushscript/cli
hushscript login
hushscript transcribe meeting.mp3 --format srt --out meeting.srt

命令列工具依序從 --token、HUSHSCRIPT_TOKEN,以及 hushscript login 儲存的權杖取得權杖。login 會在不回顯的情況下詢問權杖,並將它存放在只有您的使用者帳號能讀取的檔案中;hushscript logout 會將其刪除。在 CI 中,建議使用環境變數。

指令 功能
login 提示輸入權杖並儲存。
logout 刪除已儲存的權杖。
balance 顯示您可使用的分鐘數。
transcribe <file> 上傳錄音、等待並印出逐字稿。旗標:--language、--translate、--format srt|vtt|txt|json、--out、--key。
resume <token> <file> 完成 transcribe 中途遺留的轉錄。
transcripts 列出已完成的逐字稿,最新的在前。
transcript <id> 印出一份逐字稿。
jobs 列出工作;--active 只列出尚未完成的工作。
packs 列出可購買的分鐘套餐及價格。
buy <pack> 以您儲存的預設卡片購買一個套餐。旗標:--yes、--key。

--json 只在 stdout 輸出一份 JSON 文件,不輸出其他內容,並讓 stderr 改為 JSON Lines。結束代碼 0 表示成功,1 表示 API 或 SDK 回報了錯誤,2 表示用法錯誤(未送出任何內容),130 表示執行被中斷。

支援的檔案

MP3、M4A、MP4 與 MOV(使用影片的音軌)、WAV、FLAC,以及採用 Vorbis 或 Opus 的 OGG,長度從 15 秒到 10 小時。SDK 會根據檔案的位元組檢查格式,並在暫扣任何分鐘數之前探測時長。它們不轉換媒體,因此其他格式請先自行轉換:

ffmpeg -i input -vn -c:a libopus output.opus

錯誤

SDK 拋出的每個錯誤都屬於同一個家族,所以一個 catch 就能涵蓋全部:TypeScript 與 Python 為 HushscriptError,Go 為 *hushscript.Error,PHP 為 HushscriptException。錯誤包含 slug 形式的 code(例如 insufficient_balance)、數字代碼、HTTP 狀態、訊息、說明下一步該怎麼做的 hint、詳細資料,以及 retryAfter(PHP 中的 slug 為 errorCode,Python 中的 retryAfter 為 retry_after)。

import { HushscriptError, InsufficientBalanceError } from "@hushscript/sdk";

try {
  await hs.transcribe("meeting.mp3");
} catch (error) {
  if (error instanceof InsufficientBalanceError) console.log(error.hint);
  else if (error instanceof HushscriptError) console.log(error.code, error.hint ?? error.message);
  else throw error;
}

PreflightError 表示 SDK 在暫扣任何額度之前就拒絕了該檔案。餘額是否足以支付某個檔案由伺服器判定:建立上傳時會回傳 402,此時尚未送出任何分段。

扣款與重試

每次上傳與每次購買都帶有冪等金鑰,而重試會沿用同一把金鑰,因此重試的呼叫會重現第一次的結果,而不是另起一次。

buy() 會向您儲存的預設卡片扣款。要從程式碼購買,必須三個開關都允許:權杖具有 billing 權限範圍、權杖已開啟「允許此權杖購買分鐘數」,且帳戶已開啟「允許已連接的應用程式購買分鐘數」。缺少任何一項,呼叫都會以 pat_scope_missing 失敗。呼叫前,請先向您的買家顯示不退款聲明。

購買最多重試一次,只在網路錯誤、502 或 503 時進行,並使用相同的金鑰。有些回應可以證明未曾扣款:400、402、404 或 422,以及代碼為 4021(pat_purchase_requires_app,卡片被拒或需要您親自操作才能扣款)或 4023(pat_purchase_requires_authentication,銀行要求確認付款)的 403。遇到 4021 或 4023 時,請在應用程式中購買套餐。請求送出後發生的任何其他失敗,包括 401 或 429,都表示卡片可能已被扣款。該錯誤會帶有冪等金鑰:使用同一把金鑰再次請求,購買就絕不會發生兩次。以 Python 為例:

from hushscript import HushscriptError

try:
    purchase = hs.buy("300min", acknowledge_no_refund=True)
except HushscriptError as error:
    refused = error.status in {400, 402, 404, 422} or (
        error.status == 403 and error.numeric_code in {4021, 4023}
    )
    if error.idempotency_key is None or refused:
        raise  # only these refusals charged nothing; any other failure keeps the key for a retry
    purchase = hs.buy("300min", acknowledge_no_refund=True, idempotency_key=error.idempotency_key)

請求送出之前就失敗的購買不帶金鑰:表示沒有扣款。您自行傳入的金鑰長度必須為 1 到 128 個字元,字元取自 A-Za-z0-9_-;請勿將同一把金鑰用於不同的套餐。購買請求可能已送出時,命令列工具會印出該金鑰:

hushscript buy 300min --yes --key <key>

恢復權杖

工作一旦建立,錯誤就會在冪等金鑰旁帶有一個恢復權杖。等待逾時會拋出帶有該權杖的 WaitTimeoutError,而工作會繼續執行。把權杖傳回 resume() 即可繼續,不會再次扣款:已過上傳階段的工作不需要檔案,仍在上傳的工作則以同一個檔案接續。以 PHP 為例:

try {
    $hs->transcribe($path, ['wait_timeout' => 60]);
} catch (\Hushscript\Exception\WaitTimeoutError $timeout) {
    $transcript = $hs->resume($timeout->resumeToken, $path);
}

在命令列工具中,於 transcribe 期間按 Ctrl-C 會印出該工作的恢復權杖,以及接續它的指令:

hushscript resume <token> meeting.mp3 --format srt --out meeting.srt

記錄與遮蔽

SDK 不傳送任何遙測資料;User-Agent 標頭是唯一的用戶端識別。記錄預設為關閉。HUSHSCRIPT_LOG=debug 會對每個請求在標準錯誤輸出一行,內容為方法、路徑、狀態與耗時,絕不包含標頭、內文、標題或逐字稿文字。

權杖會從每一則錯誤、每一行記錄,以及用戶端的每一種列印形式中遮蔽。在錯誤訊息、提示與成因中,網址會保留主機與路徑,但查詢字串會變成 ?[redacted],因此簽署過的上傳網址絕不會被印出。會交給您密鑰的結果,例如認領密鑰或新的權杖,作為欄位時仍可讀取,但列印時會顯示 [redacted];JSON 匯出屬於您自己的資料,會帶有該值。命令列工具會從 stderr 清除它所知的每一個權杖;其 stdout 上的結果是您的輸出,不會被清除。

設定

設定 環境變數 預設值
權杖 HUSHSCRIPT_TOKEN 無
基礎網址 HUSHSCRIPT_BASE_URL https://api.hushscript.com
記錄層級 HUSHSCRIPT_LOG off
請求逾時 無 60 秒
重試次數 無 3

在程式碼中傳入的選項優先於對應的環境變數,空值視為未設定。分鐘數與應用程式使用同一份餘額;套餐與價格請見定價頁面。

開始轉成逐字稿––30 分鐘試用

建立帳戶前即可預覽最長 5 分鐘,新的個人帳戶還可在應用程式中免費預覽首次上傳的檔案。完整轉錄需要帳戶及分鐘數;符合資格的個人帳戶可獲得一次 30 分鐘免費額度,於信用卡驗證後或首次購買時發放。無訂閱。

開始––30 分鐘免費