@surfmate.team/digital-human-minimax
v0.2.0
Published
MiniMax adapter implementing digital-human-ports' VoiceSynthesisPort (cloud TTS, direct or via a key-holding proxy) and VoiceCloningPort (sample → voiceId). Holds no API key in proxy mode.
Readme
@surfmate.team/digital-human-minimax
MiniMax adapters for the digital-human suite — they implement the ports from
@surfmate.team/digital-human-ports:
VoiceSynthesisPort— cloud TTS (t2a_v2), via a key-holding proxy (secure) or browser-direct (dev, key exposed).VoiceCloningPort— sample → clonedvoiceId(upload →voice_clone→ use), plus list / delete.
npm i @surfmate.team/digital-human-minimaxTTS
import { createMinimaxSynthAdapter } from '@surfmate.team/digital-human-minimax'
// Secure: a proxy holds the key server-side and returns mp3 bytes.
const synth = createMinimaxSynthAdapter({ endpoint: import.meta.env.VITE_TTS_PROXY_URL })
const bytes = await synth.synthesize({
text: '你好',
voiceId: 'minimax:male-qn-jingying',
modelId: 'speech-02-hd', // optional
emotion: 'sad', // optional
})
// Dev only (key in the browser):
// createMinimaxSynthAdapter({ apiKey, groupId, host })createMinimaxSynthAdapter(config)
config is one of:
| Mode | Shape | Notes |
| --- | --- | --- |
| proxy (secure) | { endpoint } | POSTs { text, voiceId, model, emotion }; the proxy adds the key and returns mp3 bytes. The key never reaches the browser. |
| direct (dev) | { apiKey, groupId, host? } | Calls MiniMax t2a_v2 from the caller. ⚠️ key ships in the bundle — dev only. host defaults to api.minimax.io. |
Returns a VoiceSynthesisPort: synthesize(input) · playUrl(url) ·
playBytes(bytes) · stop().
synthesize(input) — VoiceSynthesisInput
| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| text | string | ✅ | What to speak. |
| voiceId | string | ✅ | minimax:<id> — a preset (minimax:male-qn-jingying) or a cloned id (minimax:surf…). The minimax: prefix is stripped before the API call. |
| modelId | string | — | Only speech-02-hd or speech-02-turbo are honored. Anything else (or omitted) → speech-02-turbo. |
| emotion | string | — | Only angry / sad / fearful / disgusted / surprised / neutral are honored. happy → neutral (it shifts the timbre); any other / omitted → no emotion sent. |
Returns Promise<ArrayBuffer> (mp3 bytes) — cache them and replay via playBytes.
The
modelId/emotionwhitelists are deliberate: a stale or foreign value (e.g. a mate-importedexpressivemodel) is coerced instead of 502-ing the call.
Voice cloning (browser-direct, dev)
import { createMinimaxVoiceCloning } from '@surfmate.team/digital-human-minimax'
const cloning = createMinimaxVoiceCloning({ apiKey, groupId })
const { voiceId } = await cloning.cloneFromSample(file) // 'minimax:surf…'
const mine = await cloning.listClones() // hides foreign/malformed idsfrom-env helpers: createMinimaxSynth(env) / createMinimaxCloning(env) pick
proxy-vs-direct from loose env config.
License
MIT
