请先查看接入必读了解具体接入方式,再参考此文档完成接入。
MusicTagging 为用户提供音乐标签分类能力,通过曲风、情绪、场景、语言、二级曲风5个维度分析音乐,自动生成各维度下的分类标签以及对应概率值。
当前支持通过 HTTP 协议在线调用
请求内容包括:
payload字段为将请求参数序列化后的json文本data字段为将音频二进制文件按照base64格式编码(标准base64,RFC 4648)的文本使用备注:
| 注意项 | 说明 | |
|---|---|---|
功能 | 限制说明 |
|
| 输入 | 音频格式支持 | wav、pcm、mp3、aac等常见格式 |
| 音频编码建议 | 采样率大于等于16kHz,否则将进行自动转码,可能带来效果损失和更多耗时处理 | |
| 音频时长限制 | 小于等于10分钟;建议大于5s,否则会影响算法效果 | |
| 音频大小限制 | 小于等于100MB | |
| 输出 | 结果格式 | 详情请参考响应格式 |
参考详细说明功能调用-通用协议
payload配置参数为json字符串格式
| 字段 | 描述 | 类型 | 是否必传 | 默认值 |
|---|---|---|---|---|
| url | 服务请求数据的url,若data字段为空,则使用该url下载音频数据。详见功能调用-通用协议-payload.url | string | 否 | - |
| audio_info | 音频参数,便于服务节省音频解码耗时 | object | 否 | - |
| audio_info.format | 音频编码格式,wav/mp3/aac | string | 否 | - |
| audio_info.sample_rate | 音频采样率 | number | 否 | - |
| audio_info.channel | 音频通道数 | number | 否 | - |
| extra | 补充参数 | object | 否 | - |
| extra.enable_tag | 是否返回标签信息 | bool | 否 | true |
| extra.enable_embed | 是否返回embedding信息 | bool | 否 | false |
| extra.top_num | 设置每个分组返回的最大标签数量,默认全部返回 | number | 否 | 1 |
HTTP响应Content-Type: application/json
| 字段 | 描述 | 类型 |
|---|---|---|
| task_id | 请求任务id,用于链路追踪、问题排查 | string |
| namespace | 服务接口命名空间,比如MusicTagging | string |
| data | 请求响应二进制数据,标准base64编码 | string |
| payload | 请求响应文本信息,json字符串格式 | string |
| status_code | 状态码 | number |
| status_text | 状态信息 | string |
| 字段 | 描述 | 类型 |
|---|---|---|
| pred | 标签预测概率值,取值范围:[0, 1.0] | array |
| embed | optional,标签维度embedding,可用于其他模型输入 | array |
| task_flow | 任务流响应结果 | object |
| task_flow.result | 子任务响应结果数组 | array |
| task_flow.result.task_type | 子任务类型 | string |
| task_flow.result.pred_dim | 子任务响应结果中预测概率值的维度 | number |
| task_flow.result.embed_dim | 子任务响应结果中embedding的维度 | number |
| task_flow.result.task_output | 子任务响应结果的其他附加信息 | object |
| task_flow.result.task_output.tags | 子任务响应结果的标签附加信息 | array |
payload示例:
{ "pred": [0.09001981,0.05727265,...,0.14518361], "task_flow": { "result": [ { "task_type": "MusicTaggingMood", "pred_dim": 6, "task_output": { "tags": [ "sorrow", "chill", "excited", "happy", "angry", "romantic" ] } }, { "task_type": "MusicTaggingTheme", "pred_dim": 14, "task_output": { "tags": [ "kadian", "DIY", "family", "sound_effect", "campus", "ACG", "game", "pet", "Beauty_fashion", "travel", "Chinese_Style", "cool", "dancale", "vlog" ] } } ] } }
调用方式为: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 = "MusicTagging" // 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":"{\"task_flow\":{\"type\":\"merge\",\"task\":`+ `[{\"task_type\":\"MusicTaggingGenre17\"},{\"task_type\":\"MusicTaggingMood10\"},`+ `{\"task_type\":\"MusicTaggingTheme24\"},{\"task_type\":\"MusicTaggingLang24\"},`+ `{\"task_type\":\"MusicTaggingVocal\"},{\"task_type\":\"MusicTaggingMTT\"}]},`+ `\"extra\":{\"use_tag\":false}}"}`, 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, response: %v", time.Since(start).Milliseconds(), string(ret)) // 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) } }
| 标签模型 | 维度 | 标签字段 | 标签含义 |
|---|---|---|---|
| MusicTaggingVocal | 2 | vocal | 声乐 |
| non_vocal | 纯音乐 | ||
| MusicTaggingMood10 | 10 | cute | 可爱 |
| dynamic | 动感 | ||
| tense | 紧张 | ||
| weird | 诡异 | ||
| sorrow | 悲伤 | ||
| chill | 宁静 | ||
| excited | 兴奋 | ||
| happy | 喜悦 | ||
| angry | 气愤 | ||
| romantic | 浪漫 | ||
| MusicTaggingGenre34 | 34 | pop | 流行 |
| rock | 摇滚 | ||
| electronic | 电子音乐 | ||
| hiphop_rap | 嘻哈 | ||
| reggae | 雷鬼 | ||
| mb_soul | / | ||
| Metal | 金属 | ||
| Jazz | 爵士 | ||
| Blues | 布鲁斯 | ||
| Country | 乡村 | ||
| Folk | 民谣 | ||
| Indie | 独立音乐 | ||
| K_pop | 韩国流行 | ||
| Indie_Pop | 独立流行 | ||
| Muslim | 穆斯林音乐 | ||
| Indo_Christian | 印度基督教音乐 | ||
| Bollywood | 宝莱坞音乐 | ||
| Bollywood_Retro | 宝莱坞音乐 | ||
| Urban_Punjabi_Pop | 都市旁遮普流行 | ||
| Tamil_Film_Music | 泰米尔电影音乐 | ||
| Kannada_Film_Music | 卡纳达电影音乐 | ||
| Telugu_Film_Music | 泰卢固电影音乐 | ||
| Indian_Independent | 印度独立音乐 | ||
| Malayalam_Film_Music | 马拉雅拉姆电影音乐 | ||
| Sertanejo | 巴西乡村音乐 | ||
| Baile_Funk | 舞蹈放克音乐 | ||
| Gospel | 福音 | ||
| Samba | 桑巴 | ||
| Pagode | 巴西舞曲 | ||
| MPB | 巴西全域音乐 | ||
| Forro | 巴西Forró | ||
| Axe | 巴西Axé | ||
| Reggaeton | 说唱音乐和加勒比风格 | ||
| Brazilian_Punk | 巴西朋克 | ||
| MusicTaggingTheme24 | 24 | kadian | 卡点 |
| DIY | DIY | ||
| family | 家庭 | ||
| sound_effect | 音效 | ||
| campus | 校园 | ||
| ACG | 二次元 | ||
| game | 游戏 | ||
| pet | 宠物 | ||
| Beauty_fashion | 美妆 | ||
| travel | 旅行 | ||
| Chinese_Style | 中国风 | ||
| cool | 潮酷 | ||
| disco_dance | 迪斯科 | ||
| vlog | Vlog | ||
| dance | 舞蹈 | ||
| dj | DJ | ||
| food | 美食 | ||
| love | 爱情 | ||
| rainy | 雨 | ||
| sport | 运动 | ||
| spring | 春 | ||
| summer | 夏 | ||
| sunny | 阳光 | ||
| funny | 搞笑 | ||
| MusicTaggingLang30 | 30 | en | 英文 |
| es | 西班牙语 | ||
| fr | 法语 | ||
| pt | 葡萄牙语 | ||
| it | 意大利语 | ||
| de | 德语 | ||
| cmn | 普通话 | ||
| id | 印尼语 | ||
| ja | 日语 | ||
| hi | 印地语 | ||
| pa | Punjabi (印度方言) | ||
| tl | Tagalog (他加禄语) | ||
| ru | 俄语 | ||
| tr | 土耳其语 | ||
| ms | 马来语 | ||
| th | 泰语 | ||
| ko | 韩语 | ||
| pl | 波兰语 | ||
| ar | 阿拉伯语 | ||
| ta | Tamil (泰米尔语) | ||
| te | Telugu(泰卢固语) | ||
| ml | Malayalam (马拉雅拉姆语) | ||
| kn | Kannada (卡纳达语) | ||
| bn | Bengali (孟加拉语) | ||
| gu | Gujarati (古吉拉特语) | ||
| mr | Marathi(马拉地语) | ||
| bho | Bhopal (博帕尔) | ||
| yue | 粤语 | ||
| minnan | 闽南语 | ||
| other | 其他 |