You need to enable JavaScript to run this app.
导航
接口说明
最近更新时间:2024.05.28 11:17:46首次发布时间:2021.08.23 16:15:12

接入必读

请先查看接入必读了解具体接入方式,再参考此文档完成接入。

功能介绍

MIDI 为用户提供音乐转谱提取能力,将输入的音频进行分析提取、导出MIDI格式音乐,包含音乐的音符、力度、时长等信息。

  • 输入:一段音乐音频
  • 输出:MIDI格式音乐

接口说明

  • 当前支持通过 HTTP 协议在线调用。
  • 请求包括:
    • payload字段为将请求参数序列化后的json文本
    • data字段为将音频二进制文件按照base64格式编码(标准base64,RFC 4648)的文本
  • 使用备注:
注意项说明

功能

限制说明

  • 不支持纯音乐、rap,否则会返回错误码status_code=40000010
  • 音乐转谱API最大超时时间为120秒
  • 入参避免直接拼接json文本,尽量使用转换库,避免转义符号导致的json格式错误
输入音频格式支持wav、mp3、aac等常见格式
音频编码建议采样率大于等于16kHz,否则将进行自动转码,可能带来效果损失和更多耗时处理
音频时长限制小于等于10分钟;建议大于5s,否则会影响算法效果
音频大小限制小于等于100MB
输出结果格式详情请参考响应格式

公共参数

参考详细说明功能调用-通用协议

配置参数

payload配置参数为json字符串格式

字段描述类型是否必传默认值
url服务请求数据的url,若data字段为空,则使用该url下载音频数据。详见功能调用-通用协议-payload.urlstring-
audio_info音频参数,便于服务节省音频解码耗时object-
audio_info.format音频编码格式,wav/mp3/aacstring-
audio_info.sample_rate音频采样率number-
audio_info.channel音频通道数number-
extra补充参数object-
extra.midi是否以MIDI格式二进制数据格式返回,若为false则返回json格式结果booltrue

响应格式

HTTP响应Content-Type: application/json

字段描述类型
task_id请求任务id,用于链路追踪、问题排查string
namespace服务接口命名空间,比如MIDIstring
data请求响应二进制数据,标准base64编码string
payload请求响应文本信息,json字符串格式string
status_code状态码number
status_text状态信息string
  • 响应结果格式由入参extra.midi决定:

    • extra.midi=true,MIDI检测结果在data字段,为MIDI格式的二进制数据,标准base64编码
    • extra.midi=false,MIDI检测结果在payload字段中,payload为json字符串格式,json内容格式如下:

    按照时间先后顺序列出了所有的人声MIDI时间段,其中pitch为对应时间段的人声音高,velocity为人声的力度(音量)

    字段描述类型
    midiList包含人声MIDI数据的数组array
    midiList.start开始时间戳,单位秒number
    midiList.end结束时间戳,单位秒number
    midiList.pitch音高number
    midiList.velocity力度(音量)number
    track扩展参数,"vocal"代表人声string
    confidence扩展参数,代表置信度float

    示例:

    {
      "midiList": [
        {
          "start": 1.4164172,
          "end": 1.7531066,
          "pitch": 54.787903,
          "velocity": 100
        },
        {
          "start": 1.9156463,
          "end": 2.078186,
          "pitch": 53.074356,
          "velocity": 100
        },
        ...
        {
          "start": 16.323627,
          "end": 16.759003,
          "pitch": 55.029453,
          "velocity": 100
        }
      ],
      "track": "vocal",
      "confidence": 0.8626614
    }
    
    

参考示例

调用方式为:POST /api/v1/invoke

Golang

// 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 = "MIDI"

	// 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":"{\"extra\":{\"midi\":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)
	}
}

常见问题

HTTP状态码业务状态码错误信息错误说明解决办法
40040000010InvalidData:NoOutput输入为纯音乐或rap,或算法受限无法检测出midi请输入受支持的音乐类型