请先查看接入必读了解具体接入方式,再参考此文档完成接入。
VoiceConversion
为用户提供声音转换能力,可以实现输入一条语音,在保持说话内容不变的情况下,转换音色为指定角色。
当前支持通过 HTTP 协议在线调用
请求内容包括:
payload
字段为将请求参数序列化后的json文本data
字段为将音频二进制文件按照base64格式编码(标准base64,RFC 4648)的文本使用备注:
注意项 | 说明 | |
---|---|---|
功能 | 限制说明 | 避免直接拼接json文本,尽量使用转换库,避免造成转义符等导致json格式错误 |
输入 | 音频格式支持 | wav、pcm、mp3、aac等常见格式 |
音频编码建议 | 采样率大于等于16kHz,单通道,否则将进行自动转码,可能带来效果损失和更多耗时处理 | |
音频时长限制 | 小于等于10分钟;建议大于1s,否则会影响算法效果 | |
音频大小限制 | 小于等于100MB | |
输出 | 结果格式 | 默认输出24kHz,单通道wav格式音频。支持用户通过请求参数配置 |
参考详细说明功能调用-通用协议
payload
配置参数为json字符串格式
字段 | 描述 | 类型 | 是否必传 | 默认值 |
---|---|---|---|---|
speaker | 发音人,具体见附录:发音人列表 | string | 是 | - |
url | 服务请求数据的url,若data字段为空,则使用该url下载音频数据。详见功能调用-通用协议-payload.url | string | 否 | - |
enable_background | 对于返回的音频,是否携带原音频中的背景音 | bool | 否 | false |
audio_config | 补充参数 | object | 否 | - |
audio_config.format | 输出音频编码格式,wav/mp3/aac | string | 否 | wav |
audio_config.sample_rate | 输出音频采样率,8000/16000/22050/24000/32000/44100/48000 | number | 否 | 24000 |
audio_config.channel | 输出音频通道数 1/2 | number | 否 | 1 |
HTTP响应Content-Type: application/json
字段 | 描述 | 类型 |
---|---|---|
task_id | 请求任务id,用于链路追踪、问题排查 | string |
namespace | 服务接口命名空间,比如VoiceConversion | string |
data | 请求响应二进制数据,标准base64编码 | string |
payload | 请求响应文本信息,json字符串格式 | string |
status_code | 状态码 | number |
status_text | 状态信息 | string |
调用方式为:POST /api/v1/invoke
// Code sample:
// use http client to invoke SAMI HTTP Service
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)
type InvokeResponse struct {
StatusCode int32 `form:"status_code,required" json:"status_code,required" query:"status_code,required"`
StatusText string `form:"status_text,required" json:"status_text,required" query:"status_text,required"`
TaskId string `form:"task_id,required" json:"task_id,required" query:"task_id,required"`
Namespace string `form:"namespace,required" json:"namespace,required" query:"namespace,required"`
Payload *string `form:"payload,omitempty" json:"payload,omitempty" query:"payload,omitempty"`
Data []byte `form:"data,omitempty" json:"data,omitempty" query:"data,omitempty"`
State *string `form:"state,omitempty" json:"state,omitempty" query:"state,omitempty"`
}
const (
domain = "https://sami.bytedance.com"
// auth token
appkey = "your_appkey"
// SAMI method
version = "v4"
namespace = "VoiceConversion"
// dump output
dataOutputFile = "output.wav"
payloadOutputFile = "output.json"
isDump = true
)
func main() {
// Get token
token := "your_token"
// Construct HTTP request
// 1. Read local audio file
// 2. Set HTTP json body
// 3. Do HTTP POST request
audioPath := "/path/to/audio"
content, err := ioutil.ReadFile(audioPath)
if err != nil {
log.Fatalf("failed to read file: %v", err)
}
data := base64.StdEncoding.EncodeToString(content)
body := fmt.Sprintf(`{"data": "%v","payload":"{\"speaker\":\"zh_female_qingxin\"}"}`, data)
urlPath := fmt.Sprintf(
"%v/api/v1/invoke?version=%v&token=%v&appkey=%v&namespace=%v",
domain, version, token, appkey, namespace,
)
log.Printf("invoke request: %v", urlPath)
// HTTP POST request
start := time.Now()
resp, err := http.Post(urlPath, "application/json", bytes.NewBuffer([]byte(body)))
if err != nil {
panic(err)
}
defer resp.Body.Close()
// Parse HTTP response
ret, err := ioutil.ReadAll(resp.Body)
if err != nil || resp.StatusCode != http.StatusOK {
panic(string(ret))
}
log.Printf("http invoke: cost=%vms", time.Since(start).Milliseconds())
// parse SAMI response
samiResp := InvokeResponse{}
payloadStr := ""
if err = json.Unmarshal(ret, &samiResp); err != nil {
log.Println("parse response failed", string(ret), err)
panic(err)
}
if samiResp.Payload != nil {
payloadStr = *samiResp.Payload
}
log.Printf("response task_id=%v, payload=%v, data=[%d]byte", samiResp.TaskId, payloadStr, len(samiResp.Data))
if isDump && samiResp.Payload != nil {
_ = ioutil.WriteFile(payloadOutputFile, []byte(*samiResp.Payload), 0644)
}
if isDump && len(samiResp.Data) > 0 {
_ = ioutil.WriteFile(dataOutputFile, samiResp.Data, 0644)
}
}
HTTP状态码 | 业务状态码 | 错误信息 | 错误说明 | 解决办法 |
---|---|---|---|---|
400 | 40000022 | IllegalPayload:InvalidSpeaker | 发音人设置无效 | 检查发音人是否正确设置 |
备注:当前仅上线中文发音人,其他语种敬请期待。
场景 | 音色 | 性别 | 调用参数speaker |
---|---|---|---|
通用 | 清新女声 | 女 | zh_female_qingxin |
醇厚男声 | 男 | zh_male_chunhou | |
童年伙伴(可爱男孩) | 男 | zh_male_xiaohai | |
温柔男声(活力男声) | 男 | zh_male_huoli | |
甜美女声 | 女 | zh_female_tianmei | |
四郎 | 男 | zh_male_silang | |
方言趣味 | 嘻哈歌手 | 男 | zh_male_rap |
四川女声 | 女 | zh_female_sichuan | |
萌丫头 | 女 | zh_female_mengyatou | |
顾姐 | 女 | zh_female_guli | |
熊二 | 男 | zh_male_xionger | |
林黛玉 | 女 | zh_female_lindaiyu | |
TVB女声 | 女 | zh_female_tvb | |
猴哥 | 男 | zh_male_sunwukong | |
广告/短视频 | 磁性解说男声 | 男 | zh_male_commentate |
超自然 | 邻家女孩 | 女 | zh_female_xiaoqian |
开朗男声 | 男 | zh_male_xiaojian | |
教育/陪伴 | 小孩 | 男 | zh_female_xiaopengyou |
场景 | 音色 | 性别 | 调用参数speaker |
---|---|---|---|
通用 | 美英男声-Cupid | 男 | en_male_cupid |